remuco-source-0.9.6/Makefile0000644000000000000000000000562111700415064015716 0ustar rootroot00000000000000# ----------------------------------------------------------------------------- # Makefile intended for end users. It is a wrapper around setup.py. # ----------------------------------------------------------------------------- #PREFIX ?= /usr/local #SETUP := python setup.py install --prefix=$(PREFIX) SETUP := python setup.py install ADAPTERS := $(shell ls adapter) help: @echo @echo "To install a player adapter (and required base components), run:" @for PA in $(ADAPTERS); do echo " make install-$$PA"; done @echo @echo "To uninstall a player adapter, run:" @for PA in $(ADAPTERS); do echo " make uninstall-$$PA"; done @echo @echo "To uninstall all components (base and player adapters), run:" @echo " make uninstall-all" @echo @echo "Of course, be root or use 'sudo' when needed." @echo all: help @true install: help @true uninstall: help @true install-base: clean python base/module/install-check.py REMUCO_COMPONENTS="" $(SETUP) --record install-base.log @echo "+-----------------------------------------------------------------+" @echo "| Installed Remuco base." @echo "+-----------------------------------------------------------------+" install-%: install-base @IC=adapter/$(subst install-,,$@)/install-check.py ; \ [ ! -e $$IC ] || python $$IC REMUCO_COMPONENTS=$(subst install-,,$@) $(SETUP) --record install-tmp.log diff --suppress-common-lines -n install-base.log install-tmp.log \ | grep "^/" > install-$(subst install-,,$@).log rm install-tmp.log @echo "+-----------------------------------------------------------------+" @echo "| Installed player adapter '$(subst install-,,$@)'." @[ ! -e adapter/$(subst install-,,$@)/.wip ] || \ echo "| WARNING: This adapter is still work in progress!" @echo "+-----------------------------------------------------------------+" uninstall-all: $(addprefix uninstall-,$(ADAPTERS)) uninstall-base @echo "+-----------------------------------------------------------------+" @echo "| Uninstalled all components." @echo "+-----------------------------------------------------------------+" uninstall-%: @PA='$(subst uninstall-,,$@)'; \ if [ -e install-$$PA.log ] ; then \ cat install-$$PA.log | xargs rm -f || exit 1; \ rm install-$$PA.log ; \ echo "+-----------------------------------------------------------------+" ; \ echo "| Uninstalled component '$$PA'." ; \ echo "+-----------------------------------------------------------------+" ; \ else \ echo "+-----------------------------------------------------------------+" ; \ echo "| Skipped component '$$PA' (install log does not exist)" ; \ echo "+-----------------------------------------------------------------+" ; \ fi clean: python setup.py clean --all @echo "+-----------------------------------------------------------------+" @echo "| Clean ok (keep install log files for uninsallation)." @echo "+-----------------------------------------------------------------+" remuco-source-0.9.6/adapter/amarok/remuco-amarok0000755000000000000000000000634611700415064021645 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter for Amarok, implemented as an executable script.""" import dbus from dbus.exceptions import DBusException import gobject import remuco from remuco import log # ============================================================================= # player adapter # ============================================================================= class AmarokAdapter(remuco.MPRISAdapter): def __init__(self): remuco.MPRISAdapter.__init__(self, "amarok", "Amarok", mime_types=remuco.MIMETYPES_AUDIO, rating=True) self.__am = None def start(self): remuco.MPRISAdapter.start(self) try: bus = dbus.SessionBus() proxy = bus.get_object("org.kde.amarok", "/amarok/MainWindow") self.__am = dbus.Interface(proxy, "org.kde.KMainWindow") except DBusException, e: raise StandardError("dbus error: %s" % e) def stop(self): remuco.MPRISAdapter.stop(self) self.__am = None def poll(self): remuco.MPRISAdapter.poll(self) # amarok does not signal change in shuffle state self._poll_status() # ========================================================================= # control interface # ========================================================================= def ctrl_rate(self, rating): rating = min(rating, 5) rating = max(rating, 1) action = "rate%s" % rating try: self.__am.activateAction(action) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_toggle_shuffle(self): remuco.MPRISAdapter.ctrl_toggle_shuffle(self) # amarok does not signal change in shuffle state gobject.idle_add(self._poll_status) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = AmarokAdapter() mg = remuco.Manager(pa, dbus_name="org.mpris.amarok") mg.run() remuco-source-0.9.6/adapter/amarok14/install-check.py0000644000000000000000000000057611700415064022414 0ustar rootroot00000000000000import sys try: import eyeD3 except ImportError, e: print("") print("+-----------------------------------------------------------------+") print("| Unsatisfied Python requirement: %s." % e) print("| Please install the missing module and then retry.") print("+-----------------------------------------------------------------+") print("") sys.exit(1)remuco-source-0.9.6/adapter/amarok14/remuco-amarok140000755000000000000000000003110511700415064022146 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Amarok1.4 adapter for Remuco, implemented as an executable script.""" import commands import os import os.path import sqlite3 import eyeD3 import gobject import remuco from remuco import log # ============================================================================= # constants # ============================================================================= IA_JUMP = remuco.ItemAction("Play Now") IA_REMOVE = remuco.ItemAction("Remove", multiple=True) PLAYLIST_ACTIONS = (IA_JUMP, IA_REMOVE) IA_ADD = remuco.ItemAction("Add to playlist", multiple=True) MLIB_ITEM_ACTIONS = (IA_ADD,) SEARCH_MASK = [ "Artist", "Album", "Title" ] AMAROK_DB = os.path.expanduser('~/.kde/share/apps/amarok/collection.db') # ============================================================================= # player adapter # ============================================================================= class Amarok14Adapter(remuco.PlayerAdapter): lastpath = "" search_list = [] db = None def __init__(self): remuco.PlayerAdapter.__init__(self, "Amarok 1.4", playback_known=True, volume_known=True, progress_known=True, shuffle_known=True, repeat_known=True, mime_types=remuco.MIMETYPES_AUDIO, max_rating=10, poll=10, search_mask=SEARCH_MASK ) def start(self): remuco.PlayerAdapter.start(self) self.db = sqlite3.connect(AMAROK_DB).cursor() def stop(self): remuco.PlayerAdapter.stop(self) self.db = None def poll(self): if not self._check_running(): return # manager will stop us import random current_state = self._amarok("player randomModeStatus") if(current_state == "true"): self.update_shuffle(True) else: self.update_shuffle(False) current_state = self._amarok("player repeatPlaylistStatus") if(current_state == "true"): self.update_repeat(True) else: self.update_repeat(False) volume = self._amarok("player getVolume", 50) self.update_volume(volume) playing = self._amarok("player isPlaying") if playing == "true": self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_PAUSE) #~ Get and calculate total time and progress current = self._amarok("player currentTime") if(len(current.split(":")) == 2): cmin, csec = current.split(":") else: cmin, csec = 0,0 total = self._amarok("player totalTime") if(len(total.split(":")) == 2): tmin, tsec = total.split(":") else: tmin, tsec = 0,0 cmin, csec, tmin, tsec = int(cmin), int(csec), int(tmin), int(tsec) current = (cmin*60)+csec total = (tmin*60)+tsec self.update_progress(progress=current, length=total) curpath = self._amarok("player path") if(self.lastpath != curpath and len(curpath) != 0): info = {} info[remuco.INFO_ARTIST] = self._amarok("player artist") info[remuco.INFO_ALBUM] = self._amarok("player album") info[remuco.INFO_TITLE] = self._amarok("player title") info[remuco.INFO_GENRE] = self._amarok("player genre") info[remuco.INFO_YEAR] = self._amarok("player year") info[remuco.INFO_BITRATE] = int(self._amarok("player bitrate")) info[remuco.INFO_RATING] = self._amarok("player rating") self.update_item("", info, self.find_image(curpath, True)) self.lastpath = curpath # ========================================================================= # control interface # ========================================================================= def ctrl_rate(self, rate): self._amarok("player setRating %s" % (rate)) def ctrl_volume(self, direction): current = int(self._amarok("player getVolume", 50)) if(direction == 1 ): self._amarok("player setVolume %s" % (current+10)) elif(direction == -1): self._amarok("player setVolume %s" % (current-10)) elif(direction == 0): self._amarok("player mute") def ctrl_toggle_shuffle(self): current_state = self._amarok("player randomModeStatus") if(current_state == "true"): self._amarok("player enableRandomMode false") self.update_shuffle(False) else: self._amarok("player enableRandomMode true") self.update_shuffle(True) def ctrl_toggle_repeat(self): current_state = self._amarok("player repeatPlaylistStatus") if(current_state == "true"): self._amarok("player enableRepeatPlaylist false") self.update_repeat(False) else: self._amarok("player enableRepeatPlaylist true") self.update_repeat(True) def ctrl_toggle_playing(self): self._amarok("player playPause") gobject.idle_add(self.poll) def ctrl_next(self): self._amarok("player next") gobject.timeout_add(150, self.poll) def ctrl_previous(self): self._amarok("player prev") gobject.timeout_add(150, self.poll) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): path = os.path.expanduser("~/.cache/current.m3u") self._amarok('playlist saveM3u "%s" false' % path) f = open(path) tag = eyeD3.Tag() while 1: line = f.readline() if not line: break if line.find("#") == -1: tag.link(line.rstrip()) reply.ids.append(len(reply.names)) reply.names.append("%s - %s" % (tag.getArtist(), tag.getTitle())) f.close reply.item_actions = PLAYLIST_ACTIONS reply.send() def request_search(self, reply, query): search = [] fields = ["artist.name", "album.name", "tags.title"] for q, f in zip(query, fields): if q: search.append('lower(%s) like "%%%s%%"' % (f, q)) if not search: reply.send() return sql = ("select tags.title as title, artist.name as artist, album.name " "as album, tags.url as url from tags join artist on " "(tags.artist = artist.id) join album on " "(tags.album = album.id) where %s" % " and ".join(search)) res = self.db.execute(sql) id = 0 self.search_list = [] for r in res: self.search_list.append("") self.search_list[len(reply.names)] = r[3] reply.ids.append(len(reply.names)) reply.names.append(" ".join(r[0:3])) reply.item_actions = MLIB_ITEM_ACTIONS reply.send() def request_mlib(self, reply, path): reply.nested, reply.names, reply.ids = [], [], [] if not path: sql = "select name from artist order by name asc" res = self.db.execute(sql) for r in res: reply.nested.append(r[0]) elif(len(path) == 1): sql = ('select distinct(album.name) from album ' 'join tags on (tags.album = album.id) ' 'join artist on (tags.artist = artist.id) ' 'where artist.name = "%s"' % path[0]) res = self.db.execute(sql) for r in res: if(len(r[0]) == 0): reply.nested.append("_no_album_") else: reply.nested.append(r[0]) elif(len(path) == 2): album = (path[1] != "_no_album_" and ' and album.name = "%s"' % path[1] or "") sql = ('select tags.title from tags ' 'join album on (tags.album = album.id) ' 'join artist on (tags.artist = artist.id) ' 'where artist.name = "%s"%s ' 'order by tags.url' % (path[0], album)) res = self.db.execute(sql) for r in res: reply.ids.append(len(reply.names)) reply.names.append(r[0]) reply.item_actions = MLIB_ITEM_ACTIONS reply.send() # ========================================================================= # Actions # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if(action_id == IA_JUMP.id): self._amarok("playlist playByIndex %s" % (positions[0])) elif(action_id == IA_REMOVE.id): for i, v in enumerate(positions): self._amarok("playlist removeByIndex %s" % (v)) else: print "Unknown action %s" %s (action_id) def action_search_item(self, action_id, positions, ids): path = [] if action_id == IA_ADD.id: #Add to playlist for pos in positions: # Ugly hack but it works. Amarok prefixes all paths with . # (period). Don't know why but this is a quickfix path.append('"%s"' % (os.path.abspath("/%s" %(self.search_list[pos])))) self._amarok("playlist addMediaList [ %s ]" % " ".join(path)) def action_mlib_item(self, action_id, path, positions, ids): if action_id == IA_ADD.id: search = [] if(len(path[0]) > 0): search.append('artist.name = "%s"' % path[0]) if(len(path[1]) > 0 and path[1] != "_no_album_"): search.append('album.name = "%s"' % path[1]) sql = ('select tags.url from tags ' 'join album on (album.id = tags.album) ' 'join artist on (artist.id = tags.artist) ' 'where %s ' 'order by tags.url' % " AND ".join(search)) res = self.db.execute(sql) list = [] for r in res: list.append(r[0]) path = [] if(len(list) > 0): for pos in positions: # Ugly hack but it works. Amarok prefixes all paths with . # (period). Don't know why but this is a quickfix path.append(' "%s"' % os.path.abspath("/%s" % list[pos])) self._amarok("playlist addMediaList [ %s ]" % " ".join(path)) # ========================================================================= # internal methods # ========================================================================= def _amarok(self, cmd, default=""): """Shortcut for running command 'dcop amarok ...'.""" ret, out = commands.getstatusoutput("dcop amarok %s" % cmd) if ret != os.EX_OK: log.warning("'dcop amarok %s' failed (%s)" % (cmd, out)) return default else: return out # ============================================================================= # main # ============================================================================= def run_check(): """Check if Amarok is running.""" return commands.getstatusoutput("dcop amarok")[0] == 0 if __name__ == '__main__': pa = Amarok14Adapter() mg = remuco.Manager(pa, poll_fn=run_check) mg.run() remuco-source-0.9.6/adapter/audacious/remuco-audacious0000755000000000000000000001524011700415064023044 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter for Audacious, implemented as an executable script.""" import dbus from dbus.exceptions import DBusException import gobject import remuco from remuco import log # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") PLAYLIST_ACTIONS = (IA_JUMP,) # ============================================================================= # player adapter # ============================================================================= class AudaciousAdapter(remuco.MPRISAdapter): def __init__(self): remuco.MPRISAdapter.__init__(self, "audacious", "Audacious", mime_types=remuco.MIMETYPES_AUDIO, extra_playlist_actions=PLAYLIST_ACTIONS) self.__ad = None self.__poll_for_repeat_and_shuffle = False def start(self): remuco.MPRISAdapter.start(self) try: bus = dbus.SessionBus() proxy = bus.get_object("org.atheme.audacious", "/org/atheme/audacious") self.__ad = dbus.Interface(proxy, "org.atheme.audacious") except DBusException, e: raise StandardError("dbus error: %s" % e) def stop(self): remuco.MPRISAdapter.stop(self) self.__ad = None def poll(self): remuco.MPRISAdapter.poll(self) if self.__poll_for_repeat_and_shuffle: self.__poll_repeat() self.__poll_shuffle() def __poll_repeat(self): # used if audacious still does not provide this by signal "StatusChange" try: repeat = bool(self.__ad.Repeat()) except DBusException, e: log.warning("dbus error: %s" % e) repeat = False self._repeat = repeat self.update_repeat(repeat) def __poll_shuffle(self): # used if audacious still does not provide this by signal "StatusChange" try: shuffle = bool(self.__ad.Shuffle()) except DBusException, e: log.warning("dbus error: %s" % e) shuffle = False self._shuffle = shuffle self.update_shuffle(shuffle) # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_repeat(self): # this works in more Audacious versions than the related MPRIS control try: self.__ad.ToggleRepeat(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) if self.__poll_for_repeat_and_shuffle: self.__poll_repeat() def ctrl_toggle_shuffle(self): # this works in more Audacious versions than the related MPRIS control try: self.__ad.ToggleShuffle(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) if self.__poll_for_repeat_and_shuffle: self.__poll_shuffle() # ========================================================================= # actions interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: try: self.__ad.Jump(positions[0], reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) else: remuco.MPRISAdapter.action_playlist_item(self, action_id, positions, ids) # ========================================================================= # internal methods which must be adapted to provide MPRIS conformity # ========================================================================= def _notify_status(self, status): if isinstance(status, int): # audacious only provides playback status here (Audacious 1.5) self.__poll_for_repeat_and_shuffle = True status = (status, self._shuffle, self._repeat, self._repeat) else: # it looks like audacious has fixed its MPRIS interface self.__poll_for_repeat_and_shuffle = False remuco.MPRISAdapter._notify_status(self, status) def _notify_track(self, track): # audacious provides length in 'length', not in 'time' or 'mtime' # (fixed by http://hg.atheme.org/audacious/rev/e6caff433c68) if "length" in track and not "mtime" in track: track["mtime"] = track["length"] # audacious 1.5 provides length in 'URI', not in 'location' if "URI" in track: track["location"] = track["URI"] remuco.MPRISAdapter._notify_track(self, track) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = AudaciousAdapter() mg = remuco.Manager(pa, dbus_name="org.mpris.audacious") mg.run() remuco-source-0.9.6/adapter/banshee/remuco-banshee0000755000000000000000000002773011700415064022133 0ustar rootroot00000000000000#!/usr/bin/env python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Banshee player adapter for Remuco, implemented as an executable script.""" import os.path import dbus from dbus.exceptions import DBusException import gobject from xdg.BaseDirectory import xdg_cache_home as xdg_cache import remuco from remuco import log # ============================================================================= # banshee dbus names # ============================================================================= DBUS_NAME = "org.bansheeproject.Banshee" DBUS_PATH_ENGINE = "/org/bansheeproject/Banshee/PlayerEngine" DBUS_IFACE_ENGINE = "org.bansheeproject.Banshee.PlayerEngine" DBUS_PATH_CONTROLLER = "/org/bansheeproject/Banshee/PlaybackController" DBUS_IFACE_CONTROLLER = "org.bansheeproject.Banshee.PlaybackController" # ============================================================================= # banshee player adapter # ============================================================================= class BansheeAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "Banshee", max_rating=5, playback_known=True, volume_known=True, repeat_known=True, shuffle_known=True, progress_known=True) self.__dbus_signal_handler = () self.__repeat = False self.__shuffle = False self.__volume = 0 self.__progress = 0 self.__progress_length = 0 log.debug("init done") def start(self): remuco.PlayerAdapter.start(self) try: bus = dbus.SessionBus() proxy = bus.get_object(DBUS_NAME, DBUS_PATH_ENGINE) self.__bse = dbus.Interface(proxy, DBUS_IFACE_ENGINE) proxy = bus.get_object(DBUS_NAME, DBUS_PATH_CONTROLLER) self.__bsc = dbus.Interface(proxy, DBUS_IFACE_CONTROLLER) except DBusException, e: raise StandardError("dbus error: %s" % e) try: self.__dbus_signal_handler = ( self.__bse.connect_to_signal("EventChanged", self.__notify_event), self.__bse.connect_to_signal("StateChanged", self.__notify_playback), ) except DBusException, e: raise StandardError("dbus error: %s" % e) try: self.__bse.GetCurrentTrack(reply_handler=self.__notify_track, error_handler=self.__dbus_error) self.__bse.GetCurrentState(reply_handler=self.__notify_playback, error_handler=self.__dbus_error) self.__bse.GetVolume(reply_handler=self.__notify_volume, error_handler=self.__dbus_error) except DBusException, e: # this is not necessarily a fatal error log.warning("dbus error: %s" % e) log.debug("start done") def stop(self): remuco.PlayerAdapter.stop(self) for handler in self.__dbus_signal_handler: handler.remove() self.__dbus_signal_handler = () self.__bsc = None self.__bse = None log.debug("stop done") def poll(self): self.__poll_repeat_shuffle() self.__poll_progress() def __poll_repeat_shuffle(self): try: self.__bsc.GetRepeatMode(reply_handler=self.__notify_repeat, error_handler=self.__dbus_error) self.__bsc.GetShuffleMode(reply_handler=self.__notify_shuffle, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def __poll_progress(self): try: self.__bse.GetPosition(reply_handler=self.__notify_progress, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): try: self.__bse.TogglePlaying(reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_next(self): try: self.__bsc.Next(False, reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_previous(self): try: self.__bsc.Previous(False, reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_seek(self, direction): if self.__progress_length == 0: return progress_new = self.__progress + direction * 5 progress_new = min(progress_new, self.__progress_length) progress_new = max(progress_new, 0) try: self.__bse.SetPosition(dbus.UInt32(progress_new * 1000), reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) else: # poll with a small delay, otherwise we get 0 as progress gobject.timeout_add(100, self.__poll_progress) def ctrl_rate(self, rating): try: self.__bse.SetRating(dbus.Byte(rating), reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_volume(self, direction): if direction == 0: volume = 0 else: volume = self.__volume + direction * 5 volume = min(volume, 100) volume = max(volume, 0) try: self.__bse.SetVolume(dbus.UInt16(volume), reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) self.__notify_event("volume", None, None) def ctrl_toggle_repeat(self): try: self.__bsc.SetRepeatMode(int(not self.__repeat), reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) self.__poll_repeat_shuffle() def ctrl_toggle_shuffle(self): mode = self.__shuffle and "off" or self.config.getx("shuffle", "song") try: self.__bsc.SetShuffleMode(mode, reply_handler=self.__dbus_ignore, error_handler=self.__dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) self.__poll_repeat_shuffle() # ========================================================================= # internal methods # ========================================================================= def __notify_event(self, event, message, buff_percent): try: if event == "startofstream" or event == "trackinfoupdated": self.__bse.GetCurrentTrack(reply_handler=self.__notify_track, error_handler=self.__dbus_error) elif event == "volume": self.__bse.GetVolume(reply_handler=self.__notify_volume, error_handler=self.__dbus_error) else: log.debug("event: %s (%s)" %(event, message)) except DBusException, e: log.warning("dbus error: %s" % e) def __notify_playback(self, state): log.debug("state: %s" % state) if state == "playing": playback = remuco.PLAYBACK_PLAY elif state == "idle": playback = remuco.PLAYBACK_STOP self.update_item(None, None, None) else: playback = remuco.PLAYBACK_PAUSE self.update_playback(playback) def __notify_volume(self, volume): self.__volume = volume self.update_volume(volume) def __notify_track(self, track): id = track.get("URI") if not id: self.update_item(None, None, None) self.__progress_length = 0 return info = {} info[remuco.INFO_TITLE] = track.get("name") info[remuco.INFO_ARTIST] = track.get("artist") info[remuco.INFO_ALBUM] = track.get("album") info[remuco.INFO_RATING] = track.get("rating", 0) self.__progress_length = int(track.get("length", 0)) img = None art_id = track.get("artwork-id") if art_id: file = "%s/album-art/%s.jpg" % (xdg_cache, art_id) if os.path.isfile(file): img = file else: img = self.find_image(id) log.debug("track: %s" % info) self.update_item(id, info, img) def __notify_repeat(self, repeat): self.__repeat = repeat > 0 self.update_repeat(self.__repeat) def __notify_shuffle(self, shuffle): self.__shuffle = shuffle != "off" self.update_shuffle(self.__shuffle) def __notify_progress(self, ms): self.__progress = ms // 1000 self.update_progress(self.__progress, self.__progress_length) def __dbus_error(self, error): """ DBus error handler. """ if self.__bsc is None: return # do not log errors when not stopped already log.warning("dbus error: %s" % error) def __dbus_ignore(self): """ DBus reply handler for methods without reply. """ pass # ============================================================================= # main # ============================================================================= if __name__ == '__main__': ba = BansheeAdapter() mg = remuco.Manager(ba, dbus_name=DBUS_NAME) mg.run() remuco-source-0.9.6/adapter/clementine/remuco-clementine0000755000000000000000000000336411700415064023364 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter for Clementine, implemented as an executable script.""" import remuco # ============================================================================= # player adapter # ============================================================================= class ClementineAdapter(remuco.MPRISAdapter): def __init__(self): remuco.MPRISAdapter.__init__(self, "clementine", "Clementine", mime_types=remuco.MIMETYPES_AUDIO) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = ClementineAdapter() mg = remuco.Manager(pa, dbus_name="org.mpris.clementine") mg.run() remuco-source-0.9.6/adapter/exaile/PLUGININFO0000644000000000000000000000016011700415064020533 0ustar rootroot00000000000000Version="0.9.6" Authors=["Remuco team"] Name="Remuco" Description="Exaile adapter for Remuco (and vice versa)." remuco-source-0.9.6/adapter/exaile/__init__.py0000644000000000000000000005436411700415064021266 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Exaile adapter for Remuco, implemented as an Exaile plugin.""" from __future__ import with_statement import os.path import re import gobject import xl.event import xl.settings try: from xl.cover import NoCoverFoundException # exaile 3.0 except ImportError: class NoCoverFoundException(Exception): pass # exaile 3.1 try: from xl import covers # exaile 3.2 except ImportError: pass # exaile 3.1 import remuco from remuco import log # ============================================================================= # constants # ============================================================================= PLAYLISTS_SMART = "Smart playlists" PLAYLISTS_CUSTOM = "Custom playlists" PLAYLISTS_OPEN = "Open playlists" SEARCH_MASK = ("Artist", "Album", "Title", "Genre") # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") IA_REMOVE = remuco.ItemAction("Remove", multiple=True) IA_ENQUEUE = remuco.ItemAction("Enqueue", multiple=True) IA_APPEND = remuco.ItemAction("Append", multiple=True) IA_REPLACE = remuco.ItemAction("Reset playlist", multiple=True) IA_NEW_PLAYLIST = remuco.ItemAction("New playlist", multiple=True) LA_OPEN = remuco.ListAction("Open") LA_ACTIVATE = remuco.ListAction("Activate") LA_CLOSE = remuco.ListAction("Close") PLAYLIST_ACTIONS = (IA_JUMP, IA_REMOVE, IA_ENQUEUE) QUEUE_ACTIONS = (IA_JUMP, IA_REMOVE) MLIB_ITEM_ACTIONS = (IA_JUMP, IA_ENQUEUE, IA_APPEND, IA_REPLACE, IA_REMOVE, IA_NEW_PLAYLIST) MLIB_LIST_ACTIONS = (LA_OPEN,) MLIB_LIST_OPEN_ACTIONS = (LA_ACTIVATE, LA_CLOSE) SEARCH_ACTIONS = (IA_ENQUEUE, IA_APPEND, IA_REPLACE, IA_NEW_PLAYLIST) # ============================================================================= # player adapter # ============================================================================= class ExaileAdapter(remuco.PlayerAdapter): def __init__(self, exaile): remuco.PlayerAdapter.__init__(self, "Exaile", max_rating=5, playback_known=True, volume_known=True, repeat_known=True, shuffle_known=True, progress_known=True, search_mask=SEARCH_MASK) self.__ex = exaile def start(self): remuco.PlayerAdapter.start(self) for event in ("playback_track_start", "playback_track_end"): xl.event.add_callback(self.__notify_track_change, event) for event in ("playback_player_end", "playback_player_start", "playback_toggle_pause"): xl.event.add_callback(self.__notify_playback_change, event) self.__update_track(self.__ex.player.current) self.__update_position() self.__update_playback() # other updates via poll() log.debug("remuco exaile adapter started") def stop(self): remuco.PlayerAdapter.stop(self) xl.event.remove_callback(self.__notify_track_change) xl.event.remove_callback(self.__notify_playback_change) log.debug("remuco exaile adapter stopped") def poll(self): self.__update_repeat_and_shuffle() self.__update_volume() self.__update_progress() # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): if self.__ex.player.is_playing() or self.__ex.player.is_paused(): self.__ex.player.toggle_pause() else: self.__ex.queue.play() # when playing after stopped, the 'playback_player_start' is missed gobject.idle_add(self.__update_playback) def ctrl_toggle_repeat(self): repeat = not self.__ex.queue.current_playlist.is_repeat() self.__ex.queue.current_playlist.set_repeat(repeat) gobject.idle_add(self.__update_repeat_and_shuffle) def ctrl_toggle_shuffle(self): shuffle = not self.__ex.queue.current_playlist.is_random() self.__ex.queue.current_playlist.set_random(shuffle) gobject.idle_add(self.__update_repeat_and_shuffle) def ctrl_next(self): """Play the next item. @note: Override if it is possible and makes sense. """ self.__ex.queue.next() def ctrl_previous(self): """Play the previous item. @note: Override if it is possible and makes sense. """ self.__ex.queue.prev() def ctrl_seek(self, direction): """Seek forward or backward some seconds. The number of seconds to seek should be reasonable for the current item's length (if known). If the progress of the current item is known, it should get synchronized immediately with clients by calling update_progress(). @param direction: * -1: seek backward * +1: seek forward @note: Override if it is possible and makes sense. """ if not self.__ex.player.is_playing(): return track = self.__ex.player.current if not track: return pos = self.__ex.player.get_time() pos = pos + direction * 5 if self.__ex.get_version() < "0.3.1": pos = min(pos, track.get_duration()) else: pos = min(pos, int(track.get_tag_raw("__length"))) pos = max(pos, 0) self.__ex.player.seek(pos) gobject.idle_add(self.__update_progress) def ctrl_rate(self, rating): track = self.__ex.player.current if not track: return track.set_rating(rating) def ctrl_volume(self, direction): if direction == 0: self.__ex.player.set_volume(0) else: volume = self.__ex.player.get_volume() + direction * 5 volume = min(volume, 100) volume = max(volume, 0) self.__ex.player.set_volume(volume) gobject.idle_add(self.__update_volume) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): tracks = self.__ex.queue.current_playlist.get_ordered_tracks() reply.ids, reply.names = self.__tracklist_to_itemlist(tracks) reply.item_actions = PLAYLIST_ACTIONS reply.send() def request_queue(self, reply): tracks = self.__ex.queue.get_tracks() reply.ids, reply.names = self.__tracklist_to_itemlist(tracks) reply.item_actions = QUEUE_ACTIONS reply.send() def request_mlib(self, reply, path): if not path: reply.nested = (PLAYLISTS_OPEN, PLAYLISTS_SMART, PLAYLISTS_CUSTOM) reply.send() elif path[0] == PLAYLISTS_SMART: if len(path) == 1: reply.nested = self.__ex.smart_playlists.list_playlists() reply.list_actions = MLIB_LIST_ACTIONS else: pl = self.__ex.smart_playlists.get_playlist(path[1]) reply.ids, reply.names = ["XXX"], ["This is a dynamic playlist!"] elif path[0] == PLAYLISTS_CUSTOM: if len(path) == 1: reply.nested = self.__ex.playlists.list_playlists() reply.list_actions = MLIB_LIST_ACTIONS else: pl = self.__ex.playlists.get_playlist(path[1]) tracks = pl.get_ordered_tracks() reply.ids, reply.names = self.__tracklist_to_itemlist(tracks) elif path[0] == PLAYLISTS_OPEN: if len(path) == 1: plo_list, pln_list = self.__get_open_playlists() reply.nested = pln_list reply.list_actions = MLIB_LIST_OPEN_ACTIONS else: pl, i = self.__get_open_playlist(path) tracks = pl.get_ordered_tracks() reply.ids, reply.names = self.__tracklist_to_itemlist(tracks) reply.item_actions = MLIB_ITEM_ACTIONS else: log.error("** BUG ** unexpected mlib path") reply.send() def request_search(self, reply, query): if self.__ex.get_version() < "0.3.1": tracks = None for key, val in zip(SEARCH_MASK, query): val = val.strip() if val: expr = "%s=%s" % (key, val) tracks = self.__ex.collection.search(expr, tracks=tracks) if tracks is None: # empty query, return _all_ tracks tracks = self.__ex.collection.search("", tracks=tracks) else: tml = [] for key, val in zip(SEARCH_MASK, query): val = val.strip() if val: sexpr = "%s=%s" % (key.lower(), val) tml.append(xl.trax.TracksMatcher(sexpr, case_sensitive=False)) tracks = xl.trax.search_tracks(self.__ex.collection, tml) reply.ids, reply.names = self.__tracklist_to_itemlist(tracks) reply.item_actions = SEARCH_ACTIONS reply.send() # ========================================================================= # action interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if self.__handle_generic_item_action(action_id, ids): pass # we are done elif action_id == IA_JUMP.id: track = self.__ex.collection.get_track_by_loc(ids[0]) self.__ex.queue.next(track=track) self.__ex.queue.current_playlist.set_current_pos(positions[0]) elif action_id == IA_REMOVE.id: self.__remove_tracks_from_playlist(positions) else: log.error("** BUG ** unexpected playlist item action") def action_queue_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: track = self.__ex.collection.get_track_by_loc(ids[0]) self.__ex.queue.next(track=track) self.__remove_tracks_from_playlist(positions, pl=self.__ex.queue) elif action_id == IA_REMOVE.id: self.__remove_tracks_from_playlist(positions, pl=self.__ex.queue) else: log.error("** BUG ** unexpected queue item action") def action_mlib_item(self, action_id, path, positions, ids): if self.__handle_generic_item_action(action_id, ids): pass # we are done elif action_id == IA_JUMP.id: self.action_mlib_list(LA_ACTIVATE.id, path) track = self.__ex.collection.get_track_by_loc(ids[0]) self.__ex.queue.next(track=track) self.__ex.queue.current_playlist.set_current_pos(positions[0]) elif action_id == IA_REMOVE.id: pl, i = self.__get_open_playlist(path) self.__remove_tracks_from_playlist(positions, pl=pl) else: log.error("** BUG ** unexpected mlib item action") def action_mlib_list(self, action_id, path): if action_id == LA_ACTIVATE.id: if path[0] == PLAYLISTS_OPEN: pl, i = self.__get_open_playlist(path) self.__ex.gui.main.playlist_notebook.set_current_page(i) else: log.error("** BUG ** unexpected mlib path %s" % path) elif action_id == LA_OPEN.id: if path[0] == PLAYLISTS_SMART: pl = self.__ex.smart_playlists.get_playlist(path[1]) pl = pl.get_playlist(self.__ex.collection) self.__ex.gui.main.add_playlist(pl) elif path[0] == PLAYLISTS_CUSTOM: pl = self.__ex.playlists.get_playlist(path[1]) self.__ex.gui.main.add_playlist(pl) else: log.error("** BUG ** unexpected mlib path %s" % path) elif action_id == LA_CLOSE.id: pl, i = self.__get_open_playlist(path) nb = self.__ex.gui.main.playlist_notebook nb.remove_page(i) else: log.error("** BUG ** unexpected mlib list action") def action_search_item(self, action_id, positions, ids): if self.__handle_generic_item_action(action_id, ids): pass # we are done else: log.error("** BUG ** unexpected search item action") # ========================================================================= # callbacks # ========================================================================= def __notify_track_change(self, type, object, data): """Callback on track change.""" self.__update_track(data) self.__update_progress() self.__update_position() def __notify_playback_change(self, type, object, data): """Callback on playback change.""" self.__update_playback() # ========================================================================= # helper methods # ========================================================================= def __update_playback(self): """Update playback state.""" if self.__ex.player.is_playing(): playback = remuco.PLAYBACK_PLAY elif self.__ex.player.is_paused(): playback = remuco.PLAYBACK_PAUSE else: playback = remuco.PLAYBACK_STOP self.update_playback(playback) def __update_repeat_and_shuffle(self): """Update repeat and shuffle state.""" repeat = self.__ex.queue.current_playlist.is_repeat() self.update_repeat(repeat) shuffle = self.__ex.queue.current_playlist.is_random() self.update_shuffle(shuffle) def __update_track(self, track): """Update meta information of current track.""" def get_tag(key): if self.__ex.get_version() < "0.3.1": val = track.get_tag(key) else: # Exaile >= 0.3.1 val = track.get_tag_raw(key) return val and (isinstance(val, list) and val[0] or val) or None id = None info = None img = None if track: id = track.get_loc_for_io() info = {} info[remuco.INFO_ARTIST] = get_tag("artist") info[remuco.INFO_ALBUM] = get_tag("album") info[remuco.INFO_TITLE] = get_tag("title") info[remuco.INFO_YEAR] = get_tag("date") info[remuco.INFO_GENRE] = get_tag("genre") info[remuco.INFO_RATING] = track.get_rating() if self.__ex.get_version() < "0.3.1": info[remuco.INFO_BITRATE] = track.get_bitrate().replace('k','') info[remuco.INFO_LENGTH] = track.get_duration() try: img = self.__ex.covers.get_cover(track) except NoCoverFoundException: # exaile 0.3.0 only pass else: # Exaile >= 0.3.1 info[remuco.INFO_BITRATE] = get_tag("__bitrate") // 1000 info[remuco.INFO_LENGTH] = int(get_tag("__length")) if self.__ex.get_version() < "0.3.2": idata = self.__ex.covers.get_cover(track, set_only=True) else: idata = covers.MANAGER.get_cover(track, set_only=True) if idata: img = os.path.join(self.config.cache, "exaile.cover") with open(img, "w") as fp: fp.write(idata) if not img and track.local_file_name(): # loc_for_io may be != UTF-8 img = self.find_image(track.local_file_name()) self.update_item(id, info, img) def __update_volume(self): """Update volume.""" self.update_volume(self.__ex.player.get_volume()) def __update_progress(self): """Update play progress of current track.""" track = self.__ex.player.current if not track: len = 0 pos = 0 else: if self.__ex.get_version() < "0.3.1": len = track.get_duration() else: # Exaile >= 0.3.1 len = int(track.get_tag_raw("__length")) pos = self.__ex.player.get_time() self.update_progress(pos, len) def __update_position(self): """Update current playlist position.""" pl = self.__ex.queue.current_playlist self.update_position(pl.get_current_pos()) def __handle_generic_item_action(self, action_id, ids): """Process generic item actions. Actions: IA_ENQUEUE, IA_APPEND, IA_REPLACE, IA_NEW_PLAYLIST Generic item actions are processed independent of the list containing the items (playlist, queue, mlib or search result). @return: True if action has been handled, False other wise """ handled = True tracks = self.__ex.collection.get_tracks_by_locs(ids) tracks = [t for t in tracks if t is not None] if action_id == IA_ENQUEUE.id: self.__ex.queue.add_tracks(tracks) elif action_id == IA_APPEND.id: self.__ex.queue.current_playlist.add_tracks(tracks) elif action_id == IA_REPLACE.id: self.__ex.queue.current_playlist.set_tracks(tracks) elif action_id == IA_NEW_PLAYLIST.id: self.__ex.gui.main.add_playlist() self.__ex.queue.current_playlist.add_tracks(tracks) else: handled = False return handled def __tracklist_to_itemlist(self, tracks): """Convert a list if track objects to a Remuco item list.""" ids = [] names = [] for track in tracks: # first, check if track is a SearchResultTrack (since Exaile 0.3.1) track = hasattr(track, "track") and track.track or track ids.append(track.get_loc_for_io()) if self.__ex.get_version() < "0.3.1": artist = track.get_tag("artist") title = track.get_tag("title") else: title = track.get_tag_raw("title") artist = track.get_tag_raw("artist") artist = artist and artist[0] or None title = title and title[0] or None name = "%s - %s" % (artist or "???", title or "???") names.append(name) return ids, names def __get_open_playlists(self): """Get open playlists. Returns 2 lists, one with the playlist objects and one with the playlist names (formatted appropriately to handle duplicates). """ nb = self.__ex.gui.main.playlist_notebook plo_list = [] pln_list = [] for i in range(nb.get_n_pages()): plo = nb.get_nth_page(i).playlist plo_list.append(plo) if plo == self.__ex.queue.current_playlist: num = "(%d)" % (i+1) else: num = "[%d]" % (i+1) pln_list.append("%s %s" % (num, plo.get_name())) return plo_list, pln_list def __get_open_playlist(self, path): """Get a playlist object and tab number of an open playlist.""" plo_list, pln_list = self.__get_open_playlists() i = int(re.match("[\(\[](\d+)[\)\]]", path[1]).group(1)) - 1 try: return plo_list[i], i except IndexError: return plo_list[0], 0 def __remove_tracks_from_playlist(self, positions, pl=None): """Remove tracks from a playlist given their positions. """ if pl is None: pl = self.__ex.queue.current_playlist revpos = positions[:] revpos.reverse() for pos in revpos: pl.remove_tracks(pos, pos) # ============================================================================= # plugin interface # ============================================================================= epa = None def enable(exaile): if exaile.loading: xl.event.add_callback(_enable, "exaile_loaded") else: _enable("exaile_loaded", exaile, None) def _enable(event, exaile, nothing): global epa epa = ExaileAdapter(exaile) epa.start() def disable(exaile): global epa if epa: epa.stop() epa = None def teardown(exaile): # teardown and disable are the same here disable(exaile)remuco-source-0.9.6/adapter/fooplay/remuco-fooplay0000755000000000000000000000572011700415064022236 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """FooPlay adapter for Remuco, implemented as an executable script.""" import remuco from remuco import log class FooPlayAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "FooPlay", playback_known=True, volume_known=True) def start(self): remuco.PlayerAdapter.start(self) log.debug("here we go") def stop(self): remuco.PlayerAdapter.stop(self) log.debug("bye, turning off the light") def poll(self): import random volume = random.randint(0,100) self.update_volume(volume) playing = random.randint(0,1) if playing: self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_PAUSE) # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): log.debug("toggle FooPlay's playing status") # ... # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): reply.ids = ["1", "2"] reply.names = ["Joe - Joe's Song", "Sue - Sue's Song"] reply.send() # ... # ============================================================================= # main (example startup using remuco.Manager) # ============================================================================= if __name__ == '__main__': pa = FooPlayAdapter() # create the player adapter mg = remuco.Manager(pa)# # pass it to a manager mg.run() # run the manager (blocks until interrupt signal) remuco-source-0.9.6/adapter/gmusicbrowser/remuco-gmusicbrowser0000755000000000000000000001200111700415064024670 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Gmusicbrowser adapter for Remuco, implemented as an executable script. By Sayan "Riju" Chakrabarti """ import dbus from dbus.exceptions import DBusException import remuco from remuco import log class GmusicbrowserAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "Gmusicbrowser", progress_known=True, playback_known=True, volume_known=True) self.__gm = None self.__songLen = 0 self.__pos = 0 # Following is the value (100%) to which both the player # volume and the client volume is set when either the adapter # started OR the client is unmuted. self.__vol = 100 def start(self): remuco.PlayerAdapter.start(self) log.debug("here we go") try: bus = dbus.SessionBus() obj = bus.get_object("org.gmusicbrowser","/org/gmusicbrowser") self.__gm = dbus.Interface(obj, "org.gmusicbrowser") except DBusException, e: raise StandardError("dbus error: %s" % e) # Set Current Song at start self.poll() # Increase player vol until its 100% to match client vol for i in range(0,10): self.__gm.RunCommand("IncVolume") self.update_volume(self.__vol) def stop(self): remuco.PlayerAdapter.stop(self) log.debug("bye, turning off the light") self.__gm = None def poll(self): item = self.__gm.CurrentSong() self.__songLen = int(item['length']) self.__pos = int(self.__gm.GetPosition()) playing = self.__gm.Playing() # TODO: item['track'] may give us path we can use to find cover art self.update_item('', item, '') self.update_progress(self.__pos, self.__songLen) if playing: self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_PAUSE) self.update_volume(self.__vol) # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): log.debug("toggle FooPlay's playing status") self.__gm.RunCommand("PlayPause") self.poll() def ctrl_next(self): self.__gm.RunCommand("NextSongInPlaylist") self.poll() def ctrl_previous(self): self.__gm.RunCommand("PrevSongInPlaylist") self.poll() def ctrl_volume(self, direction): if direction == 0: self.__gm.RunCommand("TogMute") if self.__vol != 0: self.__vol = 0 else: self.__vol = 100 for i in range(0,10): self.__gm.RunCommand("IncVolume") elif direction == -1: self.__gm.RunCommand("DecVolume") self.__vol = (self.__vol - 10) if self.__vol >= 10 else 0 else: self.__gm.RunCommand("IncVolume") self.__vol = (self.__vol + 10) if self.__vol <= 90 else 100 self.update_volume(self.__vol) def ctrl_seek(self, direction): if direction == -1: self.__gm.RunCommand("Rewind 5") else: self.__gm.RunCommand("Forward 5") self.poll() # ========================================================================= # request interface # ========================================================================= # NOT YET IMPLEMENTED IN GMUSICBROWSER # ============================================================================= # main (example startup using remuco.Manager) # ============================================================================= if __name__ == '__main__': pa = GmusicbrowserAdapter() # create the player adapter mg = remuco.Manager(pa,dbus_name="org.gmusicbrowser")# # pass it to a manager mg.run() # run the manager (blocks until interrupt signal remuco-source-0.9.6/adapter/mpd/install-check.py0000644000000000000000000000057411700415064021553 0ustar rootroot00000000000000import sys try: import mpd except ImportError, e: print("") print("+-----------------------------------------------------------------+") print("| Unsatisfied Python requirement: %s." % e) print("| Please install the missing module and then retry.") print("+-----------------------------------------------------------------+") print("") sys.exit(1)remuco-source-0.9.6/adapter/mpd/remuco-mpd0000755000000000000000000004575211700415064020465 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """MPD adapter for Remuco, implemented as an executable script.""" import os.path import socket # python-mpd (0.2.0) does not fully abstract socket errors import gobject import mpd import remuco from remuco import log # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") IA_REMOVE = remuco.ItemAction("Remove", multiple=True) PLAYLIST_ACTIONS = (IA_JUMP, IA_REMOVE) IA_ADD = remuco.ItemAction("Add to playlist", multiple=True) IA_SET = remuco.ItemAction("Set as playlist", multiple=True) MLIB_ITEM_ACTIONS = (IA_ADD, IA_SET) LA_PLAY = remuco.ListAction("Play") LA_ENQUEUE = remuco.ListAction("Enqueue") MLIB_LIST_ACTIONS = (LA_PLAY, LA_ENQUEUE) DA_PLAY = remuco.ListAction("Play") DA_ENQUEUE = remuco.ListAction("Enqueue") MLIB_DIR_ACTIONS = (DA_ENQUEUE, DA_PLAY) SEARCH_MASK = [ "Artist", "Album", "Title" ] # ============================================================================= # constants # ============================================================================= MLIB_FILES = "Files" MLIB_PLAYLISTS = "Playlists" # ============================================================================= # MPD player adapter # ============================================================================= class MPDAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "MPD", playback_known=True, volume_known=True, repeat_known=True, shuffle_known=True, progress_known=True, search_mask=SEARCH_MASK) self.__mpd = mpd.MPDClient() self.__mpd_host = self.config.getx("mpd-host", "localhost") self.__mpd_port = self.config.getx("mpd-port", "6600", int) self.__mpd_pwd = self.config.getx("mpd-password", "") self.__mpd_music = self.config.getx("mpd-music", "/var/lib/mpd/music") log.debug("MPD is at %s:%d" % (self.__mpd_host, self.__mpd_port)) self.__playing = False self.__shuffle = False self.__repeat = False self.__volume = 0 self.__position = -1 self.__progress = 0 self.__length = 0 self.__song = None def start(self): remuco.PlayerAdapter.start(self) if not self.__check_and_refresh_connection(): raise StandardError("failed to connect to MPD") try: mpd_version = self.__mpd.mpd_version except mpd.MPDError: log.warning("failed to get MPD version") mpd_version = "unknown" log.info("MPD version: %s" % mpd_version) def stop(self): remuco.PlayerAdapter.stop(self) try: self.__mpd.disconnect() except mpd.ConnectionError: pass log.debug("MPD adapter stopped") def poll(self): self.__poll_status() self.__poll_item() # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): if not self.__check_and_refresh_connection(): return try: if self.__playing: self.__mpd.pause(1) else: self.__mpd.play() except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_toggle_repeat(self): if not self.__check_and_refresh_connection(): return try: self.__mpd.repeat(int(not self.__repeat)) except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_toggle_shuffle(self): if not self.__check_and_refresh_connection(): return try: self.__mpd.random(int(not self.__shuffle)) except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_next(self): if not self.__check_and_refresh_connection(): return try: self.__mpd.next() except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_previous(self): if not self.__check_and_refresh_connection(): return try: self.__mpd.previous() except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_seek(self, direction): if self.__length == 0: return if not self.__check_and_refresh_connection(): return progress = self.__progress + direction * 5 progress = min(progress, self.__length) progress = max(progress, 0) try: self.__mpd.seek(self.__position, progress) except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) def ctrl_volume(self, direction): if not self.__check_and_refresh_connection(): return try: if direction == 0: self.__mpd.setvol(0) else: volume = self.__volume + direction * 5 volume = min(volume, 100) volume = max(volume, 0) self.__mpd.setvol(volume) except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) else: gobject.idle_add(self.__poll_status) # ========================================================================= # action interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if not self.__check_and_refresh_connection(): return if action_id == IA_JUMP.id: try: self.__mpd.play(positions[0]) except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) elif action_id == IA_REMOVE.id: positions.sort() positions.reverse() self.__batch_cmd(self.__mpd.delete, positions) else: log.error("** BUG ** unexpected playlist item action") def action_mlib_item(self, action_id, path, positions, ids): if not self.__check_and_refresh_connection(): return if action_id == IA_ADD.id: self.__batch_cmd(self.__mpd.add, ids) elif action_id == IA_SET.id: try: self.__mpd.clear() self.__batch_cmd(self.__mpd.add, ids) if self.__playing: self.__mpd.play(0) except mpd.MPDError, e: log.warning("failed to set playlist: %s" % e) else: log.error("** BUG ** unexpected mlib item action") def action_mlib_list(self, action_id, path): if not self.__check_and_refresh_connection(): return try: name = path[1] except IndexError: log.error("** BUG ** unexpected path for list actions: %s" % path) return if action_id == LA_ENQUEUE.id: try: self.__mpd.load(name) except mpd.MPDError, e: log.warning("failed to enqueue playlist (%s): %s" % (name, e)) elif action_id == LA_PLAY.id: try: self.__mpd.clear() self.__mpd.load(name) if self.__playing: self.__mpd.play(0) except mpd.MPDError, e: log.warning("failed to play playlist (%s): %s" % (name, e)) elif action_id == DA_ENQUEUE.id: try: xpath = os.path.sep.join(path[1:]) self.__mpd.add(xpath) except mpd.MPDERROR, e: log.warning("failed to add in playlist (%s): %s" % (path_s, e)) elif action_id == DA_PLAY.id: try: xpath = os.path.sep.join(path[1:]) self.__mpd.clear() self.__mpd.add(xpath) except mpd.MPDERROR, e: log.warning("failed to set playlist (%s): %s" % (path_s, e)) else: log.error("** BUG ** unexpected mlib list action") def action_search_item(self, action_id, positions, ids): self.action_mlib_item(action_id, [], positions, ids) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): if not self.__check_and_refresh_connection(): return try: playlist = self.__mpd.playlistinfo() except mpd.MPDError, e: log.warning("failed to control MPD: %s" % e) playlist = [] for song in playlist: reply.ids.append(song.get("file", "XXX")) artist = song.get("artist", "??") title = song.get("title", "??") reply.names.append("%s - %s" % (artist, title)) reply.item_actions = PLAYLIST_ACTIONS reply.send() def request_mlib(self, reply, path): if not self.__check_and_refresh_connection(): return if not path: reply.nested = [MLIB_FILES, MLIB_PLAYLISTS] elif path[0] == MLIB_FILES: reply.nested, reply.ids, reply.names = self.__get_music_dir(path[1:]) reply.item_actions = MLIB_ITEM_ACTIONS reply.list_actions = MLIB_DIR_ACTIONS elif path[0] == MLIB_PLAYLISTS and len(path) == 1: reply.nested = self.__get_playlists() reply.list_actions = MLIB_LIST_ACTIONS elif path[0] == MLIB_PLAYLISTS and len(path) == 2: reply.ids, reply.names = self.__get_playlist_content(path[1]) reply.item_actions = MLIB_ITEM_ACTIONS elif path[0] == MLIB_PLAYLISTS: log.error("** BUG ** unexpected path depth for playlists") else: log.error("** BUG ** unexpected root list: %s" % path[0]) reply.send() def request_search(self, reply, query): if not self.__check_and_refresh_connection(): return result_dicts = [] for field, value in zip(SEARCH_MASK, query): if not value: continue songs = self.__mpd.search(field, value) result = {} for song in songs: result[song.get("file", "unknown")] = song result_dicts.append(result) result = self.__intersect_dicts(result_dicts) reply.ids, reply.names = self.__songs_to_item_list(result.values(), True) reply.item_actions = MLIB_ITEM_ACTIONS reply.send() # ========================================================================= # internal methods # ========================================================================= def __poll_status(self): if not self.__check_and_refresh_connection(): return status = self.__mpd.status() self.__volume = int(status.get("volume", "0")) self.update_volume(self.__volume) self.__repeat = status.get("repeat", "0") != "0" self.update_repeat(self.__repeat) self.__shuffle = status.get("random", "0") != "0" self.update_shuffle(self.__shuffle) playback = status.get("state", "stop") if playback == "play": self.__playing = True self.update_playback(remuco.PLAYBACK_PLAY) elif playback == "pause": self.__playing = False self.update_playback(remuco.PLAYBACK_PAUSE) else: self.__playing = False self.update_playback(remuco.PLAYBACK_STOP) progress_length = status.get("time", "0:0").split(':') self.__progress = int(progress_length[0]) self.__length = int(progress_length[1]) self.update_progress(self.__progress, self.__length) self.__position = int(status.get("song", "-1")) self.update_position(max(int(self.__position), 0)) def __poll_item(self): if not self.__check_and_refresh_connection(): return try: song = self.__mpd.currentsong() except mpd.MPDError, e: log.warning("failed to query current song: %s" % e) song = None if self.__song == song: return self.__song = song if not song: self.update_item(None, None, None) return id = song.get("file", "XXX") info = {} info[remuco.INFO_ARTIST] = song.get("artist") info[remuco.INFO_TITLE] = song.get("title") info[remuco.INFO_ALBUM] = song.get("album") info[remuco.INFO_GENRE] = song.get("genre") info[remuco.INFO_LENGTH] = song.get("time") info[remuco.INFO_YEAR] = song.get("year") full_file_name = os.path.join(self.__mpd_music, id) img = self.find_image(full_file_name) self.update_item(id, info, img) def __get_music_dir(self, path): """Client requests a certain path in MPD's music directory.""" path_s = "" for elem in path: path_s = os.path.join(path_s, elem) try: content = self.__mpd.lsinfo(path_s) except mpd.MPDError, e: log.warning("failed to get dir list (%s): %s" % (path_s, e)) content = [] dirs, files = [], [] for entry in content: if "directory" in entry: dirs.append(os.path.basename(entry["directory"])) elif "file" in entry: files.append(entry["file"]) else: pass songs = self.__batch_cmd(self.__mpd.listallinfo, files) names = [] if songs and len(songs) == len(files): for item in songs: artist = item[0].get("artist", "??") title = item[0].get("title", "??") names.append("%s - %s" % (artist, title)) else: files = [] return dirs, files, names def __get_playlists(self): try: content = self.__mpd.lsinfo() except mpd.MPDError, e: log.warning("failed to get playlists: %s" % e) content = [] names = [] for entry in content: if "playlist" in entry: names.append(os.path.basename(entry["playlist"])) else: pass return names def __get_playlist_content(self, name): try: songs = self.__mpd.listplaylistinfo(name) except mpd.MPDError, e: log.warning("failed to get playlist content (%s): %s" % (name, e)) songs = [] return self.__songs_to_item_list(songs) def __songs_to_item_list(self, songs, sort=False): ids, names = [], [] def skey(song): # sorting key for songs album = song.get("album", "") track = int(song.get("track", "0").split("/")[0]) disc = int(song.get("disc", "0").split("/")[0]) return "%s.%02d.%03d" % (album, disc, track) if sort: songs = sorted(songs, key=skey) for item in songs: ids.append(item.get("file", "XXX")) artist = item.get("artist", "??") title = item.get("title", "??") names.append("%s - %s" % (artist, title)) return ids, names def __check_and_refresh_connection(self): """Check the current MPD connection and reconnect if broken.""" try: self.__mpd.ping() except mpd.ConnectionError: try: self.__mpd.disconnect() except mpd.ConnectionError: pass try: self.__mpd.connect(self.__mpd_host, self.__mpd_port) self.__mpd.ping() if self.__mpd_pwd: self.__mpd.password(self.__mpd_pwd) log.debug("connected to MPD") except (mpd.ConnectionError, socket.error), e: log.error("failed to connect to MPD: %s" % e) self.manager.stop() return False return True def __intersect_dicts(self, dict_list): """Creates an intersection of dictionaries based on keys.""" if not dict_list: return {} first, rest = dict_list[0], dict_list[1:] keys_intersection = set(first.keys()) for other_dict in rest: keys_intersection.intersection_update(set(other_dict.keys())) result = {} for key in keys_intersection: result[key] = first[key] return result def __batch_cmd(self, cmd, params): try: self.__mpd.command_list_ok_begin() except mpd.MPDError, e: log.warning("failed to start command list: %s" % e) return for param in params: try: cmd(param) except mpd.MPDError, e: log.warning("in-list command failed: %s" % e) break try: return self.__mpd.command_list_end() except mpd.MPDError, e: log.warning("failed to end command list: %s" % e) try: self.__mpd.disconnect() except mpd.ConnectionError: pass # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = MPDAdapter() mg = remuco.Manager(pa) mg.run() remuco-source-0.9.6/adapter/mplayer/remuco-mplayer0000755000000000000000000003325111700415064022236 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= # Some remote control related documentation for MPlayer is available at # http://www.mplayerhq.hu/DOCS/tech/slave.txt # To parse the status line, read # http://www.mplayerhq.hu/DOCS/HTML/en/faq.html#id2734829 """MPlayer adapter for Remuco, implemented as an executable script.""" import os import os.path import gobject import re import sys import subprocess import remuco from remuco import log from remuco.defs import * FA_APPEND = remuco.ItemAction("Append") FA_PLAY = remuco.ItemAction("Play") FILE_ACTIONS = (FA_APPEND, FA_PLAY) MODE_INDEPENDENT = 1 << 0 MODE_MASTER = 1 << 1 class MplayerAdapter(remuco.PlayerAdapter): def __init__(self, filelist=None): remuco.PlayerAdapter.__init__(self, "MPlayer", progress_known=True, file_actions=FILE_ACTIONS, mime_types=remuco.MIMETYPES_AV) self.__mode = MODE_INDEPENDENT if filelist is not None: self.filelist = filelist self.__mode = MODE_MASTER # TODO put this somewhere else if self.__mode is MODE_INDEPENDENT: self.cmdfifo = os.path.join(self.config.cache, "mplayer.cmdfifo") self.cmdfifo = self.config.getx("cmdfifo", self.cmdfifo) self.statusfifo = os.path.join(self.config.cache, "mplayer.statusfifo") self.statusfifo = self.config.getx("statusfifo", self.statusfifo) # file descriptors [self.fd_cmd_stream_in, self.fd_cmd_stream_out, self.fd_status_stream_in, self.fd_status_stream_out] = [None]*4 # gobject's watches: self.watch_id = None # read from mplayer using statusfifo self.watch_death = None # wait for mplayer exit (MODE_MASTER) # compile regexes to be used when parsing the status string # in __inputevent() # TODO use a generic self.current_regex pointing to either one # of video_regex or audio_regex and update it whenever the current # file in the playlist changes. # NOTE there is a space char after every information # NOTE audio_regex contains a "pretty position" which looks like: # ([[HH:]MM:]SS.d) # i wonder how far does it go... self.video_regex = re.compile( r"""^A:\s*(?P\d+\.\d)\s # audio position (seconds) V:\s*(?P\d+\.\d)\s # video position (seconds) A-V:\s*(?P-?\d+\.\d+)\s # video position (seconds) (?P) # identify this regex uniquely """, re.VERBOSE) self.audio_regex = re.compile( r"""^A:\s*(?P\d+\.\d)\s # raw position (seconds) \((?P(\d\d:)*\d\d\.\d)\)\s # pretty position of (?P\d+\.\d)\s # total length in seconds \((?P(\d\d:)*\d\d\.\d)\)\s # pretty total (?P) # identifier """, re.VERBOSE) self.info_regex = re.compile( r"""^ANS_(?P[A-Za-z_]+)= # information name (?P('.*'|\d+\.\d+)) # if quoted, str. else, number (?P) # identifier """, re.VERBOSE) self.pause_regex = re.compile(r" *===+ +\w+ +===+") self.__set_default_info() def start(self): remuco.PlayerAdapter.start(self) self.__setup_streams() self.watch_id = gobject.io_add_watch(self.fd_status_stream_in, gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP, self.__inputevent) if self.__mode is MODE_MASTER: args = ['mplayer', '-slave', '-input', 'file=/dev/null'] args += self.filelist self.__mplayer_pid = subprocess.Popen(args, bufsize=1, stdin=self.fd_cmd_stream_in, stdout=self.fd_status_stream_out).pid def cb(pid, condition, user_data=None): #local callback for watch_death self.manager.stop() self.watch_death = gobject.child_watch_add(self.__mplayer_pid, cb) log.debug("starting mplayer adapter") def stop(self): # FIXME probable bug: call manager.stop from here, # and the manager will call stop_pa again remuco.PlayerAdapter.stop(self) if self.fd_cmd_stream_in is not None: os.closerange(self.fd_cmd_stream_in, self.fd_status_stream_out) [self.fd_cmd_stream_in, self.fd_cmd_stream_out, self.fd_status_stream_in, self.fd_status_stream_out] = [None]*4 if self.watch_id is not None: gobject.source_remove(self.watch_id) self.watch_id = None if self.watch_death is not None: gobject.source_remove(self.watch_death) self.watch_death = None log.debug("stopping mplayer adapter") def poll(self): # fetch important information from player # NOTE while this fixes most of our problems, it will always # clutter mplayer's output if self.__playback == PLAYBACK_PLAY: self.__command('get_time_length\n') self.__command('get_file_name\n') self.__command('get_property volume\n') # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): self.__command('pause\n') def ctrl_toggle_fullscreen(self): self.__command('vo_fullscreen\n') def ctrl_next(self): self.__command('pt_step 1\n') gobject.idle_add(self.poll) def ctrl_previous(self): self.__command('pt_step -1\n') gobject.idle_add(self.poll) def ctrl_volume(self, direction): self.__command('volume %d %d\n' % (direction, direction==0)) gobject.idle_add(self.poll) def ctrl_seek(self, direction): self.__command('seek %s0\n' % direction) def ctrl_navigate(self, action): button = ['up', 'down', 'left', 'right', 'select', 'prev', 'menu'] if action >= 0 and action < button.__len__(): self.__command('dvdnav %s\n' % button[action]) # ========================================================================= # request interface # ========================================================================= #def request_playlist(self, client): # self.reply_playlist_request(client, ["1", "2"], # ["Joe - Joe's Song", "Sue - Sue's Song"]) # ... # ========================================================================= # actions interface # ========================================================================= def action_files(self, action_id, files, uris): if action_id == FA_APPEND.id: for file in files: self.__command('loadfile "%s" 1' % file) elif action_id == FA_PLAY.id: self.__command('loadfile "%s"' % files[0]) else: log.error("** BUG ** unexpected action ID") # ========================================================================= # internal methods # ========================================================================= def __command(self, cmd): """Write a command to the MPlayer FIFO and handle errors.""" try: os.write(self.fd_cmd_stream_out, cmd) except OSError, e: log.warning("FIFO to MPlayer broken (%s)", e) self.manager.stop() def __read_stream(self, fd): """Read from a file descriptor and handle errors.""" try: str = os.read(fd, 200) #magic buflength number return str except OSError, e: log.warning("FIFO from MPlayer broken (%s)", e) self.manager.stop() def __inputevent(self, fd, condition): """Parse incoming line from the player""" if condition == gobject.IO_IN: # read from fd (fd is self.fd_status_stream_in) status_str = self.__read_stream(fd) if self.pause_regex.search(status_str): self.__playback = PLAYBACK_PAUSE self.update_playback(PLAYBACK_PAUSE) return True matchobj = (self.video_regex.match(status_str) or self.audio_regex.match(status_str) or self.info_regex.match(status_str)) if matchobj is not None: self.__playback = PLAYBACK_PLAY self.update_playback(self.__playback) current_progress = self.__progress current_length = self.info[INFO_LENGTH] identifier = matchobj.lastgroup if identifier == 'videoregex': # we have a video regex current_progress = float(matchobj.group('rawvideopos')) elif identifier == 'inforegex': # info regex self.__set_info(matchobj.group('infovar'), matchobj.group('infovalue')) current_length = self.info[INFO_LENGTH] #avoid a race condition elif identifier == 'audioregex': # audio regex current_progress = float(matchobj.group('rawaudiopos')) current_length = float(matchobj.group('rawtotal')) self.update_progress(current_progress, current_length) self.__progress = current_progress self.info[INFO_LENGTH] = current_length return True else: if condition == gobject.IO_HUP: # mplayer has probably quit log.info("statusfifo hangup. is mplayer still running?") else: log.error("statusfifo read error") self.stop() gobject.idle_add(self.start) return False def __set_info(self, name, value): """ Set global information of current item @param name: The name of the variable in mplayer. (str) @param value: The value mplayer assigns. (str) @see self.__inputevent() and self.info_regex for more information """ if name == 'LENGTH': self.info[INFO_LENGTH] = float(value) elif name == 'FILENAME': self.info[INFO_TITLE] = value.strip("'") self.update_item(self.info[INFO_TITLE], self.info, None) elif name == 'volume': # lower case because we use the get_property command self.update_volume(float(value)) def __set_default_info(self): """ Set default playback information """ self.__progress = 0 self.__playback = PLAYBACK_STOP self.info = { INFO_LENGTH: 100, INFO_TITLE: '' } def __setup_streams(self): """ Setup information streams. This depends on the mode we are running: MODE_INDEPENDENT - uses FIFOs to issue commands and fetch status information MODE_MASTER - uses a newly created pipe to connect to mplayer directly """ if self.__mode is MODE_INDEPENDENT: if not(os.path.exists(self.cmdfifo)): os.mkfifo(self.cmdfifo) if not(os.path.exists(self.statusfifo)): os.mkfifo(self.statusfifo) else: log.warning('statusfifo file already exists. this is not a ' + 'problem, but you might end up with a big file if ' + self.statusfifo + ' is not a FIFO.') log.debug("opening cmdfifo and waiting for mplayer to read it") self.fd_cmd_stream_out = os.open(self.cmdfifo, os.O_WRONLY) self.fd_cmd_stream_in = self.fd_cmd_stream_out log.debug("opening statusfifo") self.fd_status_stream_in = os.open(self.statusfifo, os.O_RDONLY | os.O_NONBLOCK) self.fd_status_stream_out = self.fd_status_stream_in else: # MODE_MASTER log.debug("creating pipes to communicate with mplayer") self.fd_cmd_stream_in, self.fd_cmd_stream_out = os.pipe() self.fd_status_stream_in, self.fd_status_stream_out = os.pipe() # ============================================================================= # main # ============================================================================= if __name__ == '__main__': filepaths = None # TODO use 'optparser' module instead if sys.argv.__len__() > 1: filepaths = [] # TODO parse arguments looking for mplayer options #parse arguments looking for video files for arg in sys.argv[1:]: if os.path.isfile(arg): filepaths.append(arg) pa = MplayerAdapter(filepaths) # create the player adapter mg = remuco.Manager(pa) # pass it to a manager mg.run() # run the manager (blocks until interrupt signal) remuco-source-0.9.6/adapter/okular/.wip0000644000000000000000000000000011700415064017755 0ustar rootroot00000000000000remuco-source-0.9.6/adapter/okular/remuco-okular0000755000000000000000000001356311700415064021712 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Okular adapter for Remuco, implemented as an executable script.""" import commands import os.path import re import dbus from dbus.exceptions import DBusException import remuco from remuco import log IA_GOTO = remuco.ItemAction("Go to page", multiple=False) IA_OPEN = remuco.ItemAction("Open file", multiple=False) class OkularAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "Okular", playback_known=True, volume_known=True, search_mask=["Page"], file_actions=[IA_OPEN], mime_types=["application/pdf"]) self.__am = None self.__image = os.path.join(self.config.cache, "okular.thumbnail") def start(self): remuco.PlayerAdapter.start(self) try: bus = dbus.SessionBus() proxy = bus.get_object("org.freedesktop.DBus", "/") dbusiface = dbus.Interface(proxy, "org.freedesktop.DBus") okulariface = None for iface in dbusiface.ListNames(): if "okular" in iface: okulariface = iface proxy = bus.get_object(okulariface, "/okular") self.__am = dbus.Interface(proxy, "org.kde.okular") except DBusException, e: raise StandardError("dbus error: %s" % e) def stop(self): remuco.PlayerAdapter.stop(self) log.debug("bye, turning off the light") def poll(self): self.refreshdata(refresh_image=True) def refreshdata(self, refresh_image=False): doc = self.__am.currentDocument() page = self.__am.currentPage() page_max = self.__am.pages() info = {} info[remuco.INFO_TITLE] = os.path.basename(doc) info[remuco.INFO_ARTIST] = "%d/%d" % (page, page_max) if refresh_image: commands.getoutput('convert "%s"[%s] -thumbnail 150 %s' % (doc, page, self.__image)) image = self.__image else: image = None self.update_item(None, info, image) self.update_volume((float(page) / page_max * 100)) # ========================================================================= # control interface # ========================================================================= def ctrl_next(self): self.__am.slotNextPage() self.refreshdata() def ctrl_previous(self): self.__am.slotPreviousPage() self.refreshdata() def ctrl_volume(self, direction): if direction == 0: self.__am.goToPage(1) elif direction == -1: if self.__am.currentPage() - 10 < 1: self.__am.slotGotoFirst() else: self.__am.goToPage(self.__am.currentPage() - 10) elif direction == 1: if self.__am.currentPage() + 10 > self.__am.pages(): self.__am.slotGotoLast() else: self.__am.goToPage(self.__am.currentPage() + 10) self.refreshdata() def ctrl_toggle_fullscreen(self): self.__am.slotTogglePresentation() # ========================================================================= # actions interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if action_id == IA_GOTO.id: self.__am.goToPage(ids[0]) def action_files(self, action_id, files, uris): if action_id == IA_OPEN.id: self.__am.openDocument(uris[0]) self.refreshdata(True) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): reply.ids = range(1, self.__am.pages()+1) reply.names = range(1, self.__am.pages()+1) reply.item_actions = [IA_GOTO] reply.send() def request_search(self, reply, query): if (re.match("^[0-9]+$", query[0]) and int(query[0]) < self.__am.pages() and int(query[0]) > 0): reply.ids = [query[0]] reply.names = ["Page %s opened" % query[0]] self.__am.goToPage(int(query[0])) else: reply.ids = ["0"] reply.names = ["No such page"] reply.send() # ============================================================================= # main (example startup using remuco.Manager) # ============================================================================= if __name__ == '__main__': pa = OkularAdapter() mg = remuco.Manager(pa) mg.run() remuco-source-0.9.6/adapter/quodlibet/remuco-quodlibet0000755000000000000000000001653411700415064023101 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """QuodLibet adapter for Remuco, implemented as an executable script.""" # TODO: This adapter currently is a script. An adapter implemented as a QL # plugin probably would provide significantly more features, especially # concerning media library integration. import commands import dbus from dbus.exceptions import DBusException import gobject import remuco from remuco import log class QuodLibetAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "QuodLibet", progress_known=True, playback_known=True, repeat_known=True, shuffle_known=True, max_rating=4) self.__dbus_signal_handler = () self.__ql_dbus = None self.__song_len = 0 # need this when polling progress def start(self): remuco.PlayerAdapter.start(self) # set up DBus connection try: bus = dbus.SessionBus() proxy = bus.get_object("net.sacredchao.QuodLibet", "/net/sacredchao/QuodLibet") self.__ql_dbus = dbus.Interface(proxy, "net.sacredchao.QuodLibet") except DBusException, e: raise StandardError("dbus error: %s" % e) # connect to DBus signals try: self.__dbus_signal_handler = ( self.__ql_dbus.connect_to_signal("Paused", self.__on_paused), self.__ql_dbus.connect_to_signal("Unpaused", self.__on_unpaused), self.__ql_dbus.connect_to_signal("SongStarted", self.__on_song_started), self.__ql_dbus.connect_to_signal("SongEnded", self.__on_song_ended), ) except DBusException, e: raise StandardError("dbus error: %s" % e) # misc initialization self.__song_len = 0 # initial info retrieval self.poll() if self.__ql_dbus.IsPlaying(): self.__on_song_started(self.__ql_dbus.CurrentSong()) self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_PAUSE) def stop(self): remuco.PlayerAdapter.stop(self) # disconnect DBus stuff for handler in self.__dbus_signal_handler: handler.remove() self.__dbus_signal_handler = () self.__ql_dbus = None def poll(self): self.__poll_status() self.__poll_progress() # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): self.__ql_dbus.PlayPause() def ctrl_next(self): self.__ql_dbus.Next() def ctrl_previous(self): self.__ql_dbus.Previous() def ctrl_toggle_shuffle(self): self.__ql_cmd("--order=toggle") gobject.idle_add(self.__poll_status) def ctrl_toggle_repeat(self): self.__ql_cmd("--repeat=t") gobject.idle_add(self.__poll_status) def ctrl_volume(self, direction): if direction == 0: self.__ql_cmd("--volume=0") elif direction == -1: self.__ql_cmd("--volume-down") else: self.__ql_cmd("--volume-up") gobject.idle_add(self.__poll_status) def ctrl_rate(self, rating): self.__ql_cmd("--set-rating=%1.1f" % (float(rating) / 4)) # ========================================================================= # request interface # ========================================================================= # ... not yet supported, see TODO on top # ========================================================================= # helper # ========================================================================= def __ql_cmd(self, action): """QL command line interaction.""" return commands.getoutput("quodlibet " + action) def __on_paused(self): """DBus signal handler.""" self.update_playback(remuco.PLAYBACK_PAUSE) def __on_unpaused(self): """DBus signal handler.""" self.update_playback(remuco.PLAYBACK_PLAY) def __on_song_started(self, song): """DBus signal handler.""" info = {} info[remuco.INFO_ALBUM] = song.get("album", None) info[remuco.INFO_ARTIST] = song.get("artist", None) info[remuco.INFO_GENRE] = song.get("genre", None) info[remuco.INFO_LENGTH] = song.get("~#length", 0) info[remuco.INFO_RATING] = int(float(song.get("~#rating", 0.5)) * 4) info[remuco.INFO_TITLE] = song.get("title", None) info[remuco.INFO_YEAR] = song.get("date", 0) info[remuco.INFO_BITRATE] = int(song.get("~#bitrate", 0)) / 1000 self.__song_len = info[remuco.INFO_LENGTH] # QL does not provide an ID/URI -> no chance to get local cover art self.update_item(None, info, None) def __on_song_ended(self, song, skipped): """DBus signal handler.""" self.update_item(None, None, None) self.__song_len = 0 self.update_progress(0, 0) def __poll_status(self): """Poll volume, repeat and shuffle.""" status = self.__ql_cmd("--status").split() if status and len(status) == 5: self.update_volume(float(status[2]) * 100) self.update_shuffle(status[3] != "inorder") self.update_repeat(status[4] == "on") else: self.update_volume(50) self.update_shuffle(False) self.update_repeat(False) def __poll_progress(self): """Poll playback progress.""" if self.__ql_dbus.IsPlaying(): self.update_progress(self.__ql_dbus.GetPosition() / 1000, self.__song_len) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = QuodLibetAdapter() mg = remuco.Manager(pa, dbus_name="net.sacredchao.QuodLibet") mg.run() remuco-source-0.9.6/adapter/rhythmbox/install-check.py0000644000000000000000000000057611700415064023021 0ustar rootroot00000000000000import sys try: import gconf except ImportError, e: print("") print("+-----------------------------------------------------------------+") print("| Unsatisfied Python requirement: %s." % e) print("| Please install the missing module and then retry.") print("+-----------------------------------------------------------------+") print("") sys.exit(1)remuco-source-0.9.6/adapter/rhythmbox/remuco.rb-plugin0000644000000000000000000000034511700415064023033 0ustar rootroot00000000000000[RB Plugin] Loader=python Module=remythm IAge=1 Name=Remuco Description=Rhythmbox adapter for Remuco (and vice versa). Authors=Remuco team Copyright=Copyright © 2006-2010 by the Remuco team Website=http://remuco.googlecode.com/ remuco-source-0.9.6/adapter/rhythmbox/remythm.py0000644000000000000000000005650011700415064021763 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Rhythmbox player adapter for Remuco, implemented as a Rhythmbox plugin.""" import time import gconf import gobject import rb, rhythmdb import remuco from remuco import log # ============================================================================= # plugin # ============================================================================= class RemucoPlugin(rb.Plugin): def __init__(self): rb.Plugin.__init__(self) self.__rba = None def activate(self, shell): if self.__rba is not None: return print("create RhythmboxAdapter") self.__rba = RhythmboxAdapter() print("RhythmboxAdapter created") print("start RhythmboxAdapter") self.__rba.start(shell) print("RhythmboxAdapter started") def deactivate(self, shell): if self.__rba is None: return print("stop RhythmboxAdapter") self.__rba.stop() print("RhythmboxAdapter stopped") self.__rba = None # ============================================================================= # constants # ============================================================================= PLAYORDER_SHUFFLE = "shuffle" PLAYORDER_SHUFFLE_ALT = "random-by-age-and-rating" PLAYORDER_REPEAT = "linear-loop" PLAYORDER_NORMAL = "linear" PLAYERORDER_TOGGLE_MAP_REPEAT = { PLAYORDER_SHUFFLE: PLAYORDER_SHUFFLE_ALT, PLAYORDER_SHUFFLE_ALT: PLAYORDER_SHUFFLE, PLAYORDER_REPEAT: PLAYORDER_NORMAL, PLAYORDER_NORMAL: PLAYORDER_REPEAT } PLAYERORDER_TOGGLE_MAP_SHUFFLE = { PLAYORDER_SHUFFLE: PLAYORDER_NORMAL, PLAYORDER_NORMAL: PLAYORDER_SHUFFLE, PLAYORDER_SHUFFLE_ALT: PLAYORDER_REPEAT, PLAYORDER_REPEAT: PLAYORDER_SHUFFLE_ALT } SEARCH_MASK = ("Any", "Artist", "Title", "Album", "Genre") SEARCH_PROPS = ("Any", rhythmdb.PROP_ARTIST, rhythmdb.PROP_TITLE, rhythmdb.PROP_ALBUM, rhythmdb.PROP_GENRE) SEARCH_PROPS_ANY = (rhythmdb.PROP_ARTIST, rhythmdb.PROP_TITLE, rhythmdb.PROP_ALBUM, rhythmdb.PROP_GENRE, rhythmdb.PROP_LOCATION) # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") IA_REMOVE = remuco.ItemAction("Remove", multiple=True) LA_PLAY = remuco.ListAction("Play") IA_ENQUEUE = remuco.ItemAction("Enqueue", multiple=True) PLAYLIST_ACTIONS = (IA_JUMP, IA_ENQUEUE) QUEUE_ACTIONS = (IA_JUMP, IA_REMOVE) MLIB_LIST_ACTIONS = (LA_PLAY,) MLIB_ITEM_ACTIONS = (IA_ENQUEUE, IA_JUMP) SEARCH_ACTIONS = (IA_ENQUEUE,) # ============================================================================= # player adapter # ============================================================================= class RhythmboxAdapter(remuco.PlayerAdapter): def __init__(self): self.__shell = None self.__gconf = None remuco.PlayerAdapter.__init__(self, "Rhythmbox", max_rating=5, playback_known=True, volume_known=True, repeat_known=True, shuffle_known=True, progress_known=True, search_mask=SEARCH_MASK) self.__item_id = None self.__item_entry = None self.__playlist_sc = None self.__queue_sc = None self.__signal_ids = () log.debug("init done") def start(self, shell): if self.__shell is not None: log.warning("already started") return remuco.PlayerAdapter.start(self) self.__shell = shell sp = self.__shell.get_player() # gconf is used to adjust repeat and shuffle self.__gconf = gconf.client_get_default() # shortcuts to RB data self.__item_id = None self.__item_entry = None self.__playlist_sc = sp.get_playing_source() self.__queue_sc = self.__shell.props.queue_source # connect to shell player signals self.__signal_ids = ( sp.connect("playing_changed", self.__notify_playing_changed), sp.connect("playing_uri_changed", self.__notify_playing_uri_changed), sp.connect("playing-source-changed", self.__notify_source_changed) ) # state sync will happen by timeout # trigger item sync: self.__notify_playing_uri_changed(sp, sp.get_playing_path()) # item sync log.debug("start done") def stop(self): remuco.PlayerAdapter.stop(self) if self.__shell is None: return # disconnect from shell player signals sp = self.__shell.get_player() for sid in self.__signal_ids: sp.disconnect(sid) self.__signal_ids = () # release shell self.__shell = None self.__gconf = None log.debug("stop done") def poll(self): sp = self.__shell.get_player() # check repeat and shuffle order = sp.props.play_order repeat = order == PLAYORDER_REPEAT or order == PLAYORDER_SHUFFLE_ALT self.update_repeat(repeat) shuffle = order == PLAYORDER_SHUFFLE or order == PLAYORDER_SHUFFLE_ALT self.update_shuffle(shuffle) # check volume volume = int(sp.get_volume() * 100) self.update_volume(volume) # check progress try: progress = sp.get_playing_time() length = sp.get_playing_song_duration() except gobject.GError: progress = 0 length = 0 else: self.update_progress(progress, length) # ========================================================================= # control interface # ========================================================================= def ctrl_next(self): sp = self.__shell.get_player() try: sp.do_next() except gobject.GError, e: log.debug("do next failed: %s" % str(e)) def ctrl_previous(self): sp = self.__shell.get_player() try: sp.set_playing_time(0) time.sleep(0.1) sp.do_previous() except gobject.GError, e: log.debug("do previous failed: %s" % str(e)) def ctrl_rate(self, rating): if self.__item_entry is not None: db = self.__shell.props.db try: db.set(self.__item_entry, rhythmdb.PROP_RATING, rating) except gobject.GError, e: log.debug("rating failed: %s" % str(e)) def ctrl_toggle_playing(self): sp = self.__shell.get_player() try: sp.playpause() except gobject.GError, e: log.debug("toggle play pause failed: %s" % str(e)) def ctrl_toggle_repeat(self): sp = self.__shell.get_player() now = sp.props.play_order next = PLAYERORDER_TOGGLE_MAP_REPEAT.get(now, now) self.__gconf.set_string("/apps/rhythmbox/state/play_order", next) # update state within a short time (don't wait for scheduled poll) gobject.idle_add(self.poll) def ctrl_toggle_shuffle(self): sp = self.__shell.get_player() now = sp.props.play_order next = PLAYERORDER_TOGGLE_MAP_SHUFFLE.get(now, now) self.__gconf.set_string("/apps/rhythmbox/state/play_order", next) # update state within a short time (don't wait for scheduled poll) gobject.idle_add(self.poll) def ctrl_seek(self, direction): sp = self.__shell.get_player() try: sp.seek(direction * 5) except gobject.GError, e: log.debug("seek failed: %s" % str(e)) else: # update volume within a short time (don't wait for scheduled poll) gobject.idle_add(self.poll) def ctrl_volume(self, direction): sp = self.__shell.get_player() if direction == 0: sp.set_volume(0) else: try: sp.set_volume_relative(direction * 0.05) except gobject.GError, e: log.debug("set volume failed: %s" % str(e)) # update volume within a short time (don't wait for scheduled poll) gobject.idle_add(self.poll) # ========================================================================= # action interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: try: self.__jump_in_plq(self.__playlist_sc, positions[0]) except gobject.GError, e: log.debug("playlist jump failed: %s" % e) elif action_id == IA_ENQUEUE.id: self.__enqueue_items(ids) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_queue_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: try: self.__jump_in_plq(self.__queue_sc, positions[0]) except gobject.GError, e: log.debug("queue jump failed: %s" % e) elif action_id == IA_REMOVE.id: for id in ids: self.__shell.remove_from_queue(id) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_mlib_item(self, action_id, path, positions, ids): if action_id == IA_ENQUEUE.id: self.__enqueue_items(ids) if action_id == IA_JUMP.id: self.action_mlib_list(LA_PLAY.id, path) # delay jump, otherwise sync with clients sometimes fails gobject.timeout_add(100, self.action_playlist_item, IA_JUMP.id, positions, ids) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_mlib_list(self, action_id, path): if action_id == LA_PLAY.id: sc = self.__mlib_path_to_source(path) if sc is None: log.warning("no source for path %s" % path) return sp = self.__shell.get_player() if sc != self.__playlist_sc: try: sp.set_selected_source(sc) sp.set_playing_source(sc) self.__jump_in_plq(sc, 0) except gobject.GError, e: log.debug("switching source failed: %s" % str(e)) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_search_item(self, action_id, positions, ids): if action_id == IA_ENQUEUE.id: self.__enqueue_items(ids) else: log.error("** BUG ** unexpected action: %d" % action_id) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): if self.__playlist_sc is None: reply.send() return try: qm = self.__playlist_sc.get_entry_view().props.model reply.ids, reply.names = self.__get_item_list_from_qmodel(qm) except gobject.GError, e: log.warning("failed to get playlist items: %s" % e) reply.item_actions = PLAYLIST_ACTIONS reply.send() def request_queue(self, reply): sc = self.__queue_sc qm = sc.props.query_model try: reply.ids, reply.names = self.__get_item_list_from_qmodel(qm) except gobject.GError, e: log.warning("failed to get queue items: %s" % e) reply.item_actions = QUEUE_ACTIONS reply.send() def request_mlib(self, reply, path): slm = self.__shell.props.sourcelist_model ### root ? ### if not path: for group in slm: group_name = group[2] reply.nested.append(group_name) reply.send() return ### group ? ### Library, Playlists if len(path) == 1: for group in slm: group_name = group[2] if path[0] == group_name: for sc in group.iterchildren(): source_name = sc[2] # FIXME: how to be l10n independent here? if source_name.startswith("Play Queue"): continue if source_name.startswith("Import Error"): continue log.debug("append %s" % source_name) reply.nested.append(source_name) break reply.list_actions = MLIB_LIST_ACTIONS reply.send() return ### regular playlist (source) ! ### Library/???, Playlists/??? sc = self.__mlib_path_to_source(path) if sc is None: reply.send() return qm = sc.get_entry_view().props.model try: reply.ids, reply.names = self.__get_item_list_from_qmodel(qm) except gobject.GError, e: log.warning("failed to list items: %s" % e) reply.item_actions = MLIB_ITEM_ACTIONS reply.send() def request_search(self, reply, query): def eval_entry(entry): match = True for key in query_stripped: if key == "Any": props = SEARCH_PROPS_ANY else: props = [key] for prop in props: val = db.entry_get(entry, prop).lower() if val.find(query_stripped[key]) >= 0: break else: match = False break if match: id, name = self.__get_list_item_from_entry(entry) reply.ids.append(id) reply.names.append(name) query_stripped = {} # stripped query dict for key, val in zip(SEARCH_PROPS, query): if val.strip(): query_stripped[key] = val.lower() if query_stripped: db = self.__shell.props.db db.entry_foreach(eval_entry) reply.item_actions = SEARCH_ACTIONS reply.send() # ========================================================================== # callbacks # ========================================================================== def __notify_playing_uri_changed(self, sp, uri): """Shell player signal callback to handle an item change.""" log.debug("playing uri changed: %s" % uri) db = self.__shell.props.db entry = sp.get_playing_entry() if entry is None: id = None else: id = db.entry_get(entry, rhythmdb.PROP_LOCATION) self.__item_id = id self.__item_entry = entry if entry is not None and id is not None: info = self.__get_item_from_entry(entry) img_data = db.entry_request_extra_metadata(entry, "rb:coverArt") if img_data is None: img_file = self.find_image(id) else: try: img_file = "%s/rhythmbox.cover" % self.config.cache img_data.save(img_file, "png") except IOError, e: log.warning("failed to save cover art (%s)" % e) img_file = None else: id = None img_file = None info = None self.update_item(id, info, img_file) # a new item may result in a new position: pfq = self.__shell.get_player().props.playing_from_queue self.update_position(self.__get_position(), queue=pfq) def __notify_playing_changed(self, sp, b): """Shell player signal callback to handle a change in playback.""" log.debug("playing changed: %s" % str(b)) if b: self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_PAUSE) def __notify_source_changed(self, sp, source_new): """Shell player signal callback to handle a playlist switch.""" log.debug("source changed: %s" % str(source_new)) self.__playlist_sc = source_new # ========================================================================= # helper methods # ========================================================================= def __jump_in_plq(self, sc, position): """Do a jump within the playlist or queue. @param sc: either current playlist or queue source @param position: position to jump to """ if sc is None: return qm = sc.get_entry_view().props.model id_to_remove_from_queue = None sp = self.__shell.get_player() if sp.props.playing_from_queue: id_to_remove_from_queue = self.__item_id found = False i = 0 for row in qm: if i == position: sp.set_selected_source(sc) sp.set_playing_source(sc) sp.play_entry(row[0]) found = True break i += 1 if not found: sp.do_next() if id_to_remove_from_queue != None: log.debug("remove %s from queue" % id_to_remove_from_queue) self.__shell.remove_from_queue(id_to_remove_from_queue) def __get_item_list_from_qmodel(self, qmodel): """Get all items in a query model. @return: 2 lists - IDs and names of the items """ ids = [] names = [] if qmodel is None: return (ids, names) for row in qmodel: id, name = self.__get_list_item_from_entry(row[0]) ids.append(id) names.append(name) return (ids, names) def __get_list_item_from_entry(self, entry): """Get Remuco list item from a Rhythmbox entry. @return: ID and name """ db = self.__shell.props.db id = db.entry_get(entry, rhythmdb.PROP_LOCATION) artist = db.entry_get(entry, rhythmdb.PROP_ARTIST) title = db.entry_get(entry, rhythmdb.PROP_TITLE) if artist and title: name = "%s - %s" % (artist, title) else: name = title or artist or "Unknown" return id, name def __get_item_from_entry(self, entry): """Get a Remuco item from a Rhythmbox entry. @return: meta information (dictionary) - also if entry is None (in this case dummy information is returned) """ if entry is None: return { remuco.INFO_TITLE : "No information" } db = self.__shell.props.db meta = { remuco.INFO_TITLE : str(db.entry_get(entry, rhythmdb.PROP_TITLE)), remuco.INFO_ARTIST: str(db.entry_get(entry, rhythmdb.PROP_ARTIST)), remuco.INFO_ALBUM : str(db.entry_get(entry, rhythmdb.PROP_ALBUM)), remuco.INFO_GENRE : str(db.entry_get(entry, rhythmdb.PROP_GENRE)), remuco.INFO_BITRATE : str(db.entry_get(entry, rhythmdb.PROP_BITRATE)), remuco.INFO_LENGTH : str(db.entry_get(entry, rhythmdb.PROP_DURATION)), remuco.INFO_RATING : str(int(db.entry_get(entry, rhythmdb.PROP_RATING))), remuco.INFO_TRACK : str(db.entry_get(entry, rhythmdb.PROP_TRACK_NUMBER)), remuco.INFO_YEAR : str(db.entry_get(entry, rhythmdb.PROP_YEAR)) } return meta def __mlib_path_to_source(self, path): """Get the source object related to a library path. @param path: must contain the source' group and name (2 element list) """ if len(path) != 2: log.error("** BUG ** invalid path length: %s" % path) return None group_name, source_name = path if group_name is None or source_name is None: return None slm = self.__shell.props.sourcelist_model for group in slm: if group_name == group[2]: for source in group.iterchildren(): if source_name == source[2]: return source[3] def __enqueue_items(self, ids): for id in ids: self.__shell.add_to_queue(id) def __get_position(self): sp = self.__shell.get_player() db = self.__shell.props.db position = 0 id_now = self.__item_id if id_now is not None: if sp.props.playing_from_queue: qmodel = self.__queue_sc.props.query_model elif self.__playlist_sc is not None: qmodel = self.__playlist_sc.get_entry_view().props.model else: qmodel = None if qmodel is not None: for row in qmodel: id = db.entry_get(row[0], rhythmdb.PROP_LOCATION) if id_now == id: break position += 1 log.debug("position: %i" % position) return position remuco-source-0.9.6/adapter/songbird/remuco-songbird0000755000000000000000000000633211700415064022532 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter for Songbird, implemented as an executable script.""" import dbus from dbus.exceptions import DBusException import gobject import urllib import remuco from remuco import log # ============================================================================= # player adapter # ============================================================================= class SongbirdAdapter(remuco.MPRISAdapter): def __init__(self): remuco.MPRISAdapter.__init__(self, "songbird", "Songbird") # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): # Getting the playlist from Songbird is very slow. Further there are no # playlist actions possible right now -> don't send the playlist. reply.ids = ["X"] reply.names = ["Not yet available, maybe in a later version of the Songbird adapter"] reply.send() # no playlist actions right now, # ========================================================================= # internal methods (overridden to fix MPRIS issues) # ========================================================================= def _notify_track(self, track): # The Songbird MPRIS extension does not provide real URLs in the # meta data's location entry. Until this is fixed, quote the location # here. if track and "location" in track: loc = track["location"] try: loc = loc.encode("UTF8") except UnicodeDecodeError: pass # not a unicode string loc = urllib.quote(loc, ":/%") # '%' prevents double quoting track["location"] = loc remuco.MPRISAdapter._notify_track(self, track) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = SongbirdAdapter() mg = remuco.Manager(pa, dbus_name="org.mpris.songbird") mg.run() remuco-source-0.9.6/adapter/totem/remotem.py0000644000000000000000000002611011700415064021044 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Totem player adapter for Remuco, implemented as a Totem plugin.""" import mimetypes import os import os.path import subprocess import gobject import totem import remuco from remuco import log # ============================================================================= # totem plugin interface # ============================================================================= class RemucoPlugin(totem.Plugin): def __init__(self): totem.Plugin.__init__(self) self.__ta = None def activate(self, totem): if self.__ta is not None: return print("create TotemAdapter") self.__ta = TotemAdapter() print("TotemAdapter created") print("start TotemboxAdapter") self.__ta.start(totem) print("TotemAdapter started") def deactivate(self, totem): if self.__ta is None: return print("stop TotemboxAdapter") self.__ta.stop() print("TotemAdapter stopped") self.__ta = None # ============================================================================= # supported file actions # ============================================================================= FA_SETPL = remuco.ItemAction("Set as playlist", multiple=True) FA_ENQUEUE = remuco.ItemAction("Enqueue", multiple=True) FILE_ACTIONS=(FA_ENQUEUE, FA_SETPL) # ============================================================================= # totem player adapter # ============================================================================= class TotemAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "Totem", mime_types=remuco.MIMETYPES_AV, volume_known=True, playback_known=True, progress_known=True, file_actions=FILE_ACTIONS) self.__to = None self.__signal_ids = () self.__update_item = False self.__md_album = None self.__md_artist = None self.__md_title = None self.__last_mrl = None self.__seek_step_initial = 5000 self.__seek_step = self.__seek_step_initial self.__css_sid = 0 if not mimetypes.inited: mimetypes.init() # ------------------------------------------------------------------------- # player adapter interface # ------------------------------------------------------------------------- def start(self, totem): remuco.PlayerAdapter.start(self) self.__to = totem self.__vw = totem.get_video_widget() self.__signal_ids = ( self.__to.connect("file-opened", self.__notify_file_opened), self.__to.connect("file-closed", self.__notify_file_closed), self.__to.connect("metadata-updated", self.__notify_metadata_updated) ) self.__css_sid = 0 def stop(self): remuco.PlayerAdapter.stop(self) for sid in self.__signal_ids: self.__to.disconnect(sid) self.__signal_ids = () self.__to = None self.__vw = None def poll(self): self.__poll_item() self.__poll_state() self.__poll_progress() # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): self.__to.action_play_pause() gobject.idle_add(self.__poll_state) def ctrl_next(self): self.__to.action_next() def ctrl_previous(self): self.__to.action_previous() def ctrl_seek(self, direction): if not self.__to.is_seekable() or self.__seek_step == 0: return progress = self.__to.get_current_time() try: self.__to.action_seek_relative(self.__seek_step * direction) # Before accurate except TypeError: self.__to.action_seek_relative(self.__seek_step * direction, False) # After accurate gobject.idle_add(self.__poll_progress) if direction < 0 and progress < self.__seek_step: return # no seek check if self.__css_sid == 0: # in 1.5 seconds, at least 3 x initial seek step should be elapsed: self.__css_sid = gobject.timeout_add(1500, self.__check_seek_step, progress, self.__seek_step_initial * 3, self.__seek_step + 5000) def ctrl_volume(self, direction): # FIXME: action_volume_relative() in 2.24 says it needs an int but it # behaves as if it gets a float. Internally volume is set via # the video widget, so we do it the same way here: if direction == 0: volume = 0 else: volume = self.__get_volume() + (direction * 5) volume = min(volume, 100) volume = max(volume, 0) self.__vw.set_property("volume", volume / 100.0) gobject.idle_add(self.__poll_state) def ctrl_toggle_fullscreen(self): self.__to.action_fullscreen_toggle() # ========================================================================= # actions interface # ========================================================================= def action_files(self, action_id, files, uris): if action_id == FA_ENQUEUE.id: subprocess.Popen(["totem", "--enqueue"] + uris) elif action_id == FA_SETPL.id: subprocess.Popen(["totem", "--replace"] + uris) else: log.error("** BUG ** unexpected action ID") # ========================================================================= # internal methods # ========================================================================= def __get_title_from_window(self): # FIXME: In C plugins there is a function totem_get_short_title(). I # could not find something similar in the Python bindings that # works for all types of media played in Totem. # Here we grab the window title as a work around. title = self.__to.get_main_window().get_title() type, enc = mimetypes.guess_type(title) if type: # looks like a file name title = os.path.splitext(title)[0] return title def __check_seek_step(self, progress_before, exp_min_diff, new_step): """Check if a seek had some effect and adjust seek step if not. @param progress_before: playback progress before seeking @param new_step: new seek step to set if progress did not change significantly """ progress_now = self.__to.get_current_time() log.debug("seek diff: %d" % abs(progress_now - progress_before)) if abs(progress_now - progress_before) < exp_min_diff: log.debug("adjust seek step to %d" % new_step) self.__seek_step = new_step self.__css_sid = 0 def __poll_item(self): try: mrl = self.__to.get_current_mrl() except AttributeError: # totem < 2.24 mrl = self.__to.get_main_window().get_title() # <- fake mrl if not self.__update_item and mrl == self.__last_mrl: return # reset seek step len = self.__to.get_property("stream-length") if len < 10000: self.__seek_step_initial = 0 else: self.__seek_step_initial = max(5000, len // 200) self.__seek_step = self.__seek_step_initial log.debug("reset seek step to %d" % self.__seek_step) # update meta information log.debug("update item") self.__update_item = False self.__last_mrl = mrl info = {} if ((self.__md_artist, self.__md_title, self.__md_album) == (None, None, None)): info[remuco.INFO_TITLE] = self.__get_title_from_window() else: info[remuco.INFO_ARTIST] = self.__md_artist info[remuco.INFO_TITLE] = self.__md_title info[remuco.INFO_ALBUM] = self.__md_album info[remuco.INFO_LENGTH] = int(len / 1000) img = self.find_image(mrl) self.update_item(mrl, info, img) def __poll_state(self): if self.__to.is_playing(): playback = remuco.PLAYBACK_PLAY else: playback = remuco.PLAYBACK_PAUSE self.update_playback(playback) self.update_volume(self.__get_volume()) def __poll_progress(self): progress = self.__to.get_current_time() / 1000 length = self.__to.get_property("stream-length") / 1000 self.update_progress(progress, length) def __get_volume(self): return int(self.__vw.get_property("volume") * 100) def __notify_metadata_updated(self, totem, artist, title, album, track=0): # 'track' has been added in Totem 2.26 log.debug("metadata updated: %s, %s, %s" % (artist, title, album)) # in Totem < 2.26 meta data is always None self.__md_artist = artist self.__md_title = title self.__md_album = album self.__update_item = True def __notify_file_opened(self, totem, file): # XXX: does not get called for podcasts from BBC plugin log.debug("file opened: %s" % file) self.__update_item = True def __notify_file_closed(self, totem): log.debug("file closed") self.__update_item = True remuco-source-0.9.6/adapter/totem/remuco.totem-plugin0000644000000000000000000000031611700415064022662 0ustar rootroot00000000000000[Totem Plugin] Loader=python Module=remotem IAge=1 Name=Remuco Description=Remuco Totem Adapter Authors=Remuco team Copyright=Copyright © 2006-2010 by the Remuco team Website=http://remuco.googlecode.com/ remuco-source-0.9.6/adapter/tvtime/remuco-tvtime0000755000000000000000000001352511700415064021736 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """TVtime adapter for Remuco, implemented as an executable script.""" import commands import os import os.path from xml.dom import minidom import remuco from remuco import log # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") PLAYLIST_ACTIONS = (IA_JUMP,) # ============================================================================= # MPD player adapter # ============================================================================= class TVtimeAdapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "TVtime", poll=10, playback_known=True) stations_file = os.path.join(os.getenv("HOME", "/"), ".tvtime", "stationlist.xml") if not os.path.exists(stations_file): log.warning("station list file %s does not exist" % stations_file) self.__stations_file = None else: self.__stations_file = stations_file def start(self): remuco.PlayerAdapter.start(self) self.update_item("XYZ", {remuco.INFO_TITLE: "TVtime"}, None) def stop(self): remuco.PlayerAdapter.stop(self) log.debug("bye, turning off the light") def poll(self): status, output = commands.getstatusoutput("tvtime-command NOOP") if status == os.EX_OK: self.update_playback(remuco.PLAYBACK_PLAY) else: self.update_playback(remuco.PLAYBACK_STOP) # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): self.__tvcmd("MENU_ENTER") def ctrl_next(self): self.__tvcmd("RIGHT") def ctrl_previous(self): self.__tvcmd("LEFT") def ctrl_volume(self, volume): if volume == 0: self.__tvcmd("TOGGLE_MUTE") elif volume < 0: self.__tvcmd("DOWN") else: self.__tvcmd("UP") def ctrl_toggle_repeat(self): self.__tvcmd("SHOW_MENU") def ctrl_toggle_shuffle(self): self.__tvcmd("SHOW_MENU") def ctrl_toggle_fullscreen(self): self.__tvcmd("TOGGLE_FULLSCREEN") # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): if not self.__stations_file: reply.send() return xdoc = minidom.parse(self.__stations_file) node = xdoc.getElementsByTagName("stationlist")[0] node = node.getElementsByTagName("list")[0] station_nodes = node.getElementsByTagName("station") for node in station_nodes: active = node.getAttribute("active") if active == "0": continue reply.ids.append(node.getAttribute("position")) reply.names.append(node.getAttribute("name")) reply.item_actions = PLAYLIST_ACTIONS reply.send() # ========================================================================= # action interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: channel = ids[0] cmd = "" for number in channel: cmd += "CHANNEL_%s " % number cmd += "ENTER" self.__tvcmd(cmd) else: log.error("** BUG ** unexpected playlist item action") # ========================================================================= # internal methods # ========================================================================= def __tvcmd(self, cmd): retval, output = commands.getstatusoutput("tvtime-command %s" % cmd) if retval != os.EX_OK: log.warning("command '%s' failed: %s" % (cmd, output)) # ============================================================================= # main # ============================================================================= def run_check(): """Check if TVTime is running.""" return commands.getstatusoutput("tvtime-command NOOP")[0] == 0 if __name__ == '__main__': pa = TVtimeAdapter() mg = remuco.Manager(pa, poll_fn=run_check) mg.run() remuco-source-0.9.6/adapter/vlc/remuco-vlc0000755000000000000000000000627311700415064020470 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter for VLC, implemented as an executable script.""" import os.path import gobject import remuco from remuco import log # ============================================================================= # player adapter # ============================================================================= class VLCAdapter(remuco.MPRISAdapter): def __init__(self): remuco.MPRISAdapter.__init__(self, "vlc", "VLC", mime_types=remuco.MIMETYPES_AV) self.__retry_track_active = False def start(self): self.__retry_track_active = False remuco.MPRISAdapter.start(self) def _notify_track(self, track={}): # vlc passes no argument after startup -> make argument a keyword # vlc may need some extra time to get length of a track if (not "length" in track and not "mtime" in track and not self.__retry_track_active): self.__retry_track_active = True gobject.timeout_add(500, self.__retry_track) return self.__retry_track_active = False # vlc provides length in 'length', not in 'time' or 'mtime' if "length" in track and not "mtime" in track: track["mtime"] = track["length"] # vlc may provide title in 'nowplaying' if "nowplaying" in track and not "title" in track: track["title"] = track["nowplaying"] remuco.MPRISAdapter._notify_track(self, track) def __retry_track(self): log.debug("retry to get track data") try: self._mp_p.GetMetadata(reply_handler=self._notify_track, error_handler=self._dbus_error) except DBusException, e: # this is not necessarily a fatal error log.warning("dbus error: %s" % e) # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = VLCAdapter() mg = remuco.Manager(pa, dbus_name="org.mpris.vlc") mg.run() remuco-source-0.9.6/adapter/xmms2/install-check.py0000644000000000000000000000060311700415064022032 0ustar rootroot00000000000000import sys try: import xmmsclient except ImportError, e: print("") print("+-----------------------------------------------------------------+") print("| Unsatisfied Python requirement: %s." % e) print("| Please install the missing module and then retry.") print("+-----------------------------------------------------------------+") print("") sys.exit(1)remuco-source-0.9.6/adapter/xmms2/remuco-xmms20000755000000000000000000006543711700415064021243 0ustar rootroot00000000000000#!/usr/bin/python # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """XMMS2 adapter for Remuco, implemented as an XMMS2 startup script.""" import os import gobject import xmmsclient try: from xmmsclient import XMMSValue as X2RV # XMMS2 >= 0.6 except ImportError: from xmmsclient import XMMSResult as X2RV # XMMS2 < 0.6 import xmmsclient.glib import xmmsclient.collections as xc import remuco from remuco import log # ============================================================================= # XMMS2 related constants # ============================================================================= MINFO_KEYS_ART = ("picture_front", "album_front_large", "album_front_small", "album_front_thumbnail") MINFO_KEY_TAGS = "tag" MINFO_KEY_RATING = "rating" BIN_DATA_DIR = "%s/bindata" % xmmsclient.userconfdir_get() ERROR_DISCONNECTED = "disconnected" PLAYLIST_ID_ACTIVE = "_active" SEARCH_MASK = ["Artist", "Title", "Album", "Genre"] VARIOUS_ARTISTS = "Various Artists" BLANK_ARTIST = "[unknown]" BLANK_TITLE = "[untitled]" # ============================================================================= # actions # ============================================================================= IA_JUMP = remuco.ItemAction("Jump to") IA_REMOVE = remuco.ItemAction("Remove", multiple=True) PLAYLIST_ITEM_ACTIONS = (IA_JUMP, IA_REMOVE) LA_LOAD = remuco.ListAction("Load") MLIB_LIST_ACTIONS = (LA_LOAD,) IA_APPEND = remuco.ItemAction("Enqueue", multiple=True) IA_PLAY_NEXT = remuco.ItemAction("Play next", multiple=True) MLIB_ITEM_ACTIONS = (IA_APPEND, IA_PLAY_NEXT) # ============================================================================= # helper classes # ============================================================================= class ItemListRequest(): def __init__(self, reply, pa, path, search=False): """Create a new item list request. @param reply: the request's ListReply object @param pa: XMMS2Adapter @param path: path of the requested item list @keyword search: if True then path is a search query """ self.__reply = reply self.__pa = pa self.__path = path self.__pl_ids = [] self.__pl_tracks = [] x2 = self.__pa._x2 roots = [ 'Playlists', 'Collections', 'Albums', 'Artists', 'Tracks' ] if search: self.__reply.item_actions = MLIB_ITEM_ACTIONS match = None for field, value in zip(SEARCH_MASK, path): value = value.strip() if not value: continue value = "*%s*" % value field = field.lower() match = xc.Match(match, field=field, value=value) if match is None: reply.send() else: x2.coll_query_infos(match, ['artist', 'title', 'id'], cb=self.__bil_list_of_tracks) elif not path: self.__reply.nested = roots self.__reply.send() elif path[0] not in roots: log.error("** BUG ** unexpected path: %s" % path) elif len(path) == 1: if path[0] == "Playlists": self.__reply.list_actions = MLIB_LIST_ACTIONS x2.coll_list(path[0], cb=self.__bil_list_of_colls) if path[0] == "Collections": x2.coll_list(path[0], cb=self.__bil_list_of_colls) elif path[0] == "Albums": match = xc.Has(xc.Universe(), 'album') x2.coll_query_infos(match, ['album', 'artist', 'compilation'], groupby=['album', 'artist'], cb=self.__bil_list_of_albums) elif path[0] == 'Artists': artists = xc.Has(xc.Universe(), 'artist') match = xc.Intersection(xc.Complement(xc.Has(xc.Universe(), 'compilation')), artists) match = xc.Union(match, xc.Match(artists, field='compilation', value='0')) x2.coll_query_infos(match, ['artist'], groupby=['artist'], cb=self.__bil_list_of_artists) elif path[0] == 'Tracks': match = xc.Has(xc.Universe(), 'title') x2.coll_query_infos(match, ['title', 'artist', 'id'], groupby=['title', 'artist'], cb=self.__bil_list_of_tracks) elif len(path) == 2: if path[0] == 'Playlists': if path[1] == PLAYLIST_ID_ACTIVE: self.__reply.item_actions = PLAYLIST_ITEM_ACTIONS else: self.__reply.item_actions = MLIB_ITEM_ACTIONS x2.playlist_list_entries(playlist=path[1], cb=self.__handle_pl_ids) elif path[0] == 'Collections': self.__reply.item_actions = MLIB_ITEM_ACTIONS x2.coll_get(path[1], ns="Collections", cb=self.__handle_collection) elif path[0] == 'Albums': self.__reply.item_actions = MLIB_ITEM_ACTIONS album, artist = path[1].split("\n") if artist == BLANK_ARTIST: artist = "" elif artist == VARIOUS_ARTISTS: artist = None match = xc.Match(xc.Universe(), field='album', value=album) if artist is not None: match = xc.Match(match, field='artist', value=artist) x2.coll_query_infos(match, ['title', 'artist', 'id', 'compilation', 'tracknr'], order=['tracknr'], cb=self.__bil_items_in_album) elif path[0] == 'Artists': self.__reply.item_actions = MLIB_ITEM_ACTIONS match = xc.Match(xc.Universe(), field='artist', value=path[1]) x2.coll_query_infos(match, ['title', 'album', 'id', 'compilation'], cb=self.__bil_items_and_albums_of_artist) elif len(path) == 3: if path[0] == 'Artists': self.__reply.item_actions = MLIB_ITEM_ACTIONS match = xc.Match(xc.Universe(), field='artist', value=path[1]) match = xc.Match(match, field='album', value=path[2]) x2.coll_query_infos(match, ['title', 'id', 'tracknr'], order=['tracknr'], cb=self.__bil_items_in_album) else: log.error("** BUG ** unexpected path: %s" % path) def __handle_pl_ids(self, result): """Collects track infos for the tracks in the playlist ID list.""" if not self.__pa._check_result(result): return self.__pl_ids = result.value() log.debug("playlist ids: %s" % self.__pl_ids) self.__request_next_pl_track() def __request_next_pl_track(self): """Requests track info for the next track in the playlist ID list.""" if len(self.__pl_tracks) < len(self.__pl_ids): # proceed in getting item names id = self.__pl_ids[len(self.__pl_tracks)] self.__pa._x2.medialib_get_info(id, cb=self.__handle_pl_track) else: # have all item names self.__bil_list_of_tracks(self.__pl_tracks) def __handle_pl_track(self, result): """Adds a track to the playlist track list and requests the next.""" if not self.__pa._check_result(result): return self.__pl_tracks.append(result.value()) self.__request_next_pl_track() def __handle_collection(self, result): """Requests a track info list for a collection.""" if not self.__pa._check_result(result): return coll = result.value() self.__pa._x2.coll_query_infos(coll, ['title', 'artist', 'id'], cb=self.__bil_list_of_tracks) def __bil_list_of_colls(self, result): """Builds an item list with all collections of a specific namespace.""" if not self.__pa._check_result(result): return colls = result.value() self.__reply.nested = [ i for i in colls if not i.startswith("_") ] self.__reply.send() def __bil_list_of_tracks(self, result): """Builds an item list of a non-specific list of tracks.""" if isinstance(result, X2RV): if not self.__pa._check_result(result): return tracks = result.value() else: tracks = result for minfo in tracks: self.__reply.ids.append(minfo['id']) self.__reply.names.append(self.__get_item_name(minfo)) self.__reply.send() def __bil_list_of_albums(self, result): """Builds an item list of all albums.""" if not self.__pa._check_result(result): return albums = set() for x in result.value(): if not x['album']: continue elif x['compilation']: albums.add("%s\n%s" % (x['album'], VARIOUS_ARTISTS)) else: albums.add("%s\n%s" % (x['album'], x['artist'] or BLANK_ARTIST)) self.__reply.nested = sorted(albums) self.__reply.send() def __bil_list_of_artists(self, result): """Builds an item list of all artists.""" if not self.__pa._check_result(result): return self.__reply.nested = map(lambda x: x['artist'], result.value()) self.__reply.send() def __bil_items_in_album(self, result): """Builds an item list for a specific album.""" if not self.__pa._check_result(result): return for minfo in result.value(): number = minfo.get('tracknr', 0) and "%s. " % minfo['tracknr'] or "" track = "%s%s" % (number, minfo.get('title', BLANK_TITLE)) if minfo.get('compilation', False): track += " / %s" % minfo.get('artist', BLANK_ARTIST) self.__reply.names.append(track) self.__reply.ids.append(minfo['id']) self.__reply.send() def __bil_items_and_albums_of_artist(self, result): """Builds an item list for a specific artist.""" if not self.__pa._check_result(result): return albums = set() for minfo in result.value(): if not minfo.get('album') or minfo.get('compilation'): name = minfo.get('title', BLANK_TITLE) if minfo.get('album'): name += " / %s" % minfo['album'] self.__reply.names.append(name) self.__reply.ids.append(minfo['id']) else: albums.add(minfo['album']) self.__reply.nested = sorted(albums) self.__reply.send() def __get_item_name(self, minfo, need=None): """Get a standard item name. @param minfo: track info dict @keyword need: list of required tags (artist, title) @return: a name composed of artist and title or None if one the tags in 'need' is None or the empty string """ if need and 'title' in need and not minfo.get('title'): return None if need and 'artist' in need and not minfo.get('artist'): return None artist = minfo.get('artist', BLANK_ARTIST) title = minfo.get('title', BLANK_TITLE) return "%s / %s" % (title, artist) # ============================================================================= # player adapter # ============================================================================= class XMMS2Adapter(remuco.PlayerAdapter): def __init__(self): remuco.PlayerAdapter.__init__(self, "XMMS2", max_rating=5, shuffle_known=True, playback_known=True, volume_known=True, progress_known=True, search_mask=SEARCH_MASK) self.__state_playback = remuco.PLAYBACK_STOP self.__state_volume = 0 self.__state_position = 0 self.__item_id_int = None # id as integer self.__item_id = None # id as string self.__item_meta = None self.__item_len = 0 # for update_progress() self.__shuffle_off_sid = 0 self._x2 = xmmsclient.XMMS("remuco") self.__x2_glib_connector = None def start(self): remuco.PlayerAdapter.start(self) try: self._x2.connect(path=os.getenv("XMMS_PATH"), disconnect_func=self.__notify_disconnect) except IOError, e: raise StandardError("failed to connect to XMMS2: %s" % e) self.__x2_glib_connector = xmmsclient.glib.GLibConnector(self._x2) self._x2.broadcast_playback_current_id(self.__notify_id) self._x2.broadcast_playback_status(self.__notify_playback) self._x2.broadcast_playback_volume_changed(self.__notify_volume) self._x2.broadcast_playlist_current_pos(self.__notify_position) # to dectect all posistion changes: self._x2.broadcast_playlist_changed(self.__notify_playlist_change) self._x2.signal_playback_playtime(self.__notify_progress) # get initial player state (broadcasts only work on changes): self._x2.playback_current_id(cb=self.__notify_id) self._x2.playback_status(cb=self.__notify_playback) self._x2.playback_volume_get(cb=self.__notify_volume) self._x2.playlist_current_pos(cb=self.__notify_position) self.__item_len = 0 def stop(self): remuco.PlayerAdapter.stop(self) if self.__shuffle_off_sid > 0: gobject.source_remove(self.__shuffle_off_sid) self.__shuffle_off_sid = 0 self._x2 = None self.__x2_glib_connector = None def poll(self): self._x2.playback_playtime(cb=self.__notify_progress) # ========================================================================= # control interface # ========================================================================= def ctrl_next(self): self._x2.playlist_set_next_rel(1, cb=self.__ignore_result) self._x2.playback_tickle(cb=self.__ignore_result) def ctrl_previous(self): if self.__state_position > 0: self._x2.playlist_set_next_rel(-1, cb=self.__ignore_result) self._x2.playback_tickle(cb=self.__ignore_result) def ctrl_toggle_playing(self): if (self.__state_playback == remuco.PLAYBACK_STOP or self.__state_playback == remuco.PLAYBACK_PAUSE): self._x2.playback_start(cb=self.__ignore_result) else: self._x2.playback_pause(cb=self.__ignore_result) def ctrl_toggle_shuffle(self): self._x2.playlist_shuffle(cb=self.__ignore_result) self.update_shuffle(True) # emulate shuffle mode: show shuffle state for a second if self.__shuffle_off_sid > 0: gobject.source_remove(self.__shuffle_off_sid) self.__shuffle_off_sid = gobject.timeout_add(1000, self.__shuffle_off) def ctrl_seek(self, direction): self._x2.playback_seek_ms_rel(direction * 5000, cb=self.__ignore_result) self.poll() def ctrl_volume(self, direction): # TODO: currently this fails, problem relates to xmms2 installation if direction == 0: volume = 0 else: volume = self.__state_volume + 5 * direction volume = min(volume, 100) volume = max(volume, 0) for chan in ("right", "left"): self._x2.playback_volume_set(chan, volume, cb=self.__ignore_result) def ctrl_rate(self, rating): if self.__item_id_int == 0: return self._x2.medialib_property_set(self.__item_id_int, MINFO_KEY_RATING, rating, cb=self.__ignore_result) def ctrl_tag(self, id, tags): try: id_int = int(id) except ValueError: log.error("** BUG ** id is not an int") return s = "" for tag in tags: s = "%s,%s" % (s, tag) self._x2.medialib_property_set(id_int, MINFO_KEY_TAGS, s, cb=self.__ignore_result) # ========================================================================= # actions interface # ========================================================================= def action_playlist_item(self, action_id, positions, ids): if action_id == IA_JUMP.id: self._x2.playlist_set_next(positions[0], cb=self.__ignore_result) self._x2.playback_tickle(cb=self.__ignore_result) if self.__state_playback != remuco.PLAYBACK_PLAY: self._x2.playback_start(cb=self.__ignore_result) elif action_id == IA_REMOVE.id: positions.sort() positions.reverse() for pos in positions: log.debug("remove %d from playlist" % pos) self._x2.playlist_remove_entry(pos, cb=self.__ignore_result) else: log.error("** BUG ** unexpected playlist item action") def action_mlib_item(self, action_id, path, positions, ids): if action_id == IA_APPEND.id: for id in ids: id = int(id) self._x2.playlist_add_id(id, cb=self.__ignore_result) elif action_id == IA_PLAY_NEXT.id: pos = self.__state_position + 1 ids.reverse() for id in ids: id = int(id) self._x2.playlist_insert_id(pos, id, cb=self.__ignore_result) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_mlib_list(self, action_id, path): if action_id == LA_LOAD.id: if len(path) == 2 and path[0] == "Playlists": self._x2.playlist_load(path[1], cb=self.__ignore_result) self._x2.playlist_set_next(0, cb=self.__ignore_result) self._x2.playback_tickle(cb=self.__ignore_result) if self.__state_playback != remuco.PLAYBACK_PLAY: self._x2.playback_start(cb=self.__ignore_result) else: log.error("** BUG ** unexpected path: %s" % path) else: log.error("** BUG ** unexpected action: %d" % action_id) def action_search_item(self, action_id, positions, ids): self.action_mlib_item(action_id, None, positions, ids) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): ItemListRequest(reply, self, ['Playlists', PLAYLIST_ID_ACTIVE]) def request_mlib(self, reply, path): ItemListRequest(reply, self, path) def request_search(self, reply, query): ItemListRequest(reply, self, query, search=True) # ========================================================================= # internal methods # ========================================================================= def _check_result(self, result): """ Check the result of a request sent to XMMS2. """ try: ie = result.is_error() # XMMS2 >= 0.6 except AttributeError: ie = result.iserror() # XMMS2 < 0.6 if not ie: return True err = result.get_error() if err.lower() == ERROR_DISCONNECTED: log.warning("lost connection to XMMS2") self.manager.stop() else: log.warning("error result: %s" % err) return False def __notify_id(self, result): if not self._check_result(result): self.update_item(None, None, None) return self.__item_id_int = result.value() self.__item_id = str(self.__item_id_int) log.debug("new item id: %u" % self.__item_id_int) if self.__item_id_int == 0: self.update_item(None, None, None) return self._x2.medialib_get_info(self.__item_id_int, cb=self.__handle_info) def __handle_info(self, result): """Callback to handle meta data requested for the current item.""" if not self._check_result(result): self.__item_id_int = 0 self.__item_id = str(self.__item_id_int) self.update_item(None, None, None) return minfo = result.value() info = {} info[remuco.INFO_ARTIST] = minfo.get('artist', "") info[remuco.INFO_ALBUM] = minfo.get('album', "") info[remuco.INFO_TITLE] = minfo.get('title', "") info[remuco.INFO_GENRE] = minfo.get('genre', "") info[remuco.INFO_YEAR] = minfo.get('year', "") info[remuco.INFO_BITRATE] = int(minfo.get('bitrate', 0) / 1000) info[remuco.INFO_RATING] = minfo.get(MINFO_KEY_RATING, 0) info[remuco.INFO_TAGS] = minfo.get(MINFO_KEY_TAGS, "") self.__item_len = int(minfo.get('duration', 0) // 1000) info[remuco.INFO_LENGTH] = self.__item_len img = None for img_key in MINFO_KEYS_ART: img = minfo.get(img_key) if img: img = "%s/%s" % (BIN_DATA_DIR, img) break if not img: url = minfo.get('url').replace("+", "%20") img = self.find_image(url) self.update_item(self.__item_id, info, img) self.poll() # update progress def __notify_playback(self, result): if not self._check_result(result): return val = result.value() if val == xmmsclient.PLAYBACK_STATUS_PAUSE: self.__state_playback = remuco.PLAYBACK_PAUSE elif val == xmmsclient.PLAYBACK_STATUS_PLAY: self.__state_playback = remuco.PLAYBACK_PLAY elif val == xmmsclient.PLAYBACK_STATUS_STOP: self.__state_playback = remuco.PLAYBACK_STOP else: log.error("** BUG ** unknown XMMS2 playback status: %d", val) return self.update_playback(self.__state_playback) def __notify_progress(self, result): if not self._check_result(result): return progress = int(result.value() // 1000) progress = min(progress, self.__item_len) progress = max(progress, 0) self.update_progress(progress, self.__item_len) def __notify_volume(self, result): if not self._check_result(result): return val = result.value() volume = 0 i = 0 for v in val.values(): volume += v i += 1 volume = volume / i self.__state_volume = volume self.update_volume(self.__state_volume) def __notify_position(self, result): if not self._check_result(result): return self.__state_position = result.value()['position'] self.update_position(self.__state_position) def __notify_playlist_change(self, result): if not self._check_result(result): return # change in playlist may result in position change: self._x2.playlist_current_pos(cb=self.__notify_position) def __notify_disconnect(self, result): log.info("xmms2 disconnected") self.manager.stop() def __ignore_result(self, result): """Handle an XMMS2 result which is not of interest.""" self._check_result(result) def __shuffle_off(self): """Timeout callback to disable the pseudo shuffle.""" self.update_shuffle(False) self.__shuffle_off_sid = 0 # ============================================================================= # main # ============================================================================= if __name__ == '__main__': pa = XMMS2Adapter() mg = remuco.Manager(pa) mg.run() remuco-source-0.9.6/base/module/install-check.py0000644000000000000000000000102711700415064021544 0ustar rootroot00000000000000import sys try: import gobject if sys.platform.startswith("linux"): import xdg.BaseDirectory import dbus import Image import logging import bluetooth except ImportError, e: print("") print("+-----------------------------------------------------------------+") print("| Unsatisfied Python requirement: %s." % e) print("| Please install the missing module and then retry.") print("+-----------------------------------------------------------------+") print("") sys.exit(1)remuco-source-0.9.6/base/module/remuco/__init__.py0000644000000000000000000000704711700415064022064 0ustar rootroot00000000000000# -*- coding: UTF-8 -*- # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco player adapter module. The module 'remuco' provides classes and constants for Remuco player adapters. Class PlayerAdapter: Base class for player adapters (start reading here). Class MPRISAdapter: Base class for player adapters for MPRIS players. Classes ItemAction and ListAction: Classes to define actions clients may execute in their media browser. Class ListReply: Used by player adapters to reply requests for playlists and other lists. Class Manager: Helper class for managing the life cycle of a player adapter. Constants: The constants starting with 'INFO' are keys to be used for the dictionary describing an item (a playable object: song, video, slide, picture, ...). The constants starting with 'PLAYBACK' are the values used by Remuco to describe a playback state. Logging: It is recommended to use the remuco logging system within player adapters. To do so, import the module 'remuco.log' and use the functions * remuco.log.debug(), * remuco.log.info(), * remuco.log.warning() and * remuco.log.error(). Then all messages of the player adapter will be written into the same file as used internally by the remuco module - that makes debugging a lot easier. Internally Remuco uses the module 'logging' for all its logging messages. Messages go into a player specific log file (usually ~/.cache/remuco/PLAYER/log). The log level is defined in a player specific configuration file (usually ~/.config/remuco/PLAYER/conf). """ #============================================================================== # imports #============================================================================== from remuco.adapter import PlayerAdapter, ItemAction, ListAction, ListReply from remuco.adapter import MIMETYPES_AUDIO, MIMETYPES_VIDEO, MIMETYPES_AV from remuco.config import Config from remuco.defs import * from remuco.manager import Manager from remuco.mpris import MPRISAdapter #============================================================================== # exports #============================================================================== __all__ = ["PlayerAdapter", "ListReply", "MPRISAdapter", "ItemAction", "ListAction", "Manager", "Config", "INFO_ALBUM", "INFO_ARTIST", "INFO_GENRE", "INFO_LENGTH", "INFO_RATING", "INFO_TAGS", "INFO_TITLE", "INFO_YEAR", "PLAYBACK_PAUSE", "PLAYBACK_PLAY", "PLAYBACK_STOP", "MIMETYPES_AUDIO", "MIMETYPES_VIDEO", "MIMETYPES_AV", ] __version__ = REMUCO_VERSION remuco-source-0.9.6/base/module/remuco/adapter.py0000644000000000000000000014544511700415064021752 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import commands import inspect import math # for ceiling import os import os.path import urllib import urlparse import gobject from remuco import art from remuco import config from remuco import files from remuco import log from remuco import message from remuco import net from remuco import serial from remuco.defs import * from remuco.features import * from remuco.data import PlayerInfo, PlayerState, Progress, ItemList, Item from remuco.data import Control, Action, Tagging, Request from remuco.manager import NoManager # ============================================================================= # reply class for requests # ============================================================================= class ListReply(object): """Reply object for an item list request. A ListReply is the first parameter of the request methods PlayerAdapter.request_playlist(), PlayerAdapter.request_queue(), PlayerAdapter.request_mlib() and PlayerAdapter.request_search(). Player adapters are supposed to use the list reply object to set the reply data (using properties 'ids', 'names', 'item_actions' and 'nested', 'list_actions') and to send the reply to clients (using send()). """ def __init__(self, client, request_id, reply_msg_id, page, path=None): """Create a new list reply. Used internally, not needed within player adapters. @param client: the client to send the reply to @param request_id: the request's ID @param reply_msg_id: the message ID of the client's request @param page: page of the requested list @keyword path: path of the requested list, if there is one """ self.__client = client self.__request_id = request_id self.__reply_msg_id = reply_msg_id self.__page = page self.__path = path self.__nested = [] self.__ids = [] self.__names = [] self.__list_actions = [] self.__item_actions = [] def send(self): """Send the requested item list to the requesting client.""" ### paging ### page_size = self.__client.info.page_size len_all = len(self.__ids or []) + len(self.__nested or []) # P3K: remove float() and int() page_max = int(max(math.ceil(float(len_all) / page_size) - 1, 0)) # number of pages may have changed since client sent the request self.__page = min(self.__page, page_max) index_start = self.__page * page_size index_end = index_start + page_size nested, ids, names = [], [], [] item_offset = 0 if self.__nested and index_start < len(self.__nested): # page contains nested lists and maybe items nested = self.__nested[index_start:index_end] if len(nested) < page_size: # page contains nested lists and items num_items = page_size - len(nested) ids = self.__ids[0:num_items] names = self.__names[0:num_items] else: # page contains only items index_start -= len(self.__nested) index_end -= len(self.__nested) ids = self.__ids[index_start:index_end] names = self.__names[index_start:index_end] item_offset = index_start ### sending ### ilist = ItemList(self.__request_id, self.__path, nested, ids, names, item_offset, self.__page, page_max, self.__item_actions, self.__list_actions) msg = net.build_message(self.__reply_msg_id, ilist) gobject.idle_add(self.__client.send, msg) # === property: ids === def __pget_ids(self): """IDs of the items contained in a list. Player adapters should set this to a list of IDs of the items contained in the requested list. """ return self.__ids def __pset_ids(self, value): self.__ids = value ids = property(__pget_ids, __pset_ids, None, __pget_ids.__doc__) # === property: names === def __pget_names(self): """Names of the items contained in a list. Player adapters should set this to a list of names of the items contained in the requested list. Good choice for a name is combination of artist and title. """ return self.__names def __pset_names(self, value): self.__names = value names = property(__pget_names, __pset_names, None, __pget_names.__doc__) # === property: nested === def __pget_nested(self): """Names of nested lists contained in a list. Player adapters should set this to a list of names of the nested lists contained in the requested list. To be used only for mlib requests (see PlayerAdapter.request_mlib()). """ return self.__nested def __pset_nested(self, value): self.__nested = value nested = property(__pget_nested, __pset_nested, None, __pget_nested.__doc__) # === property: item_actions === def __pget_item_actions(self): """A list of actions clients can apply to items in the list. The list must contain ItemAction objects. """ return self.__item_actions def __pset_item_actions(self, value): self.__item_actions = value item_actions = property(__pget_item_actions, __pset_item_actions, None, __pget_item_actions.__doc__) # === property: list_actions === def __pget_list_actions(self): """A list of actions clients can apply to nested lists in the list. The list must contain ListAction objects. """ return self.__list_actions def __pset_list_actions(self, value): self.__list_actions = value list_actions = property(__pget_list_actions, __pset_list_actions, None, __pget_list_actions.__doc__) # ============================================================================= # media browser actions # ============================================================================= class ListAction(object): """List related action for a client's media browser. A list action defines an action a client may apply to a list from the player's media library. If possible, player adapters may define list actions and send them to clients via PlayerAdapter.replay_mlib_request() Clients may then use these actions which results in a call to PlayerAdapter.action_mlib_list(). @see: PlayerAdapter.action_mlib_list() """ __id_counter = 0 def __init__(self, label): """Create a new action for lists from a player's media library. @param label: label of the action (keep short, ideally this is just a single word like 'Load', ..) """ ListAction.__id_counter -= 1 self.__id = ListAction.__id_counter self.label = label def __str__(self): return "(%d, %s)" % (self.__id, self.label) # === property: id === def __pget_id(self): """ID of the action (auto-generated, read only)""" return self.__id id = property(__pget_id, None, None, __pget_id.__doc__) class ItemAction(object): """Item related action for a client's media browser. An item action defines an action a client may apply to a file from the local file system, to an item from the playlist, to an item from the play queue or to an item from the player's media library. If possible, player adapters should define item actions and send them to clients by setting the keyword 'file_actions' in PlayerAdapter.__init__(), via PlayerAdapter.reply_playlist_request(), via PlayerAdapter.reply_queue_request() or via PlayerAdapter.reply_mlib_request(). Clients may then use these actions which results in a call to PlayerAdapter.action_files(), PlayerAdapter.action_playlist_item(), PlayerAdapter.action_queue_item() or PlayerAdapter.action_mlib_item(). @see: PlayerAdapter.action_files() @see: PlayerAdapter.action_playlist() @see: PlayerAdapter.action_queue() @see: PlayerAdapter.action_mlib_item() """ __id_counter = 0 def __init__(self, label, multiple=False): """Create a new action for items or files. @param label: label of the action (keep short, ideally this is just a single word like 'Enqueue', 'Play', ..) @keyword multiple: if the action may be applied to multiple items/files or only to a single item/file """ ItemAction.__id_counter += 1 self.__id = ItemAction.__id_counter self.label = label self.multiple = multiple def __str__(self): return "(%d, %s, %s)" % (self.id, self.label, self.multiple) # === property: id === def __pget_id(self): """ID of the action (auto-generated, read only)""" return self.__id id = property(__pget_id, None, None, __pget_id.__doc__) # ============================================================================= # player adapter # ============================================================================= MIMETYPES_AUDIO = ("audio", "application/ogg") MIMETYPES_VIDEO = ("video",) MIMETYPES_AV = MIMETYPES_AUDIO + MIMETYPES_VIDEO class PlayerAdapter(object): '''Base class for Remuco player adapters. Remuco player adapters must subclass this class and override certain methods to implement player specific behavior. Additionally PlayerAdapter provides methods to interact with Remuco clients. Following is a summary of all relevant methods, grouped by functionality. =========================================================================== Methods to extend to manage life cycle =========================================================================== * start() * stop() A PlayerAdapter can be started and stopped with start() and stop(). The same instance of a PlayerAdapter should be startable and stoppable multiple times. Subclasses of PlayerAdapter may override these methods as needed but must always call the super class implementations too! =========================================================================== Methods to override to control the media player: =========================================================================== * ctrl_toggle_playing() * ctrl_toggle_repeat() * ctrl_toggle_shuffle() * ctrl_toggle_fullscreen() * ctrl_next() * ctrl_previous() * ctrl_seek() * ctrl_volume() * ctrl_rate() * ctrl_tag() * ctrl_navigate() * action_files() * action_playlist_item() * action_queue_item() * action_mlib_item() * action_mlib_list() * action_search_item() Player adapters only need to implement only a *subset* of these methods - depending on what is possible and what makes sense. Remuco checks which methods have been overridden and uses this information to notify Remuco clients about capabilities of player adapters. =========================================================================== Methods to override to provide information from the media player: =========================================================================== * request_playlist() * request_queue() * request_mlib() * request_search() As above, only override the methods which make sense for the corresponding media player. =========================================================================== Methods to call to synchronize media player state information with clients: =========================================================================== * update_playback() * update_repeat() * update_shuffle() * update_item() * update_position() * update_progress() These methods should be called whenever the corresponding information has changed in the media player (it is safe to call these methods also if there actually is no change, internally a change check is done before sending any data to clients). Subclasses of PlayerAdapter may override the method poll() to periodically check a player's state. =========================================================================== Finally some utility methods: =========================================================================== * find_image() ''' manager = NoManager() # ========================================================================= # constructor # ========================================================================= def __init__(self, name, playback_known=False, volume_known=False, repeat_known=False, shuffle_known=False, progress_known=False, max_rating=0, poll=2.5, file_actions=None, mime_types=None, search_mask=None): """Create a new player adapter and configure its capabilities. Just does some early initializations. Real job starts with start(). @param name: name of the media player @keyword playback_known: indicates if the player's playback state can be provided (see update_playback()) @keyword volume_known: indicates if the player's volume can be provided (see update_volume()) @keyword repeat_known: indicates if the player's repeat mode can be provided (see update_repeat()) @keyword shuffle_known: indicates if the player's shuffle mode can be provided (see update_shuffle()) @keyword progress_known: indicates if the player's playback progress can be provided (see update_progress()) @keyword max_rating: maximum possible rating value for items @keyword poll: interval in seconds to call poll() @keyword file_actions: list of ItemAction which can be applied to files from the local file system (actions like play a file or append files to the playlist) - this keyword is only relevant if the method action_files() gets overridden @keyword mime_types: list of mime types specifying the files to which the actions given by the keyword 'file_actions' can be applied, this may be general types like 'audio' or 'video' but also specific types like 'audio/mp3' or 'video/quicktime' (setting this to None means all mime types are supported) - this keyword is only relevant if the method action_files() gets overridden @keyword search_mask: list of fields to search the players library for (e.g. artist, genre, any, ...) - if set method request_search() should be overridden @attention: When overriding, call super class implementation first! """ self.__name = name # init config (config inits logging) self.config = config.Config(self.__name) # init misc fields serial.Bin.HOST_ENCODING = self.config.player_encoding self.__clients = [] self.__state = PlayerState() self.__progress = Progress() self.__item_id = None self.__item_info = None self.__item_img = None flags = self.__util_calc_flags(playback_known, volume_known, repeat_known, shuffle_known, progress_known) self.__info = PlayerInfo(name, flags, max_rating, file_actions, search_mask) self.__sync_triggers = {} self.__poll_ival = max(500, int(poll * 1000)) self.__poll_sid = 0 self.stopped = True self.__server_bluetooth = None self.__server_wifi = None if self.config.fb_root_dirs: self.__filelib = files.FileSystemLibrary( self.config.fb_root_dirs, mime_types, self.config.fb_show_extensions, False) else: log.info("file browser is disabled") if "REMUCO_TESTSHELL" in os.environ: from remuco import testshell testshell.setup(self) log.debug("init done") def start(self): """Start the player adapter. @attention: When overriding, call super class implementation first! """ if not self.stopped: log.debug("ignore start, already running") return self.stopped = False # set up server if self.config.bluetooth_enabled: self.__server_bluetooth = net.BluetoothServer(self.__clients, self.__info, self.__handle_message, self.config) else: self.__server_bluetooth = None if self.config.wifi_enabled: self.__server_wifi = net.WifiServer(self.__clients, self.__info, self.__handle_message, self.config) else: self.__server_wifi = None # set up polling if self.__poll_ival > 0: log.debug("poll every %d milli seconds" % self.__poll_ival) self.__poll_sid = gobject.timeout_add(self.__poll_ival, self.__poll) log.debug("start done") def stop(self): """Shutdown the player adapter. Disconnects all clients and shuts down the Bluetooth and WiFi server. Also ignores any subsequent calls to an update or reply method (e.g. update_volume(), ..., reply_playlist_request(), ...). @note: The same player adapter instance can be started again with start(). @attention: When overriding, call super class implementation first! """ if self.stopped: return self.stopped = True for c in self.__clients: c.disconnect(remove_from_list=False, send_bye_msg=True) self.__clients = [] if self.__server_bluetooth is not None: self.__server_bluetooth.down() self.__server_bluetooth = None if self.__server_wifi is not None: self.__server_wifi.down() self.__server_wifi = None for sid in self.__sync_triggers.values(): if sid is not None: gobject.source_remove(sid) self.__sync_triggers = {} if self.__poll_sid > 0: gobject.source_remove(self.__poll_sid) log.debug("stop done") def poll(self): """Does nothing by default. If player adapters override this method, it gets called periodically in the interval specified by the keyword 'poll' in __init__(). A typical use case of this method is to detect the playback progress of the current item and then call update_progress(). It can also be used to poll any other player state information when a player does not provide signals for all or certain state information changes. """ raise NotImplementedError def __poll(self): if self.config.master_volume_enabled: self.__update_volume_master() try: self.poll() except NotImplementedError: # poll again if master volume is used, otherwise not return self.config.master_volume_enabled return True # ========================================================================= # utility methods which may be useful for player adapters # ========================================================================= def find_image(self, resource): """Find a local art image file related to a resource. This method first looks in the resource' folder for typical art image files (e.g. 'cover.png', 'front.jpg', ...). If there is no such file it then looks into the user's thumbnail directory (~/.thumbnails). @param resource: resource to find an art image for (may be a file name or URI) @keyword prefer_thumbnail: True means first search in thumbnails, False means first search in the resource' folder @return: an image file name (which can be used for update_item()) or None if no image file has been found or if 'resource' is not local """ file = art.get_art(resource) log.debug("image for '%s': %s" % (resource, file)) return file # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): """Toggle play and pause. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_toggle_repeat(self): """Toggle repeat mode. @note: Override if it is possible and makes sense. @see: update_repeat() """ log.error("** BUG ** in feature handling") def ctrl_toggle_shuffle(self): """Toggle shuffle mode. @note: Override if it is possible and makes sense. @see: update_shuffle() """ log.error("** BUG ** in feature handling") def ctrl_toggle_fullscreen(self): """Toggle full screen mode. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_next(self): """Play the next item. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_previous(self): """Play the previous item. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_seek(self, direction): """Seek forward or backward some seconds. The number of seconds to seek should be reasonable for the current item's length (if known). If the progress of the current item is known, it should get synchronized immediately with clients by calling update_progress(). @param direction: * -1: seek backward * +1: seek forward @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_rate(self, rating): """Rate the currently played item. @param rating: rating value (int) @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_tag(self, id, tags): """Attach some tags to an item. @param id: ID of the item to attach the tags to @param tags: a list of tags @note: Tags does not mean ID3 tags or similar. It means the general idea of tags (e.g. like used at last.fm). @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_navigate(self, action): """Navigate through menus (typically DVD menus). @param action: A number selecting one of these actions: UP, DOWN, LEFT, RIGHT, SELECT, RETURN, TOPMENU (e.g. 0 is UP and 6 is TOPMENU). @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def ctrl_volume(self, direction): """Adjust volume. @param volume: * -1: decrease by some percent (5 is a good value) * 0: mute volume * +1: increase by some percent (5 is a good value) @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def __ctrl_volume_master(self, direction): """Adjust volume using custom volume command (instead of player).""" if direction < 0: cmd = self.config.master_volume_down_cmd elif direction > 0: cmd = self.config.master_volume_up_cmd else: cmd = self.config.master_volume_mute_cmd ret, out = commands.getstatusoutput("sh -c '%s'" % cmd) if ret != os.EX_OK: log.error("master-volume-... failed: %s" % out) else: gobject.idle_add(self.__update_volume_master) def __ctrl_shutdown_system(self): if self.config.system_shutdown_enabled: log.debug("run system shutdown command") cmd = "sh -c '%s'" % self.config.system_shutdown_cmd ret, out = commands.getstatusoutput(cmd) if ret != os.EX_OK: log.error("system-shutdown failed: %s" % out) return self.stop() # ========================================================================= # actions interface # ========================================================================= def action_files(self, action_id, files, uris): """Do an action on one or more files. The files are specified redundantly by 'files' and 'uris' - use whatever fits better. If the specified action is not applicable to multiple files, then 'files' and 'uris' are one element lists. The files in 'files' and 'uris' may be any files from the local file system that have one of the mime types specified by the keyword 'mime_types' in __init__(). @param action_id: ID of the action to do - this specifies one of the actions passed previously to __init__() by the keyword 'file_actions' @param files: list of files to apply the action to (regular path names) @param uris: list of files to apply the action to (URI notation) @note: Override if file item actions gets passed to __init__(). """ log.error("** BUG ** action_files() not implemented") def action_playlist_item(self, action_id, positions, ids): """Do an action on one or more items from the playlist. The items are specified redundantly by 'positions' and 'ids' - use whatever fits better. If the specified action is not applicable to multiple items, then 'positions' and 'ids' are one element lists. @param action_id: ID of the action to do - this specifies one of the actions passed previously to reply_playlist_request() by the keyword 'item_actions' @param positions: list of positions to apply the action to @param ids: list of IDs to apply the action to @note: Override if item actions gets passed to reply_playlist_request(). """ log.error("** BUG ** action_item() not implemented") def action_queue_item(self, action_id, positions, ids): """Do an action on one or more items from the play queue. The items are specified redundantly by 'positions' and 'ids' - use whatever fits better. If the specified action is not applicable to multiple items, then 'positions' and 'ids' are one element lists. @param action_id: ID of the action to do - this specifies one of the actions passed previously to reply_queue_request() by the keyword 'item_actions' @param positions: list of positions to apply the action to @param ids: list of IDs to apply the action to @note: Override if item actions gets passed to reply_queue_request(). """ log.error("** BUG ** action_item() not implemented") def action_mlib_item(self, action_id, path, positions, ids): """Do an action on one or more items from the player's media library. The items are specified redundantly by 'positions' and 'ids' - use whatever fits better. If the specified action is not applicable to multiple items, then 'positions' and 'ids' are one element lists. @param action_id: ID of the action to do - this specifies one of the actions passed previously to reply_mlib_request() by the keyword 'item_actions' @param path: the library path that contains the items @param positions: list of positions to apply the action to @param ids: list of IDs to apply the action to @note: Override if item actions gets passed to reply_mlib_request(). """ log.error("** BUG ** action_mlib_item() not implemented") def action_mlib_list(self, action_id, path): """Do an action on a list from the player's media library. @param action_id: ID of the action to do - this specifies one of the actions passed previously to reply_mlib_request() by the keyword 'list_actions' @param path: path specifying the list to apply the action to @note: Override if list actions gets passed to reply_mlib_request(). """ log.error("** BUG ** action_mlib_list() not implemented") def action_search_item(self, action_id, positions, ids): """Do an action on one or more items from a search result. @param action_id: ID of the action to do - this specifies one of the actions passed previously to reply_search_request() by the keyword 'item_actions' @param positions: list of positions to apply the action to @param ids: list of IDs to apply the action to @note: Override if list actions gets passed to reply_search_request(). """ log.error("** BUG ** action_search_item() not implemented") # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): """Request the content of the currently active playlist. @param reply: a ListReply object @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def request_queue(self, reply): """Request the content of the play queue. @param reply: a ListReply object @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def request_mlib(self, reply, path): """Request the content of a playlist from the player's media library. @param reply: a ListReply object @param path: a path within a player's media library If path is an empty list, the root of the library (all top level playlists) are requested. Otherwise path is set as illustrated in this example: Consider a player with a media library structure like this: |- Radio |- Genres |- Jazz |- ... |- Dynamic |- Never played |- Played recently |- ... |- Playlists |- Party |- Sue's b-day |- ... |- ... If path is the empty list, all top level playlists are requests, e.g. ['Radio', 'Genres', 'Dynamic', 'Playlists', ...]. Otherwise path may specify a specific level in the library tree, e.g. [ 'Radio' ] or [ 'Playlists', 'Party', 'Sue's b-day' ] or etc. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") def request_search(self, reply, query): """Request a list of items matching a search query. @param reply: a ListReply object @param query: a list of search query values corresponding with the search mask specified with keyword 'search_mask' in PlayerAdapter.__init__() Example: If search mask was [ 'Artist', 'Title', 'Album' ], then a query may look like this: [ 'Blondie', '', 'Best' ]. It is up to player adapters how to interpret these values. However, good practice is to interpret them as case insensitive, and-connected, non exact matching search values. The given example would then reply a list with all items where 'Blondie' is contained in the artist field and 'Best' is contained in the Album field. @note: Override if it is possible and makes sense. """ log.error("** BUG ** in feature handling") # ========================================================================= # player side synchronization # ========================================================================= def update_position(self, position, queue=False): """Set the current item's position in the playlist or queue. @param position: position of the currently played item (starting at 0) @keyword queue: True if currently played item is from the queue, False if it is from the currently active playlist @note: Call to synchronize player state with remote clients. """ change = self.__state.queue != queue change |= self.__state.position != position if change: self.__state.queue = queue self.__state.position = position self.__sync_trigger(self.__sync_state) def update_playback(self, playback): """Set the current playback state. @param playback: playback mode @see: remuco.PLAYBACK_... @note: Call to synchronize player state with remote clients. """ change = self.__state.playback != playback if change: self.__state.playback = playback self.__sync_trigger(self.__sync_state) def update_repeat(self, repeat): """Set the current repeat mode. @param repeat: True means play indefinitely, False means stop after the last playlist item @note: Call to synchronize player state with remote clients. """ repeat = bool(repeat) change = self.__state.repeat != repeat if change: self.__state.repeat = repeat self.__sync_trigger(self.__sync_state) def update_shuffle(self, shuffle): """Set the current shuffle mode. @param shuffle: True means play in non-linear order, False means play in linear order @note: Call to synchronize player state with remote clients. """ shuffle = bool(shuffle) change = self.__state.shuffle != shuffle if change: self.__state.shuffle = shuffle self.__sync_trigger(self.__sync_state) def update_volume(self, volume): """Set the current volume. @param volume: the volume in percent @note: Call to synchronize player state with remote clients. """ if self.config.master_volume_enabled: # ignore if custom command has been set return volume = int(volume) if volume < 0 or volume > 100: log.warning("bad volume from player adapter: %d" % volume) volume = 50 change = self.__state.volume != volume if change: self.__state.volume = volume self.__sync_trigger(self.__sync_state) def __update_volume_master(self): """Set the current volume (use custom command instead of player).""" cmd = "sh -c '%s'" % self.config.master_volume_get_cmd ret, out = commands.getstatusoutput(cmd) if ret != os.EX_OK: log.error("master-volume-get failed: '%s'" % out) return try: volume = int(out) if volume < 0 or volume > 100: raise ValueError except ValueError: log.error("output of master-volume-get malformed: '%s'" % out) return change = self.__state.volume != volume if change: self.__state.volume = volume self.__sync_trigger(self.__sync_state) def update_progress(self, progress, length): """Set the current playback progress. @param progress: number of currently elapsed seconds @keyword length: item length in seconds (maximum possible progress value) @note: Call to synchronize player state with remote clients. """ # sanitize progress (to a multiple of 5) length = max(0, int(length)) progress = max(0, int(progress)) off = progress % 5 if off < 3: progress -= off else: progress += (5 - off) if length > 0: progress = min(length, progress) change = self.__progress.length != length change |= self.__progress.progress != progress if change: self.__progress.progress = progress self.__progress.length = length self.__sync_trigger(self.__sync_progress) def update_item(self, id, info, img): """Set currently played item. @param id: item ID (str) @param info: meta information (dict) @param img: image / cover art (either a file name or URI or an instance of Image.Image) @note: Call to synchronize player state with remote clients. @see: find_image() for finding image files for an item. @see: remuco.INFO_... for keys to use for 'info' """ log.debug("new item: (%s, %s %s)" % (id, info, img)) change = self.__item_id != id change |= self.__item_info != info change |= self.__item_img != img if change: self.__item_id = id self.__item_info = info self.__item_img = img self.__sync_trigger(self.__sync_item) # ========================================================================= # synchronization (outbound communication) # ========================================================================= def __sync_trigger(self, sync_fn): if self.stopped: return if sync_fn in self.__sync_triggers: log.debug("trigger for %s already active" % sync_fn.func_name) return self.__sync_triggers[sync_fn] = \ gobject.idle_add(sync_fn, priority=gobject.PRIORITY_LOW) def __sync_state(self): del self.__sync_triggers[self.__sync_state] log.debug("broadcast new state to clients: %s" % self.__state) msg = net.build_message(message.SYNC_STATE, self.__state) if msg is None: return for c in self.__clients: c.send(msg) return False def __sync_progress(self): del self.__sync_triggers[self.__sync_progress] log.debug("broadcast new progress to clients: %s" % self.__progress) msg = net.build_message(message.SYNC_PROGRESS, self.__progress) if msg is None: return for c in self.__clients: c.send(msg) return False def __sync_item(self): del self.__sync_triggers[self.__sync_item] log.debug("broadcast new item to clients: %s" % self.__item_id) for c in self.__clients: msg = net.build_message(message.SYNC_ITEM, self.__item(c)) if msg is not None: c.send(msg) return False # ========================================================================= # handling client message (inbound communication) # ========================================================================= def __handle_message(self, client, id, bindata): if message.is_control(id): log.debug("control from client %s" % client) self.__handle_message_control(id, bindata) elif message.is_action(id): log.debug("action from client %s" % client) self.__handle_message_action(id, bindata) elif message.is_request(id): log.debug("request from client %s" % client) self.__handle_message_request(client, id, bindata) elif id == message.PRIV_INITIAL_SYNC: msg = net.build_message(message.SYNC_STATE, self.__state) client.send(msg) msg = net.build_message(message.SYNC_PROGRESS, self.__progress) client.send(msg) msg = net.build_message(message.SYNC_ITEM, self.__item(client)) client.send(msg) else: log.error("** BUG ** unexpected message: %d" % id) def __handle_message_control(self, id, bindata): if id == message.CTRL_PLAYPAUSE: self.ctrl_toggle_playing() elif id == message.CTRL_NEXT: self.ctrl_next() elif id == message.CTRL_PREV: self.ctrl_previous() elif id == message.CTRL_SEEK: control = serial.unpack(Control, bindata) if control is None: return self.ctrl_seek(control.param) elif id == message.CTRL_VOLUME: control = serial.unpack(Control, bindata) if control is None: return if self.config.master_volume_enabled: self.__ctrl_volume_master(control.param) else: self.ctrl_volume(control.param) elif id == message.CTRL_REPEAT: self.ctrl_toggle_repeat() elif id == message.CTRL_SHUFFLE: self.ctrl_toggle_shuffle() elif id == message.CTRL_RATE: control = serial.unpack(Control, bindata) if control is None: return self.ctrl_rate(control.param) elif id == message.CTRL_TAG: tag = serial.unpack(Tagging, bindata) if tag is None: return self.ctrl_tag(tag.id, tag.tags) elif id == message.CTRL_NAVIGATE: control = serial.unpack(Control, bindata) if control is None: return self.ctrl_navigate(control.param) elif id == message.CTRL_FULLSCREEN: self.ctrl_toggle_fullscreen() elif id == message.CTRL_SHUTDOWN: self.__ctrl_shutdown_system() else: log.error("** BUG ** unexpected control message: %d" % id) def __handle_message_action(self, id, bindata): a = serial.unpack(Action, bindata) if a is None: return if id == message.ACT_PLAYLIST: self.action_playlist_item(a.id, a.positions, a.items) elif id == message.ACT_QUEUE: self.action_queue_item(a.id, a.positions, a.items) elif id == message.ACT_MLIB and a.id < 0: # list action id self.action_mlib_list(a.id, a.path) elif id == message.ACT_MLIB and a.id > 0: # item action id self.action_mlib_item(a.id, a.path, a.positions, a.items) elif id == message.ACT_FILES: uris = self.__util_files_to_uris(a.items) self.action_files(a.id, a.items, uris) elif id == message.ACT_SEARCH: self.action_search_item(a.id, a.positions, a.items) else: log.error("** BUG ** unexpected action message: %d" % id) def __handle_message_request(self, client, id, bindata): request = serial.unpack(Request, bindata) if request is None: return reply = ListReply(client, request.request_id, id, request.page, path=request.path) if id == message.REQ_PLAYLIST: self.request_playlist(reply) elif id == message.REQ_QUEUE: self.request_queue(reply) elif id == message.REQ_MLIB: self.request_mlib(reply, request.path) elif id == message.REQ_FILES: reply.nested, reply.ids, reply.names = \ self.__filelib.get_level(request.path) reply.send() elif id == message.REQ_SEARCH: self.request_search(reply, request.path) else: log.error("** BUG ** unexpected request message: %d" % id) # ========================================================================= # miscellaneous # ========================================================================= def __item(self, client): """Creates a client specific item object.""" return Item(self.__item_id, self.__item_info, self.__item_img, client.info.img_size, client.info.img_type) def __util_files_to_uris(self, files): def file_to_uri(file): url = urllib.pathname2url(file) return urlparse.urlunparse(("file", None, url, None, None, None)) if not files: return [] uris = [] for file in files: uris.append(file_to_uri(file)) return uris def __util_calc_flags(self, playback_known, volume_known, repeat_known, shuffle_known, progress_known): """Check player adapter capabilities. Most capabilities get detected by testing which methods have been overridden by a subclassing player adapter. """ def ftc(cond, feature): if inspect.ismethod(cond): # check if overridden enabled = cond.__module__ != __name__ else: enabled = cond if enabled: return feature else: return 0 features = ( # --- 'is known' features --- ftc(playback_known, FT_KNOWN_PLAYBACK), ftc(volume_known, FT_KNOWN_VOLUME), ftc(self.config.master_volume_enabled, FT_KNOWN_VOLUME), ftc(repeat_known, FT_KNOWN_REPEAT), ftc(shuffle_known, FT_KNOWN_SHUFFLE), ftc(progress_known, FT_KNOWN_PROGRESS), # --- misc control features --- ftc(self.ctrl_toggle_playing, FT_CTRL_PLAYBACK), ftc(self.ctrl_volume, FT_CTRL_VOLUME), ftc(self.config.master_volume_enabled, FT_CTRL_VOLUME), ftc(self.ctrl_seek, FT_CTRL_SEEK), ftc(self.ctrl_tag, FT_CTRL_TAG), ftc(self.ctrl_rate, FT_CTRL_RATE), ftc(self.ctrl_toggle_repeat, FT_CTRL_REPEAT), ftc(self.ctrl_toggle_shuffle, FT_CTRL_SHUFFLE), ftc(self.ctrl_next, FT_CTRL_NEXT), ftc(self.ctrl_previous, FT_CTRL_PREV), ftc(self.ctrl_toggle_fullscreen, FT_CTRL_FULLSCREEN), ftc(self.ctrl_navigate, FT_CTRL_NAVIGATE), # --- request features --- ftc(self.request_playlist, FT_REQ_PL), ftc(self.request_queue, FT_REQ_QU), ftc(self.request_mlib, FT_REQ_MLIB), ftc(self.config.system_shutdown_enabled, FT_SHUTDOWN), ) flags = 0 for feature in features: flags |= feature log.debug("flags: %X" % flags) return flags remuco-source-0.9.6/base/module/remuco/art.py0000644000000000000000000000707411700415064021113 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import glob import hashlib import os.path import re import urllib import urlparse from remuco import log from remuco.remos import user_home _RE_IND = r'(?:front|album|cover|folder|art)' # words indicating art files _RE_EXT = r'\.(?:png|jpeg|jpg|gif)' # art file extensions _RE_FILE = (r'^%s%s$' % (_RE_IND,_RE_EXT), # typical name (e.g. front.jpg) r'^.*%s.*%s$' % (_RE_IND,_RE_EXT), # typical name with noise r'^.*%s$' % _RE_EXT) # any image file _RE_FILE = [re.compile(rx, re.IGNORECASE) for rx in _RE_FILE] # ============================================================================= # various methods to find local cover art / media images # ============================================================================= _TN_DIR = os.path.join(user_home, ".thumbnails") def _try_thumbnail(resource): """Try to find a thumbnail for a resource (path or URI).""" if not os.path.isdir(_TN_DIR): return None # we need a file://... URI elems = urlparse.urlparse(resource) if elems[0] and elems[0] != "file": # not local return None if not elems[0]: # resource is a path elems = list(elems) # make elems assignable elems[0] = "file" if isinstance(resource, unicode): resource = resource.encode("utf-8") elems[2] = urllib.pathname2url(resource) resource = urlparse.urlunparse(elems) hex = hashlib.md5(resource).hexdigest() for subdir in ("large", "normal"): file = os.path.join(_TN_DIR, subdir, "%s.png" % hex) if os.path.isfile(file): return file return None def _try_folder(resource): """Try to find an image in the resource's folder.""" # we need a local path elems = urlparse.urlparse(resource) if elems[0] and elems[0] != "file": # resource is not local return None rpath = elems[0] and urllib.url2pathname(elems[2]) or elems[2] rpath = os.path.dirname(rpath) log.debug("looking for art image in %s" % rpath) files = glob.glob(os.path.join(rpath, "*")) files = [os.path.basename(f) for f in files if os.path.isfile(f)] for rx in _RE_FILE: for file in files: if rx.match(file): return os.path.join(rpath, file) return None # ============================================================================= def get_art(resource, prefer_thumbnail=False): if resource is None: return None fname = None methods = (_try_thumbnail, _try_folder) for meth in methods: fname = meth(resource) if fname: break return fname remuco-source-0.9.6/base/module/remuco/config.py0000644000000000000000000002722111700415064021566 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= from __future__ import with_statement import ConfigParser from datetime import datetime from glob import glob import os from os.path import join, isdir, exists, pathsep, basename import re import shutil import sys import textwrap from remuco import log from remuco import defs from remuco.remos import user_config_dir from remuco.remos import user_cache_dir # ============================================================================= # Ordered dictionary, makes CP write sorted config files # ============================================================================= class _odict(dict): def keys(self): kl = list(super(_odict, self).keys()) kl.sort() return kl def items(self): il = list(super(_odict, self).items()) il.sort(cmp=lambda a,b: cmp(a[0], b[0])) return il # ============================================================================= # Constants and definitions # ============================================================================= DEVICE_FILE = join(user_cache_dir, "remuco", "devices") _DOC_HEADER = """# Player Adapter Configuration # ============================ # # Options defined in section DEFAULT affect *all* player adapters. Individual # option values can be defined in each player's section. # # Options starting with `x-` are player specific options, i.e. they don't # appear in section DEFAULT because they only make sense for specific players. # # Options # ======= #""" # should be updated on major changes in config backend (simple removal or # additions of options do not require a version update) _CONFIG_VERSION = "3" # standard options with default values, converter functions and documentation _OPTIONS = { "config-version": ("0", None, "Used internally, don't edit."), "bluetooth-enabled": ("1", int, "Enable or disable Bluetooth."), "bluetooth-channel": ("0", int, "Bluetooth channel to use. 0 mean the next free channel."), "wifi-enabled": ("1", int, "Enable or disable WiFi (Inet)."), "wifi-port": ("34271", int, "WiFi port to use. Should be changed if Remuco is used for multiple " "players simultaneously to prevent port conflicts among adapters."), "player-encoding": ("UTF8", None, "Encoding of text coming from the player (i.e. artist, title, ...)."), "log-level": ("INFO", lambda v: getattr(log, v), "Log verbosity. Possible values: ERROR, WARNING, INFO, DEBUG."), "fb-show-extensions": ("0", int, "If to show file name extensions in a client's file browser."), "fb-root-dirs": ("auto", lambda v: v.split(pathsep), "List of directories (separated by `%s`) to show in a client's file " "browser. `auto` expands to all directories which typically contain " "files of the mime types a player supports (e.g. `~/Music` for audio " "players)." % pathsep), "master-volume-enabled": ("0", int, "Enable or disable master volume. By default a player's volume level " "is controlled by and displayed on clients. By setting this to `1` " "the system's master volume is used instead - in that case the " "following options *may* need to get adusted."), "master-volume-get-cmd": (r'amixer get Master | grep -E "\[[0-9]+%\]" | ' 'sed -re "s/^.*\[([0-9]+)%\].*$/\\1/"', None, "Command to get the master volume level in percent."), "master-volume-up-cmd": ("amixer set Master 5%+", None, "Command to increase the master volume."), "master-volume-down-cmd": ("amixer set Master 5%-", None, "Command to decrease the master volume."), "master-volume-mute-cmd": ("amixer set Master 0%", None, "Command to mute the master volume."), "system-shutdown-enabled": ("0", int, "Enable or disable system shutdown by clients. If enabled, the " "following option *may* need to get adjusted."), "system-shutdown-cmd": ("dbus-send --session --type=method_call " "--dest=org.freedesktop.PowerManagement " "/org/freedesktop/PowerManagement " "org.freedesktop.PowerManagement.Shutdown", None, "Command to shut down the system."), } # defaults-only version of _OPTIONS to pass to config parser _DEFAULTS = _odict() for k, v in _OPTIONS.items(): _DEFAULTS[k] = v[0] # timestamp (used for backups of old config data) _TS = datetime.now().strftime("%Y%m%d-%H%M%S") # ============================================================================= # Config class # ============================================================================= class Config(object): """Class for getting and setting player adapter specific configurations. An instance of Config mirrors the configuration of a specific player adapter (usually ~/.config/remuco/PLAYER/conf). Player adapters are not supposed to create instances of Config. Instead use the 'config' attribute of a PlayerAdapter instance to access the currently used Config instance. """ def __init__(self, player_name): """Create a new instance for the given player (adapter).""" super(Config, self).__init__() # convert descriptive name to a plain canonical one self.player = re.sub(r'[^\w-]', '', player_name).lower() # paths self.dir = join(user_config_dir, "remuco") self.cache = join(user_cache_dir, "remuco") self.file = join(self.dir, "remuco.cfg") # remove old stuff self.__cleanup() # create directories for dname in (self.dir, self.cache): try: if not isdir(dname): os.makedirs(dname) except OSError, e: log.error("failed to make dir: %s", e) if not "REMUCO_LOG_STDOUT" in os.environ and isdir(self.cache): log.set_file(join(self.cache, "%s.log" % self.player)) # load cp = ConfigParser.RawConfigParser(_DEFAULTS, _odict) if not cp.has_section(self.player): cp.add_section(self.player) if exists(self.file): try: cp.read(self.file) except ConfigParser.Error, e: log.warning("failed to read config %s (%s)" % (self.file, e)) # reset on version change if cp.get(ConfigParser.DEFAULTSECT, "config-version") != _CONFIG_VERSION: sections = cp.sections() # keep already existing player sections cp = ConfigParser.RawConfigParser(_DEFAULTS, _odict) for sec in sections: cp.add_section(sec) if exists(self.file): bak = "%s.%s.backup" % (self.file, _TS) log.info("reset config (major changes, backup: %s)" % bak) shutil.copy(self.file, bak) # remove unknown options in all sections for sec in cp.sections() + [ConfigParser.DEFAULTSECT]: for key, value in cp.items(sec): if key not in _DEFAULTS and not key.startswith("x-"): cp.remove_option(sec, key) # add not yet existing options to default section for key, value in _DEFAULTS.items(): if not cp.has_option(ConfigParser.DEFAULTSECT, key): cp.set(ConfigParser.DEFAULTSECT, key, value) # update version cp.set(ConfigParser.DEFAULTSECT, "config-version", _CONFIG_VERSION) self.__cp = cp # save to always have a clean file self.__save() log.set_level(self.log_level) log.info("remuco version: %s" % defs.REMUCO_VERSION) def __getattribute__(self, attr): """Attribute-style access to standard options.""" try: return super(Config, self).__getattribute__(attr) except AttributeError, e: _attr = attr.replace("_", "-") if _attr in _OPTIONS: attr = _attr elif attr not in _OPTIONS: raise e value = self.__cp.get(self.player, attr) converter = _OPTIONS[attr][1] or (lambda v: v) try: return converter(value) except Exception, e: log.error("malformed option '%s: %s' (%s)" % (attr, e)) return converter(_DEFAULTS[attr]) def getx(self, key, default, converter=None, save=True): """Get the value of a non-standard, player specific option. @param key: config option name @param default: default value (as string!) @keyword converter: value converter function, e.g. `int` @keyword save: save default value in config file if not yet set @return: option value, optionally converted """ key = "x-%s" % key if not self.__cp.has_option(self.player, key) and save: self.__cp.set(self.player, key, default) self.__save() try: value = self.__cp.get(self.player, key) except ConfigParser.NoOptionError: value = default converter = converter or (lambda v: v) try: return converter(value) except Exception, e: log.error("malformed option '%s: %s' (%s)" % (key, value, e)) return converter(default) # if this fails then, it's a bug def __save(self): """Save config to it's file.""" doc = [_DOC_HEADER] for key in _DEFAULTS.keys(): idoc = "# %s:" % key idoc = [idoc] + textwrap.wrap(_OPTIONS[key][2], 73) idoc = "\n# ".join(idoc) doc.append(idoc) doc = "\n".join(doc) try: with open(self.file, 'w') as fp: fp.write(doc) fp.write("\n\n") self.__cp.write(fp) except IOError, e: log.warning("failed to save config to %s (%s)" % (self.file, e)) def __cleanup(self): """Trash obsolete config and cache data from older versions.""" def obsolete(fn): """Check if a config or cache item may be trashed.""" obs = isdir(fn) obs |= basename(fn) in ("shutdown-system", "volume") obs &= not basename(fn).startswith("old-") return obs for dname, dtype in ((self.dir, "config"), (self.cache, "cache")): trash = join(dname, "old-%s.backup" % _TS) fnames = [f for f in glob(join(dname, "*")) if obsolete(f)] if fnames: log.info("moving old %s data to %s" % (dtype, trash)) if not exists(trash): os.makedirs(trash) for fn in fnames: shutil.move(fn, trash) remuco-source-0.9.6/base/module/remuco/data.py0000644000000000000000000002412611700415064021233 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Data containers to send to and receive from clients.""" import tempfile import Image import urlparse import urllib from remuco import log from remuco import serial # ============================================================================= # outgoing data (to clients) # ============================================================================= class PlayerInfo(serial.Serializable): """ Parameter of the player info message sent to clients.""" def __init__(self, name, flags, max_rating, file_item_actions, search_mask): self.name = name self.flags = flags self.max_rating = max_rating self.fia_ids = [] self.fia_labels = [] self.fia_multiples = [] for action in file_item_actions or []: self.fia_ids.append(action.id); self.fia_labels.append(action.label); self.fia_multiples.append(action.multiple); self.search_mask = search_mask or [] # === serial interface === def get_fmt(self): return (serial.TYPE_S, serial.TYPE_I, serial.TYPE_Y, serial.TYPE_AI, serial.TYPE_AS, serial.TYPE_AB, serial.TYPE_AS) def get_data(self): return (self.name, self.flags, self.max_rating, self.fia_ids, self.fia_labels, self.fia_multiples, self.search_mask) class PlayerState(serial.Serializable): """ Parameter of the state sync message sent to clients.""" def __init__(self): self.playback = 0 self.volume = 0 self.position = 0 self.repeat = False self.shuffle = False self.queue = False def __str__(self): return "(%d, %d, %d, %s, %s, %s)" % ( self.playback, self.volume, self.position, self.repeat, self.shuffle, self.queue) # === serial interface === def get_fmt(self): return (serial.TYPE_Y, serial.TYPE_Y, serial.TYPE_I, serial.TYPE_B, serial.TYPE_B, serial.TYPE_B) def get_data(self): return (self.playback, self.volume, self.position, self.repeat, self.shuffle, self.queue) class Progress(serial.Serializable): """ Parameter of the progress sync message sent to clients.""" def __init__(self): self.progress = 0 self.length = 0 def __str__(self): return "(%d/%d)" % (self.progress, self.length) # === serial interface === def get_fmt(self): return (serial.TYPE_I, serial.TYPE_I) def get_data(self): return (self.progress, self.length) class Item(serial.Serializable): """ Parameter of the item sync message sent to clients.""" def __init__(self, id, info, img, img_size, img_type): self.__id = id self.__info = self.__flatten_info(info) self.__img = self.__thumbnail_img(img, img_size, img_type) def __str__(self): return "(%s, %s, %s)" % (self.__id, self.__info, self.__img) # === serial interface === def get_fmt(self): return (serial.TYPE_S, serial.TYPE_AS, serial.TYPE_AY) def get_data(self): return (self.__id, self.__info, self.__img) # === misc === def __flatten_info(self, info_dict): info_list = [] if not info_dict: return info_list for key in info_dict.keys(): val = info_dict.get(key) if val is not None: info_list.append(key) if not isinstance(val, basestring): val = str(val) info_list.append(val) return info_list def __thumbnail_img(self, img, img_size, img_type): if img_size == 0: return [] if isinstance(img, basestring) and img.startswith("file://"): img = urlparse.urlparse(img)[2] img = urllib.url2pathname(img) if not img: return [] try: if not isinstance(img, Image.Image): img = Image.open(img) img.thumbnail((img_size, img_size)) file_tmp = tempfile.TemporaryFile() if img_type == "JPEG" and img.mode == "P": img = img.convert("RGB") img.save(file_tmp, img_type) file_tmp.seek(0) thumb = file_tmp.read() file_tmp.close() return thumb except IOError, e: log.warning("failed to thumbnail %s (%s)" % (img, e)) return [] class ItemList(serial.Serializable): """ Parameter of a request reply message sent to clients.""" def __init__(self, request_id, path, nested, item_ids, item_names, item_offset, page, page_max, item_actions, list_actions): self.request_id = request_id self.path = path or [] self.nested = nested or [] self.item_ids = item_ids or [] self.item_names = item_names or [] self.item_offset = item_offset self.page = page or 0 self.page_max = page_max or 0 self.ia_ids = [] self.ia_labels = [] self.ia_multiples = [] for action in item_actions or []: self.ia_ids.append(action.id); self.ia_labels.append(action.label); self.ia_multiples.append(action.multiple); self.la_ids = [] self.la_labels = [] for action in list_actions or []: self.la_ids.append(action.id); self.la_labels.append(action.label); def __str__(self): return "(%d, %s, %s, %s, %s, %d, %d, %d, %s, %s, %s, %s, %s, %s, %s)" % ( self.request_id, self.path, self.nested, self.item_ids, self.item_names, self.item_offset, self.page, self.page_max, self.ia_ids, self.ia_labels, self.ia_multiples, self.la_ids, self.la_labels) # === serial interface === def get_fmt(self): return (serial.TYPE_I, serial.TYPE_AS, serial.TYPE_AS, serial.TYPE_AS, serial.TYPE_AS, serial.TYPE_I, serial.TYPE_I, serial.TYPE_I, serial.TYPE_AI, serial.TYPE_AS, serial.TYPE_AB, serial.TYPE_AI, serial.TYPE_AS) def get_data(self): return (self.request_id, self.path, self.nested, self.item_ids, self.item_names, self.item_offset, self.page, self.page_max, self.ia_ids, self.ia_labels, self.ia_multiples, self.la_ids, self.la_labels) # ============================================================================= # incoming data (from clients) # ============================================================================= class ClientInfo(serial.Serializable): """ Parameter of a client info messages from a client.""" def __init__(self): self.img_size = 0 self.img_type = None self.page_size = 0 self.device = {} # === serial interface === def get_fmt(self): return (serial.TYPE_I, serial.TYPE_S, serial.TYPE_I, serial.TYPE_AS, serial.TYPE_AS) def set_data(self, data): self.img_size, self.img_type, self.page_size, dev_keys, dev_vals = data for key, value in zip(dev_keys, dev_vals): self.device[key] = value class Control(serial.Serializable): """ Parameter of control messages from clients with integer arguments.""" def __init__(self): self.param = 0 # === serial interface === def get_fmt(self): return (serial.TYPE_I,) def set_data(self, data): self.param, = data class Action(serial.Serializable): """ Parameter of an action message from a client.""" def __init__(self): self.id = 0 self.path = None self.positions = None self.items = None # item ids or file names # === serial interface === def get_fmt(self): return (serial.TYPE_I, serial.TYPE_AS, serial.TYPE_AI, serial.TYPE_AS) def set_data(self, data): self.id, self.path, self.positions, self.items = data class Tagging(serial.Serializable): """ Parameter of a tagging message from a client.""" def __init__(self): self.id = None self.tags = None # === serial interface === def get_fmt(self): return (serial.TYPE_S, serial.TYPE_AS) def set_data(self, data): self.id, self.tags = data class Request(serial.Serializable): """ Parameter of a request message from a client.""" def __init__(self): self.request_id = -2 self.id = None # item id self.path = None # list path self.page = 0 # list page # === serial interface === def get_fmt(self): return (serial.TYPE_I, serial.TYPE_S, serial.TYPE_AS, serial.TYPE_I) def set_data(self, data): self.request_id, self.id, self.path, self.page = data remuco-source-0.9.6/base/module/remuco/defs.py0000644000000000000000000000245311700415064021242 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= PLAYBACK_PAUSE = 1 PLAYBACK_PLAY = 2 PLAYBACK_STOP = 0 INFO_ABSTRACT = "__abstract__" INFO_ALBUM = "album" INFO_ARTIST = "artist" INFO_BITRATE = "bitrate" INFO_COMMENT = "comment" INFO_GENRE = "genre" INFO_LENGTH = "length" INFO_RATING = "rating" INFO_TAGS = "tags" INFO_TITLE = "title" INFO_TRACK = "track" INFO_YEAR = "year" REMUCO_VERSION = "0.9.6" remuco-source-0.9.6/base/module/remuco/dictool.py0000644000000000000000000001026011700415064021751 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Utility functions to read/write simple str<->str dicts from/to files.""" from __future__ import with_statement import os.path from remuco import log def dict_to_string(dic, keys=None): """Flatten a dictionary. @param dic: The dictionary to flatten. @keyword only: A list of keys to include in the flattened string. This list also gives the order in which items are flattened. If only is None, all items are flattened in an arbitrary order. @return: the flattened dictionary as a string """ flat = "" keys = keys or dic.keys() for key in keys: value = dic.get(key, "") value = value.replace(",", "_") flat += "%s:%s," % (key, value) flat = flat.strip(",") return flat def string_to_dict(s, keys=None): """Create a dictionary from a flattened string representation. @param s: The string to build dictionary from. @keyword keys: A list of keys to include in dictionary. If keys is None, all items are flattened in an arbitrary order. @return: the dictionary """ dic = {} items = s.split(",") for item in items: try: key, value = item.split(":", 1) except ValueError: key, value = item, "" if keys is None or key in keys: dic[key] = value return dic def read_dicts_from_file(filename, flat=False, keys=None): """Read a list of dictionaries from a file. @param filename: Name of the file to read. @keyword flat: If True, the dictionaries are returned flattened, i.e. as strings. @keyword keys: See string_to_dict(). Only used if flat is False. @return: the list of dictionaries """ if not os.path.exists(filename): return [] lines = [] try: fp = open(filename, "r") lines = fp.readlines() fp.close() except IOError, e: log.warning("failed to open %s (%s)" % (filename, e)) dicts_flat = [] for line in lines: line = line.replace("\n", "") line = line.strip(" ") if line.startswith("#") or len(line) == 0: continue dicts_flat.append(line) if flat: return dicts_flat dicts = [] for dic_flat in dicts_flat: dicts.append(string_to_dict(dic_flat, keys=keys)) return dicts def write_dicts_to_file(filename, dicts, keys=None, comment=None): """Write a list of dictionaries into a file. @param filename: Name of the file to write into. @param dicts: Either a list of dictionaries or a list of strings, i.e. already flattened dictionaries. @keyword keys: See dict_to_string(). Only used if dictionaries are not yet flattened. @keyword comment: A comment text to put at the beginning of the file. """ lines = [] if comment: lines.append("%s\n" % comment) for dic in dicts: if not isinstance(dic, basestring): dic = dict_to_string(dic, keys=keys) lines.append("%s\n" % dic) try: with open(filename, "w") as fp: fp.writelines(lines) except IOError, e: log.warning("failed to write to %s (%s)" % (filename, e)) remuco-source-0.9.6/base/module/remuco/features.py0000644000000000000000000000315711700415064022141 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= # --- 'is known' features --- FT_KNOWN_VOLUME = 1 << 0 FT_KNOWN_REPEAT = 1 << 1 FT_KNOWN_SHUFFLE = 1 << 2 FT_KNOWN_PLAYBACK = 1 << 3 FT_KNOWN_PROGRESS = 1 << 4 # --- control features --- FT_CTRL_PLAYBACK = 1 << 9 FT_CTRL_VOLUME = 1 << 10 FT_CTRL_SEEK = 1 << 11 FT_CTRL_TAG = 1 << 12 #FT_CTRL_ = 1 << 13 #FT_CTRL_ = 1 << 14 FT_CTRL_RATE = 1 << 15 FT_CTRL_REPEAT = 1 << 16 FT_CTRL_SHUFFLE = 1 << 17 FT_CTRL_NEXT = 1 << 18 FT_CTRL_PREV = 1 << 19 FT_CTRL_FULLSCREEN = 1 << 20 FT_CTRL_NAVIGATE = 1 << 21 # --- request features --- FT_REQ_ITEM = 1 << 25 # obsolete FT_REQ_PL = 1 << 26 FT_REQ_QU = 1 << 27 FT_REQ_MLIB = 1 << 28 # --- misc features FT_SHUTDOWN = 1 << 30 remuco-source-0.9.6/base/module/remuco/files.py0000644000000000000000000001372111700415064021423 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import os import os.path import mimetypes import sys from remuco import log from remuco.remos import media_dirs, user_home class FileSystemLibrary(object): def __init__(self, root_dirs, mime_types, show_extensions, show_hidden): self.__mime_types = mime_types self.__show_extensions = show_extensions self.__show_hidden = show_hidden if not sys.getfilesystemencoding() in ("UTF8", "UTF-8", "UTF_8"): log.warning("file system encoding is not UTF-8, this may cause " + "problems with file browser features") root_dirs = root_dirs or [] # mimetype dependent root dirs if "auto" in root_dirs: root_dirs.remove("auto") if mime_types: for mtype in mime_types: if mtype in media_dirs: root_dirs += media_dirs[mtype] mtype = mtype.split("/")[0] # use main mimetype if mtype in media_dirs: root_dirs += media_dirs[mtype] root_dirs = self.__trim_root_dirs(root_dirs) or [user_home] # map root dirs to names self.__roots = {} for dir in root_dirs: name = os.path.basename(dir) if name == dir: # == "/" name = "Root" else: name = name.capitalize() counter = 2 name_x = name while name_x in self.__roots: name_x = "%s (%d)" % (name, counter) counter += 1 self.__roots[name_x] = dir log.info("file browser root dirs: %s " % self.__roots) if not mimetypes.inited: mimetypes.init() def __trim_root_dirs(self, dirs): """Trim a directory list. Expands variables and '~' and removes duplicate, relative, non existent and optionally hidden directories. @return: a trimmed directory list """ trimmed = [] for dir in dirs: dir = os.path.expandvars(dir) dir = os.path.expanduser(dir) if not self.__show_hidden and dir.startswith("."): continue if not os.path.isabs(dir): log.warning("path %s not absolute, ignore" % dir) continue if not os.path.isdir(dir): log.warning("path %s not a directory, ignore" % dir) continue if dir not in trimmed: trimmed.append(dir) return trimmed def get_level(self, path): def is_hidden(name): return name.startswith(".") or name.endswith("~") def mimetype_is_supported(name): type = mimetypes.guess_type(name)[0] or "" type_main = type.split("/")[0] return (not self.__mime_types or type_main in self.__mime_types or type in self.__mime_types) nested = [] ids = [] names = [] if not path: nested = list(self.__roots.keys()) # Py3K nested.sort() return (nested, ids, names) label = path[0] # root dir label dir = self.__roots[label] # root dir path = path[1:] # path elements relative to root dir for elem in path: dir = os.path.join(dir, elem) try: x, dirs, files = os.walk(dir).next() except StopIteration: return (nested, ids, names) dirs.sort() files.sort() for entry in dirs: entry_abs = os.path.join(dir, entry) if not self.__show_hidden and is_hidden(entry): log.debug("ignore %s (hidden)" % entry_abs) continue if not os.access(entry_abs, os.X_OK | os.R_OK): log.debug("ignore %s (no access)" % entry_abs) continue nested.append(entry) for entry in files: entry_abs = os.path.join(dir, entry) if not self.__show_hidden and is_hidden(entry): log.debug("ignore %s (hidden)" % entry_abs) continue if not os.access(entry_abs, os.R_OK): log.debug("ignore %s (no access)" % entry_abs) continue if not os.path.isfile(entry_abs): log.debug("ignore %s (no regular file)" % entry_abs) continue if not mimetype_is_supported(entry): log.debug("ignore %s (wrong mime type)" % entry_abs) continue ids.append(entry_abs) if not self.__show_extensions: entry = os.path.splitext(entry)[0] names.append(entry) return (nested, ids, names) remuco-source-0.9.6/base/module/remuco/log.py0000644000000000000000000000675111700415064021107 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import logging DEBUG = logging.DEBUG INFO = logging.INFO WARNING = logging.WARNING ERROR = logging.ERROR #=============================================================================== # set up default logger #=============================================================================== class _config: """Configuration container""" FMT = logging.Formatter("%(asctime)s [%(levelname)7s] [%(filename)11s " + "%(lineno)4d] %(message)s") FMTX = logging.Formatter("%(levelname)s: %(message)s (check the log for " "details)") handler_stdout = logging.StreamHandler() handler_stdout.setFormatter(FMT) handler = handler_stdout logga = logging.getLogger("remuco") logga.addHandler(handler) logga.setLevel(INFO) #=============================================================================== # log functions #=============================================================================== debug = _config.logga.debug info = _config.logga.info warning = _config.logga.warning error = _config.logga.error exception = _config.logga.exception #=============================================================================== # configuration functions #=============================================================================== def set_file(file): """Set log file (pass None to log to stdout).""" new_handler = None if file is not None: try: new_handler = logging.FileHandler(file, 'w') except IOError, e: print("failed to set up log handler (%s)" % e) return new_handler.setFormatter(_config.FMT) print("Log output will be stored in %s" % file) print("Contribute to Remuco: Please run 'remuco-report' once a client " "has connected, thanks!") if _config.handler != _config.handler_stdout: _config.logga.removeHandler(_config.handler) if new_handler: _config.handler_stdout.setLevel(ERROR) _config.handler_stdout.setFormatter(_config.FMTX) _config.logga.addHandler(new_handler) _config.handler = new_handler else: _config.handler_stdout.setLevel(_config.logga.level) _config.handler_stdout.setFormatter(_config.FMT) _config.handler = _config.handler_stdout def set_level(level): """ Set log level (one of log.DEBUG, log.INFO, log.WARNING, log.ERROR).""" _config.logga.setLevel(level) if _config.handler is not None: _config.handler.setLevel(level) remuco-source-0.9.6/base/module/remuco/manager.py0000644000000000000000000002517011700415064021734 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Manage life cycle of stand-alone (not plugin based) player adapters.""" import signal import gobject from remuco import log try: import dbus from dbus.exceptions import DBusException from dbus.mainloop.glib import DBusGMainLoop except ImportError: log.warning("dbus not available - dbus using player adapters will crash") # ============================================================================= # global items and signal handling # ============================================================================= _ml = None def _sighandler(signum, frame): log.info("received signal %i" % signum) if _ml is not None: _ml.quit() # ============================================================================= # start stop functions # ============================================================================= def _start_pa(pa): """Start the given player adapter with error handling.""" log.info("start player adapter") try: pa.start() except StandardError, e: log.error("failed to start player adapter (%s)" % e) return False except Exception, e: log.exception("** BUG ** %s", e) return False else: log.info("player adapter started") return True def _stop_pa(pa): """Stop the given player adapter with error handling.""" log.info("stop player adapter") try: pa.stop() except Exception, e: log.exception("** BUG ** %s", e) else: log.info("player adapter stopped") # ============================================================================= # Polling Observer # ============================================================================= class _PollingObserver(): """Polling based observer for a player's run state. A polling observer uses a custom function to periodically check if a media player is running and automatically starts and stops the player adapter accordingly. """ def __init__(self, pa, poll_fn): """Create a new polling observer. @param pa: the PlayerAdapter to automatically start and stop @param poll_fn: the function to call periodically to check if the player is running """ self.__pa = pa self.__poll_fn = poll_fn self.__sid = gobject.timeout_add(5123, self.__poll, False) gobject.idle_add(self.__poll, True) def __poll(self, first): running = self.__poll_fn() if running and self.__pa.stopped: _start_pa(self.__pa) elif not running and not self.__pa.stopped: _stop_pa(self.__pa) # else: nothing to do return first and False or True def stop(self): gobject.source_remove(self.__sid) # ============================================================================= # DBus Observer # ============================================================================= class _DBusObserver(): """DBus based observer for a player's run state. A DBus observer uses DBus name owner change notifications to automatically start and stop a player adapter if the corresponding media player starts or stops. """ def __init__(self, pa, dbus_name): """Create a new DBus observer. @param pa: the PlayerAdapter to automatically start and stop @param dbus_name: the bus name used by the adapter's media player """ DBusGMainLoop(set_as_default=True) self.__pa = pa self.__dbus_name = dbus_name try: bus = dbus.SessionBus() except DBusException, e: log.error("no dbus session bus (%s)" % e) return try: proxy = bus.get_object(dbus.BUS_DAEMON_NAME, dbus.BUS_DAEMON_PATH) self.__dbus = dbus.Interface(proxy, dbus.BUS_DAEMON_IFACE) except DBusException, e: log.error("failed to connect to dbus daemon (%s)" % e) return try: self.__handlers = ( self.__dbus.connect_to_signal("NameOwnerChanged", self.__on_owner_change, arg0=self.__dbus_name), ) self.__dbus.NameHasOwner(self.__dbus_name, reply_handler=self.__reply_has_owner, error_handler=self.__dbus_error) except DBusException, e: log.error("failed to talk with dbus daemon (%s)" % e) return def __on_owner_change(self, name, old, new): log.debug("dbus name owner changed: '%s' -> '%s'" % (old, new)) _stop_pa(self.__pa) if new: _start_pa(self.__pa) def __reply_has_owner(self, has_owner): log.debug("dbus name has owner: %s" % has_owner) if has_owner: _start_pa(self.__pa) def __dbus_error(self, error): log.warning("dbus error: %s" % error) def stop(self): for handler in self.__handlers: handler.remove() self.__handlers = () self.__dbus = None # ============================================================================= # Manager # ============================================================================= class Manager(object): """Life cycle manager for a stand-alone player adapter. A manager cares about calling a PlayerAdapter's start and stop methods. Additionally, because Remuco needs a GLib main loop to run, it sets up and manages such a loop. It is intended for player adapters running stand-alone, outside the players they adapt. A manager is not needed for player adapters realized as a plugin for a media player. In that case the player's plugin interface should care about the life cycle of a player adapter (see the Rhythmbox player adapter as an example). """ def __init__(self, pa, dbus_name=None, poll_fn=None): """Create a new manager. @param pa: the PlayerAdapter to manage @keyword dbus_name: if the player adapter uses DBus to communicate with its player set this to the player's well known bus name (see run() for more information) @keyword poll_fn: if DBus is not used, this function may be set for periodic checks if the player is running, used to automatically start and stop the player adapter When neither `dbus_name` nor `poll_fn` is given, the adapter is started immediately, assuming the player is running and the adapter is ready to work. """ self.__pa = pa self.__pa.manager = self self.__stopped = False self.__observer = None global _ml if _ml is None: _ml = gobject.MainLoop() signal.signal(signal.SIGINT, _sighandler) signal.signal(signal.SIGTERM, _sighandler) self.__ml = _ml if dbus_name: log.info("start dbus observer") self.__observer = _DBusObserver(pa, dbus_name) elif poll_fn: log.info("start polling observer") self.__observer = _PollingObserver(pa, poll_fn) else: # nothing to do pass def run(self): """Activate the manager. This method starts the player adapter, runs a main loop (GLib) and blocks until SIGINT or SIGTERM arrives or until stop() gets called. If this happens the player adapter gets stopped and this method returns. If `player_dbus_name` or `poll_fn` has been passed to __init__(), then the player adapter does not get started until the player is running (according to checks based on the DBus name or poll function). Also the adapter gets stopped automatically if the player is not running anymore. However, the manager keeps running, i.e. the player adapter may get started and stopped multiple times while this method is running. """ if self.__observer is None: # start pa directly ready = _start_pa(self.__pa) else: # observer will start pa ready = True if ready and not self.__stopped: # not stopped since creation log.info("start main loop") try: self.__ml.run() except Exception, e: log.exception("** BUG ** %s", e) else: log.info("main loop stopped") if self.__observer: # stop observer self.__observer.stop() log.info("observer stopped") # stop pa _stop_pa(self.__pa) def stop(self): """Shut down the manager. Stops the manager's main loop and player adapter. As a result a previous call to run() will return now. This should be used by player adapters when there is a crucial error and restarting the adapter won't fix this. """ log.info("manager stopped internally") self.__stopped = True self.__ml.quit() class NoManager(object): """Dummy manager which can be stopped - does nothing. Initially this manager is assigned to every PlayerAdapter. That way it is always safe to call PlayerAdapter.manager.stop() even if an adapter has not yet or not at all a real Manager. """ def stop(self): """Stop me, I do nothing.""" remuco-source-0.9.6/base/module/remuco/message.py0000644000000000000000000000644311700415064021750 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= IGNORE = 0 # ============================================================================= # connection related messages # ============================================================================= _CONN = 100 #CONN_PLIST = _CONN CONN_PINFO = _CONN + 10 CONN_CINFO = _CONN + 20 CONN_SLEEP = _CONN + 30 CONN_WAKEUP = _CONN + 40 CONN_BYE = _CONN + 90 # ============================================================================= # sync messages # ============================================================================= _SYNC = 200 SYNC_STATE = _SYNC SYNC_PROGRESS = _SYNC + 1 SYNC_ITEM = _SYNC + 2 # ============================================================================= # control messages # ============================================================================= _CTRL = 300 CTRL_PLAYPAUSE = _CTRL CTRL_NEXT = _CTRL + 1 CTRL_PREV = _CTRL + 2 CTRL_SEEK = _CTRL + 3 CTRL_VOLUME = _CTRL + 4 CTRL_REPEAT = _CTRL + 5 CTRL_SHUFFLE = _CTRL + 6 CTRL_FULLSCREEN = _CTRL + 7 CTRL_RATE = _CTRL + 8 CTRL_TAG = _CTRL + 30 CTRL_NAVIGATE = _CTRL + 40 #31 would be ugly CTRL_SHUTDOWN = _CTRL + 90 # ============================================================================= # action messages # ============================================================================= _ACT = 400 ACT_PLAYLIST = _ACT ACT_QUEUE = _ACT + 1 ACT_MLIB = _ACT + 2 ACT_FILES = _ACT + 3 ACT_SEARCH = _ACT + 4 # ============================================================================= # request messages # ============================================================================= _REQ = 500 REQ_ITEM = _REQ # currently unused REQ_PLAYLIST = _REQ + 1 REQ_QUEUE = _REQ + 2 REQ_MLIB = _REQ + 3 REQ_FILES = _REQ + 4 REQ_SEARCH = _REQ + 5 # ============================================================================= # internal messages # ============================================================================= _PRIV = 0x10000000 PRIV_INITIAL_SYNC = _PRIV # used internally in server # ============================================================================= def _is_in_range(range_start, id): return id >= range_start and id < range_start + 100 def is_control(id): return _is_in_range(_CTRL, id) def is_action(id): return _is_in_range(_ACT, id) def is_request(id): return _is_in_range(_REQ, id) def is_private(id): return _is_in_range(_PRIV, id) remuco-source-0.9.6/base/module/remuco/mpris.py0000644000000000000000000004417511700415064021462 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import os.path import gobject from remuco.adapter import PlayerAdapter, ItemAction from remuco.defs import * from remuco import log try: import dbus from dbus.exceptions import DBusException except ImportError: log.warning("dbus not available - MPRIS based player adapters will crash") # ============================================================================= # MPRIS constants # ============================================================================= CAN_GO_NEXT = 1 << 0 CAN_GO_PREV = 1 << 1 CAN_PAUSE = 1 << 2 CAN_PLAY = 1 << 3 CAN_SEEK = 1 << 4 CAN_PROVIDE_METADATA = 1 << 5 CAN_HAS_TRACKLIST = 1 << 6 STATUS_PLAYING = 0 STATUS_PAUSED = 1 STATUS_STOPPED = 2 MINFO_KEY_RATING = "rating" # ============================================================================= # actions # ============================================================================= IA_APPEND = ItemAction("Append", multiple=True) IA_APPEND_PLAY = ItemAction("Append and play", multiple=True) FILE_ACTIONS = (IA_APPEND, IA_APPEND_PLAY) IA_JUMP = ItemAction("Jump to") # __jump_to() is ambiguous on dynamic playlists IA_REMOVE = ItemAction("Remove", multiple=True) PLAYLIST_ACTIONS = [IA_REMOVE] # ============================================================================= # player adapter # ============================================================================= class MPRISAdapter(PlayerAdapter): def __init__(self, name, display_name=None, poll=2.5, mime_types=None, rating=False, extra_file_actions=None, extra_playlist_actions=None): display_name = display_name or name if rating: max_rating = 5 else: max_rating = 0 all_file_actions = FILE_ACTIONS + tuple(extra_file_actions or ()) PlayerAdapter.__init__(self, display_name, max_rating=max_rating, playback_known=True, volume_known=True, repeat_known=True, shuffle_known=True, progress_known=True, file_actions=all_file_actions, mime_types=mime_types) self.__playlist_actions = PLAYLIST_ACTIONS if self.config.getx("playlist-jump-enabled", "0", int): self.__playlist_actions.append(IA_JUMP) if extra_playlist_actions: self.__playlist_actions.extend(extra_playlist_actions) self.__name = name self.__dbus_signal_handler = () self._mp_p = None self._mp_t = None self._repeat = False self._shuffle = False self._playing = PLAYBACK_STOP self.__volume = 0 self.__progress_now = 0 self.__progress_max = 0 self.__can_pause = False self.__can_play = False self.__can_seek = False self.__can_next = False self.__can_prev = False self.__can_tracklist = False log.debug("init done") def start(self): PlayerAdapter.start(self) try: bus = dbus.SessionBus() proxy = bus.get_object("org.mpris.%s" % self.__name, "/Player") self._mp_p = dbus.Interface(proxy, "org.freedesktop.MediaPlayer") proxy = bus.get_object("org.mpris.%s" % self.__name, "/TrackList") self._mp_t = dbus.Interface(proxy, "org.freedesktop.MediaPlayer") except DBusException, e: raise StandardError("dbus error: %s" % e) try: self.__dbus_signal_handler = ( self._mp_p.connect_to_signal("TrackChange", self._notify_track), self._mp_p.connect_to_signal("StatusChange", self._notify_status), self._mp_p.connect_to_signal("CapsChange", self._notify_caps), self._mp_t.connect_to_signal("TrackListChange", self._notify_tracklist_change), ) except DBusException, e: raise StandardError("dbus error: %s" % e) try: self._mp_p.GetStatus(reply_handler=self._notify_status, error_handler=self._dbus_error) self._mp_p.GetMetadata(reply_handler=self._notify_track, error_handler=self._dbus_error) self._mp_p.GetCaps(reply_handler=self._notify_caps, error_handler=self._dbus_error) except DBusException, e: # this is not necessarily a fatal error log.warning("dbus error: %s" % e) def stop(self): PlayerAdapter.stop(self) for handler in self.__dbus_signal_handler: handler.remove() self.__dbus_signal_handler = () self._mp_p = None self._mp_t = None def poll(self): self._poll_volume() self._poll_progress() # ========================================================================= # control interface # ========================================================================= def ctrl_toggle_playing(self): try: if self._playing == PLAYBACK_STOP: self._mp_p.Play(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) else: self._mp_p.Pause(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_toggle_repeat(self): try: self._mp_t.SetLoop(not self._repeat, reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_toggle_shuffle(self): try: self._mp_t.SetRandom(not self._shuffle, reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_next(self): if not self.__can_next: log.debug("go to next item is currently not possible") return try: self._mp_p.Next(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_previous(self): if not self.__can_prev: log.debug("go to previous is currently not possible") return try: self._mp_p.Prev(reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def ctrl_volume(self, direction): if direction == 0: volume = 0 else: volume = self.__volume + 5 * direction volume = min(volume, 100) volume = max(volume, 0) try: self._mp_p.VolumeSet(volume, reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) gobject.idle_add(self._poll_volume) def ctrl_seek(self, direction): if not self.__can_seek: log.debug("seeking is currently not possible") return self.__progress_now += 5 * direction self.__progress_now = min(self.__progress_now, self.__progress_max) self.__progress_now = max(self.__progress_now, 0) log.debug("new progress: %d" % self.__progress_now) try: self._mp_p.PositionSet(self.__progress_now * 1000, reply_handler=self._dbus_ignore, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) gobject.idle_add(self._poll_progress) # ========================================================================= # actions interface # ========================================================================= def action_files(self, action_id, files, uris): if action_id == IA_APPEND.id or action_id == IA_APPEND_PLAY.id: try: self._mp_t.AddTrack(uris[0], action_id == IA_APPEND_PLAY.id) for uri in uris[1:]: self._mp_t.AddTrack(uri, False) except DBusException, e: log.warning("dbus error: %s" % e) return else: log.error("** BUG ** unexpected action: %d" % action_id) def action_playlist_item(self, action_id, positions, ids): if action_id == IA_REMOVE.id: positions.sort() positions.reverse() try: for pos in positions: self._mp_t.DelTrack(pos) except DBusException, e: log.warning("dbus error: %s" % e) return elif action_id == IA_JUMP.id: self.__jump_to(positions[0]) else: log.error("** BUG ** unexpected action: %d" % action_id) # ========================================================================= # request interface # ========================================================================= def request_playlist(self, reply): if not self.__can_tracklist: reply.send() return # TODO: very slow for SongBird, should be async tracks = self.__get_tracklist() for track in tracks: id, info = self.__track2info(track) artist = info.get(INFO_ARTIST, "???") title = info.get(INFO_TITLE, "???") name = "%s - %s" % (artist, title) reply.ids.append(id) reply.names.append(name) reply.item_actions = self.__playlist_actions reply.send() # ========================================================================= # internal methods (may be overridden by subclasses to fix MPRIS issues) # ========================================================================= def _poll_status(self): """Poll player status information. Some MPRIS players do not notify about all status changes, so that status must be polled. Subclasses may call this method for that purpose. """ try: self._mp_p.GetStatus(reply_handler=self._notify_status, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def _poll_volume(self): try: self._mp_p.VolumeGet(reply_handler=self._notify_volume, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def _poll_progress(self): try: self._mp_p.PositionGet(reply_handler=self._notify_progress, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def _notify_track(self, track): log.debug("track: %s" % str(track)) id, info = self.__track2info(track) self.__progress_max = info.get(INFO_LENGTH, 0) # for update_progress() img = track.get("arturl") if not img or not img.startswith("file:"): img = self.find_image(id) self.update_item(id, info, img) try: self._mp_t.GetCurrentTrack(reply_handler=self._notify_position, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def _notify_status(self, status): log.debug("status: %s " % str(status)) if status[0] == STATUS_STOPPED: self._playing = PLAYBACK_STOP elif status[0] == STATUS_PAUSED: self._playing = PLAYBACK_PAUSE elif status[0] == STATUS_PLAYING: self._playing = PLAYBACK_PLAY else: log.warning("unknown play state (%s), assume playing)" % status[0]) self._playing = PLAYBACK_PLAY self.update_playback(self._playing) self._shuffle = status[1] # remember for toggle_shuffle() self.update_shuffle(self._shuffle) self._repeat = status[2] or status[3] # for toggle_repeat() self.update_repeat(self._repeat) def _notify_tracklist_change(self, new_len): log.debug("tracklist change") try: self._mp_t.GetCurrentTrack(reply_handler=self._notify_position, error_handler=self._dbus_error) except DBusException, e: log.warning("dbus error: %s" % e) def _notify_position(self, position): log.debug("tracklist pos: %d" % position) self.update_position(position) def _notify_volume(self, volume): self.__volume = volume # remember for ctrl_volume() self.update_volume(volume) def _notify_progress(self, progress): self.__progress_now = progress // 1000 # remember for ctrl_seek() self.update_progress(self.__progress_now, self.__progress_max) def _notify_caps(self, caps): self.__can_play = caps & CAN_PLAY != 0 self.__can_pause = caps & CAN_PAUSE != 0 self.__can_next = caps & CAN_GO_NEXT != 0 self.__can_prev = caps & CAN_GO_PREV != 0 self.__can_seek = caps & CAN_SEEK != 0 self.__can_tracklist = caps & CAN_HAS_TRACKLIST != 0 # ========================================================================= # internal methods (private) # ========================================================================= def __get_tracklist(self): """Get a list of track dicts of all tracks in the tracklist.""" try: length = self._mp_t.GetLength() except DBusException, e: log.warning("dbus error: %s" % e) length = 0 if length == 0: return [] tracks = [] for i in range(0, length): try: tracks.append(self._mp_t.GetMetadata(i)) except DBusException, e: log.warning("dbus error: %s" % e) return [] return tracks def __track2info(self, track): """Convert an MPRIS meta data dict to a Remuco info dict.""" id = track.get("location", "None") info = {} title_alt = os.path.basename(id) title_alt = os.path.splitext(title_alt)[0] info[INFO_TITLE] = track.get("title", title_alt) info[INFO_ARTIST] = track.get("artist", "") info[INFO_ALBUM] = track.get("album", "") info[INFO_GENRE] = track.get("genre", "") info[INFO_YEAR] = track.get("year", "") info[INFO_LENGTH] = track.get("time", track.get("mtime", 0) // 1000) info[INFO_RATING] = track.get("rating", 0) return (id, info) def __jump_to(self, position): """Jump to a position in the tracklist. MPRIS has no such method, this is a workaround. Unfortunately it behaves not as expected on dynamic playlists. """ tracks = self.__get_tracklist() if position >= len(tracks): return uris = [] for track in tracks[position:]: uris.append(track.get("location", "there must be a location")) positions = range(position, len(tracks)) self.action_playlist_item(IA_REMOVE.id, positions, uris) self.action_files(IA_APPEND_PLAY.id, [], uris) # ========================================================================= # dbus reply handler (may be reused by subclasses) # ========================================================================= def _dbus_error(self, error): """ DBus error handler.""" if self._mp_p is None: return # do not log errors when not stopped already log.warning("DBus error: %s" % error) def _dbus_ignore(self): """ DBus reply handler for methods without reply.""" pass remuco-source-0.9.6/base/module/remuco/net.py0000644000000000000000000004315411700415064021112 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import socket import struct import time import bluetooth import gobject from remuco import log from remuco import message from remuco import report from remuco import serial from remuco.data import ClientInfo from remuco.remos import zc_publish, zc_unpublish def build_message(id, serializable): """Create a message ready to send on a socket. @param id: message id @param serializable: message content (object of type Serializable) @return: the message as a binary string or None if serialization failed """ # This is not included in ClientConnection.send() because if there are # multiple clients, each client would serialize the data to send again. # Using this method, a message can be serialized once and send to many # clients. if serializable is not None: ba = serial.pack(serializable) if ba is None: log.warning("failed to serialize (msg-id %d)" % id) return None else: ba = "" header = struct.pack("!hi", id, len(ba)) return "%s%s" % (header, ba) class ReceiveBuffer(object): """ A box to pool some receive buffer related data. """ def __init__(self): self.header = "" self.data = "" self.rest = 0 class ClientConnection(object): IO_HEADER_LEN = 6 IO_MSG_MAX_SIZE = 10240 # prevent DOS IO_PREFIX = '\xff\xff\xff\xff' IO_SUFFIX = '\xfe\xfe\xfe\xfe' IO_PROTO_VERSION = '\x0a' IO_HELLO = "%s%s%s" % (IO_PREFIX, IO_PROTO_VERSION, IO_SUFFIX) # hello msg def __init__(self, sock, addr, clients, pinfo_msg, msg_handler_fn, c_type): self.__sock = sock self.__addr = addr self.__clients = clients self.__pinfo_msg = pinfo_msg self.__msg_handler_fn = msg_handler_fn self.__conn_type = c_type # client info self.info = ClientInfo() self.__psave = False # the following fields are used for iterative receiving on message data # see io_recv() and io_recv_buff() self.__rcv_buff_header = ReceiveBuffer() self.__rcv_buff_data = ReceiveBuffer() self.__rcv_msg_id = message.IGNORE self.__rcv_msg_size = 0 self.__snd_buff = "" # buffer for outgoing data # source IDs for various events self.__sids = [ gobject.io_add_watch(self.__sock, gobject.IO_IN, self.__io_recv), gobject.io_add_watch(self.__sock, gobject.IO_ERR, self.__io_error), gobject.io_add_watch(self.__sock, gobject.IO_HUP, self.__io_hup) ] self.__sid_out = 0 log.debug("send 'hello' to %s" % self) self.send(ClientConnection.IO_HELLO) def __str__(self): return str(self.__addr) #========================================================================== # io #========================================================================== def __recv_buff(self, rcv_buff): """ Receive some data and put it into the given ReceiveBuffer. @param rcv_buff: the receive buffer to put received data into @return: true if some data has been received, false if an error occurred """ try: log.debug("try to receive %d bytes" % rcv_buff.rest) data = self.__sock.recv(rcv_buff.rest) except socket.timeout, e: # TODO: needed? log.warning("connection to %s broken (%s)" % (self, e)) self.disconnect() return False except socket.error, e: log.warning("connection to %s broken (%s)" % (self, e)) self.disconnect() return False received = len(data) log.debug("received %d bytes" % received) if received == 0: log.warning("connection to %s broken (no data)" % self) self.disconnect() return False rcv_buff.data = "%s%s" % (rcv_buff.data, data) rcv_buff.rest -= received return True def __io_recv(self, fd, cond): """ GObject callback function (when there is data to receive). """ log.debug("data from client %s available" % self) # --- init buffers on new message ------------------------------------- if (self.__rcv_buff_header.rest + self.__rcv_buff_data.rest == 0): self.__rcv_msg_id = message.IGNORE self.__rcv_msg_size = 0 # will be set later self.__rcv_buff_header.data = "" self.__rcv_buff_header.rest = ClientConnection.IO_HEADER_LEN self.__rcv_buff_data.data = "" self.__rcv_buff_data.rest = 0 # will be set later # --- receive header -------------------------------------------------- if self.__rcv_buff_header.rest > 0: ok = self.__recv_buff(self.__rcv_buff_header) if not ok: return False if self.__rcv_buff_header.rest > 0: return True # more data to read, come back later id, size = struct.unpack('!hi', self.__rcv_buff_header.data) if size > ClientConnection.IO_MSG_MAX_SIZE: log.warning("msg from %s too big (%d bytes)" % (self, size)) self.disconnect() return False log.debug("incoming msg: %d, %dB" % (id, size)) self.__rcv_buff_data.rest = size self.__rcv_msg_id, self.__rcv_msg_size = id, size if size > 0: return True # more data to read, come back later # --- receive content ------------------------------------------------- if self.__rcv_buff_data.rest > 0: ok = self.__recv_buff(self.__rcv_buff_data) if not ok: return False if self.__rcv_buff_data.rest > 0: return True # more data to read, come back later # --- message complete ------------------------------------------------ msg_id = self.__rcv_msg_id msg_data = self.__rcv_buff_data.data log.debug("incoming msg ") if msg_id == message.IGNORE: log.debug("received ignore msg (probably a ping)") elif msg_id == message.CONN_SLEEP: self.__psave = True elif msg_id == message.CONN_WAKEUP: self.__psave = False self.__msg_handler_fn(self, message.PRIV_INITIAL_SYNC, None) elif msg_id == message.CONN_CINFO: log.debug("received client info from %s" % self) serial.unpack(self.info, msg_data) if not self in self.__clients: # initial client info device = self.info.device.copy() device["conn"] = self.__conn_type report.log_device(device) self.__clients.append(self) log.debug("sending player info to %s" % self) self.send(self.__pinfo_msg) self.__msg_handler_fn(self, message.PRIV_INITIAL_SYNC, None) else: self.__msg_handler_fn(self, msg_id, msg_data) return True def __io_error(self, fd, cond): """ GObject callback function (when there is an error). """ log.warning("connection to client %s broken" % self) self.disconnect() return False def __io_hup(self, fd, cond): """ GObject callback function (when other side disconnected). """ log.info("client %s disconnected" % self) self.disconnect() return False def __io_send(self, fd, cond): """ GObject callback function (when data can be written). """ if not self.__snd_buff: self.__sid_out = 0 return False log.debug("try to send %d bytes to %s" % (len(self.__snd_buff), self)) try: sent = self.__sock.send(self.__snd_buff) except socket.error, e: log.warning("failed to send data to %s (%s)" % (self, e)) self.disconnect() return False log.debug("sent %d bytes" % sent) if sent == 0: log.warning("failed to send data to %s" % self) self.disconnect() return False self.__snd_buff = self.__snd_buff[sent:] if not self.__snd_buff: self.__sid_out = 0 return False else: return True def send(self, msg): """Send a message to the client. @param msg: complete message (incl. ID and length) in binary format (net.build_message() is your friend here) @see: net.build_message() """ if msg is None: log.error("** BUG ** msg is None") return if self.__sock is None: log.debug("cannot send message to %s, already disconnected" % self) return if self.__psave: log.debug("%s is in sleep mode, send nothing" % self) return self.__snd_buff = "%s%s" % (self.__snd_buff, msg) # if not already trying to send data .. if self.__sid_out == 0: # .. do it when it is possible: self.__sid_out = gobject.io_add_watch(self.__sock, gobject.IO_OUT, self.__io_send) def disconnect(self, remove_from_list=True, send_bye_msg=False): """ Disconnect the client. @keyword remove_from_list: whether to remove the client from the client list or not (default is true) @keyword send_bye_msg: whether to send a bye message before disconnecting """ # send bye message if send_bye_msg and self.__sock is not None: log.info("send 'bye' to %s" % self) msg = build_message(message.CONN_BYE, None) sent = 0 retry = 0 while sent < len(msg) and retry < 10: try: sent += self.__sock.send(msg) except socket.error, e: log.warning("failed to send 'bye' to %s (%s)" % (self, e)) break time.sleep(0.02) retry += 1 if sent < len(msg): log.warning("failed to send 'bye' to %s" % self) else: # give client some time to close connection: time.sleep(0.1) # disconnect log.debug("disconnect %s" % self) if remove_from_list and self in self.__clients: self.__clients.remove(self) for sid in self.__sids: gobject.source_remove(sid) self.__sids = () if (self.__sid_out > 0): gobject.source_remove(self.__sid_out) self.__sid_out = 0 if self.__sock is not None: try: self.__sock.shutdown(socket.SHUT_RDWR) except socket.error, e: pass self.__sock.close() self.__sock = None class _Server(object): SOCKET_TIMEOUT = 2.5 def __init__(self, clients, pinfo, msg_handler_fn, config): """ Create a new server. @param clients: a list to add connected clients to @param pinfo: player info (type data.PlayerInfo) @param msg_handler_fn: callback function for passing received messages to @param config: adapter configuration """ self.__clients = clients self.__msg_handler_fn = msg_handler_fn self.__pinfo_msg = build_message(message.CONN_PINFO, pinfo) self.__sid = None self._pinfo = pinfo self._config = config self._sock = None # set up socket try: self._sock = self._create_socket() self._sock.settimeout(_Server.SOCKET_TIMEOUT) except (IOError, socket.error), e: # TODO: socket.error may be removed when 2.5 support is dropped log.error("failed to set up %s server (%s)" % (self._get_type(), e)) return log.info("created %s server" % self._get_type()) # watch socket self.__sid = gobject.io_add_watch(self._sock, gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP, self.__handle_io) #========================================================================== # io #========================================================================== def __handle_io(self, fd, condition): """ GObject callback function (when there is a socket event). """ if condition == gobject.IO_IN: try: log.debug("connection request from %s client" % self._get_type()) client_sock, addr = self._sock.accept() log.debug("connection request accepted") client_sock.setblocking(0) ClientConnection(client_sock, addr, self.__clients, self.__pinfo_msg, self.__msg_handler_fn, self._get_type()) except IOError, e: log.error("accepting %s client failed: %s" % (self._get_type(), e)) return True else: log.error("%s server socket broken" % self._get_type()) self.__sid = None return False def down(self): """ Shut down the server. """ if self.__sid is not None: gobject.source_remove(self.__sid) if self._sock is not None: log.debug("closing %s server socket" % self._get_type()) try: self._sock.shutdown(socket.SHUT_RDWR) except socket.error: pass self._sock.close() self._sock = None def _create_socket(self): """ Create the server socket. @return: a socket object """ raise NotImplementedError #========================================================================== # miscellaneous #========================================================================== def _get_type(self): """Get server type name.""" raise NotImplementedError class BluetoothServer(_Server): UUID = "025fe2ae-0762-4bed-90f2-d8d778f020fe" def _create_socket(self): try: sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM) sock.bind(("", self._config.bluetooth_channel or bluetooth.PORT_ANY)) sock.listen(1) sock.settimeout(0.33) bluetooth.advertise_service(sock, self._pinfo.name, service_id=BluetoothServer.UUID, service_classes=[BluetoothServer.UUID, bluetooth.SERIAL_PORT_CLASS], profiles=[bluetooth.SERIAL_PORT_PROFILE]) except Exception, e: # bluez does not always convert its internal error into a # IOError-based BluetoothError, so we need to catch here everything # and convert internal Bluetooth errors to regular IO errors. if isinstance(e, IOError): raise e else: raise IOError(*e) return sock def down(self): if self._sock is not None: try: bluetooth.stop_advertising(self._sock) except bluetooth.BluetoothError, e: log.warning("failed to unregister bluetooth service (%s)" % e) super(BluetoothServer, self).down() def _get_type(self): return "bluetooth" class WifiServer(_Server): def _create_socket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('', self._config.wifi_port)) sock.listen(1) zc_publish(self._pinfo.name, sock.getsockname()[1]) return sock def _get_type(self): return "wifi" def down(self): zc_unpublish() super(WifiServer, self).down() remuco-source-0.9.6/base/module/remuco/remos.py0000644000000000000000000001637411700415064021455 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Module to abstract platform specific code.""" from __future__ import with_statement import os from os.path import join as opj import re import sys from remuco import log # ============================================================================= # platform detection # ============================================================================= linux = sys.platform.startswith("linux") windows = sys.platform.startswith("win") mac = sys.platform == "darwin" # ============================================================================= # helpers # ============================================================================= def _real_path(p): """Expand a path to a variable-free absolute path.""" return os.path.abspath(os.path.expanduser(os.path.expandvars(p))) # ============================================================================= # locations # ============================================================================= # media_dirs: # Maps some mimetypes to a list of locations which typically contain files # of a specific mimetype. For those mimetypes not mapped, `user_home` may # be used as a fallback. if linux: import xdg.BaseDirectory user_home = os.getenv("HOME") user_config_dir = xdg.BaseDirectory.xdg_config_home user_cache_dir = xdg.BaseDirectory.xdg_cache_home media_dirs = {} try: with open(opj(user_config_dir, "user-dirs.dirs")) as fp: _udc = fp.read() except IOError, e: log.warning("failed to load user dirs config (%s)" % e) media_dirs["audio"] = ["~/Music"] media_dirs["video"] = ["~/Videos"] else: m = re.search(r'XDG_MUSIC_DIR="([^"]+)', _udc) media_dirs["audio"] = [m and m.groups()[0] or "~/Music"] m = re.search(r'XDG_VIDEOS_DIR="([^"]+)', _udc) media_dirs["video"] = [m and m.groups()[0] or "~/Video"] elif windows: from win32com.shell import shell, shellcon user_home = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, 0, 0) user_config_dir = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA,0, 0) user_cache_dir = shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, 0, 0) media_dirs = {} media_dirs["audio"] = [shell.SHGetFolderPath(0, shellcon.CSIDL_MYMUSIC, 0, 0), shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_MUSIC, 0, 0)] media_dirs["video"] = [shell.SHGetFolderPath(0, shellcon.CSIDL_MYVIDEO, 0, 0), shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_VIDEO, 0, 0)] elif mac: raise NotImplementedError else: assert False # sanitize locations: for mime_type, dirs in list(media_dirs.items()): # list prevents iter/edit conflicts media_dirs[mime_type] = [_real_path(p) for p in dirs] media_dirs[mime_type] = [p for p in dirs if os.path.exists(p)] # ============================================================================= # user notifications # ============================================================================= if linux: import dbus from dbus.exceptions import DBusException def notify(title, text): """Notify the user that a new device has been loggend.""" try: bus = dbus.SessionBus() except DBusException, e: log.error("no dbus session bus (%s)" % e) return try: proxy = bus.get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") notid = dbus.Interface(proxy, "org.freedesktop.Notifications") except DBusException, e: log.error("failed to connect to notification daemon (%s)" % e) return try: caps = notid.GetCapabilities() except DBusException, e: return if not caps or "body-markup" not in caps: text = text.replace("", "") text = text.replace("", "") try: notid.Notify("Remuco", 0, "phone", title, text, [], {}, 15) except DBusException, e: log.warning("user notification failed (%s)" % e) return else: def notify(title, text): log.info("%s: %s" % (title, text)) # TODO: implementations for mac and win # ============================================================================= # zeroconf # ============================================================================= _ZC_TYPE = "_remuco._tcp" if linux: import dbus from dbus.mainloop.glib import DBusGMainLoop from dbus.exceptions import DBusException import gobject dbus.set_default_main_loop(DBusGMainLoop()) # Avahi DBus constants (defined here to prevent python-avahi dependency) _DBA_NAME = "org.freedesktop.Avahi" _DBA_INTERFACE_SERVER = _DBA_NAME + ".Server" _DBA_PATH_SERVER = "/" _DBA_INTERFACE_ENTRY_GROUP = _DBA_NAME + ".EntryGroup" _zc_group = None def zc_publish(player, port): """Publish a service for the given player at the given port.""" zc_unpublish() log.debug("publishing zeroconf service") try: bus = dbus.SystemBus() obj = bus.get_object(_DBA_NAME, _DBA_PATH_SERVER) server = dbus.Interface(obj, _DBA_INTERFACE_SERVER) obj = bus.get_object(_DBA_NAME, server.EntryGroupNew()) group = dbus.Interface(obj, _DBA_INTERFACE_ENTRY_GROUP) group.AddService(-1, -1, 0, "Remuco %s" % player, _ZC_TYPE, "local", "", port, "") group.Commit() except dbus.DBusException, e: log.warning("failed to publish zeroconf service (%s)" % e) group = None else: log.debug("published zeroconf service") global _zc_group _zc_group = group def zc_unpublish(): """Unpublish the previously published service.""" global _zc_group if _zc_group: try: _zc_group.Reset() except DBusException, e: log.warning("failed to unpublish zeroconf service (%s)" % e) _zc_group = None else: def zc_publish(player, port): log.warning("publishing zeroconf services not implemented on this OS") def zc_unpublish(): pass remuco-source-0.9.6/base/module/remuco/report.py0000644000000000000000000000753011700415064021635 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= """Remuco report handler.""" import httplib import os import os.path import urllib from remuco.config import DEVICE_FILE from remuco import dictool from remuco.remos import notify __HOST = "remuco.sourceforge.net" __LOC = "/cgi-bin/report" __DEVICE_FILE_COMMENT = """# Seen Remuco client devices. # # The information in this file is sent to remuco.sourceforge.net if you run # the tool 'remuco-report'. It is used to set up a list of Remuco compatible # mobile devices. # """ # Fields of a client device info to log. __FIELDS = ("name", "version", "conn", "utf8", "touch") def log_device(device): """Log a client device.""" device = dictool.dict_to_string(device, keys=__FIELDS) seen_devices = dictool.read_dicts_from_file(DEVICE_FILE, flat=True, keys=__FIELDS) if not device in seen_devices: notify("New Remuco Client", "Please run the tool remuco-report !") seen_devices.append(device) dictool.write_dicts_to_file(DEVICE_FILE, seen_devices, comment=__DEVICE_FILE_COMMENT) def __send_device(device): """Send a single device.""" print("sending %s" % device) params = urllib.urlencode(device) #print(params) headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} try: conn = httplib.HTTPConnection(__HOST) conn.request("POST", __LOC, params, headers) response = conn.getresponse() except IOError, e: return -1, str(e) response.read() # needed ? conn.close() return response.status, response.reason def __send_devices(): """Send all seen devices. @return: True if sending was successful, False if something failed """ device_list = dictool.read_dicts_from_file(DEVICE_FILE, flat=False, keys=__FIELDS) ok = True for device in device_list: # add a simple watchword marking this report as a real one device["ww"] = "sun_is_shining" status, reason = __send_device(device) if status != httplib.OK: print("-> failed (%s - %s)" % (status, reason)) if status == httplib.NOT_FOUND: print(" the submission link I'm using may be outdated") ok = False else: print("-> ok") return ok if __name__ == '__main__': import sys if len(sys.argv) == 2: if sys.argv[1] == "send": ok = __send_devices() if ok: sys.exit(os.EX_OK) else: sys.exit(os.EX_TEMPFAIL) elif sys.argv[1] == "dump": devices = dictool.read_dicts_from_file(DEVICE_FILE, flat=True) for dev in devices: print(dev) sys.exit(os.EX_OK) sys.exit(os.EX_USAGE) remuco-source-0.9.6/base/module/remuco/serial.py0000644000000000000000000003246311700415064021604 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import inspect import struct import array from remuco import log TYPE_Y = 1 TYPE_I = 2 TYPE_B = 3 TYPE_S = 4 TYPE_AY = 5 TYPE_AI = 6 TYPE_AS = 7 TYPE_L = 8 TYPE_N = 9 TYPE_AN = 10 TYPE_AB = 11 TYPE_AL = 12 class Bin: NET_ENCODING = "UTF-8" # codec for data exchanged with clients NET_ENCODING_ALT = ("UTF-8", "UTF8", "utf-8", "utf8") # synonyms HOST_ENCODING = NET_ENCODING # will be updated with value from config file def __init__(self, buff=None): self.__data = buff or array.array('c') self.__off = 0 def get_buff(self): if isinstance(self.__data, basestring): return self.__data elif isinstance(self.__data, array.array): return self.__data.tostring() else: log.error("** BUG ** unexpected buffer type") def read_boolean(self): b = self.read_byte() if b == 0: return False else: return True def read_byte(self): y = struct.unpack_from('b', self.__data, offset=self.__off)[0] self.__off += 1 return y def read_short(self): n = struct.unpack_from('!h', self.__data, offset=self.__off)[0] self.__off += 2 return n def read_int(self): i = struct.unpack_from('!i', self.__data, offset=self.__off)[0] self.__off += 4 return i def read_long(self): l = struct.unpack_from('!q', self.__data, offset=self.__off)[0] self.__off += 8 return l def read_string(self): """ Read a string. The read raw string will be converted from Bin.NET_ENCODING to Bin.HOST_ENCODING. """ s = self.__read_string() if Bin.HOST_ENCODING not in Bin.NET_ENCODING_ALT: try: s = unicode(s, Bin.NET_ENCODING).encode(Bin.HOST_ENCODING) except UnicodeDecodeError, e: log.warning("could not decode '%s' with codec %s (%s)" % (s, Bin.NET_ENCODING, e)) except UnicodeEncodeError, e: log.warning("could not encode '%s' with codec %s (%s)" % (s, Bin.HOST_ENCODING, e)) return s def read_type(self, expected): type = self.read_byte() if type != expected: log.warning("bin data malformed (expected type %d, have %d)" % (expected, type)) return False else: return True def read_array_boolean(self): return self.__read_array(self.read_boolean) def read_array_byte(self): return self.__read_array(self.read_byte) def read_array_short(self): return self.__read_array(self.read_short) def read_array_int(self): return self.__read_array(self.read_int) def read_array_long(self): return self.__read_array(self.read_long) def read_array_string(self): return self.__read_array(self.read_string) def __read_string(self): """ Read a string as it is, i.e. without any codec conversion. """ l = self.read_short() s = struct.unpack_from('%ds' % l, self.__data, offset=self.__off)[0] self.__off += l return s def __read_array(self, fn_read_element): num = self.read_int() a = [] for i in range(num): a.append(fn_read_element()) return a def get_unused_data(self): return len(self.__data) - self.__off def write_type(self, type): self.write_byte(type) def write_boolean(self, b): if b: self.write_byte(1) else: self.write_byte(0) def write_byte(self, y): if y is None: y = 0 self.__data.extend(' ' * 1) struct.pack_into('b', self.__data, self.__off, y) self.__off += 1 def write_short(self, n): if n is None: n = 0 self.__data.extend(' ' * 2) struct.pack_into('!h', self.__data, self.__off, n) self.__off += 2 def write_int(self, i): if i is None: i = 0 self.__data.extend(' ' * 4) struct.pack_into('!i', self.__data, self.__off, i) self.__off += 4 def write_long(self, l): if l is None: l = 0 self.__data.extend(' ' * 8) struct.pack_into('!q', self.__data, self.__off, l) self.__off += 8 def write_string(self, s): """ Write a string. If the string is a unicode string, it will be encoded as a normal string in Bin.NET_ENCODING. If it already is a normal string it will be converted from Bin.HOST_ENCODING to Bin.NET_ENCODING. """ if s is None: self.__write_string(s) return if isinstance(s, unicode): try: s = s.encode(Bin.NET_ENCODING) except UnicodeEncodeError, e: log.warning("could not encode '%s' with codec %s (%s)" % (s, Bin.NET_ENCODING, e)) s = str(s) elif Bin.HOST_ENCODING not in Bin.NET_ENCODING_ALT: log.debug("convert '%s' from %s to %s" % (s, Bin.HOST_ENCODING, Bin.NET_ENCODING)) try: s = unicode(s, Bin.HOST_ENCODING).encode(Bin.NET_ENCODING) except UnicodeDecodeError, e: log.warning("could not decode '%s' with codec %s (%s)" % (s, Bin.HOST_ENCODING, e)) except UnicodeEncodeError, e: log.warning("could not encode '%s' with codec %s (%s)" % (s, Bin.NET_ENCODING, e)) self.__write_string(s) def write_array_boolean(self, ba): self.__write_array(ba, self.write_boolean) def write_array_byte(self, ba): if isinstance(ba, str): # byte sequences often come as strings self.__write_string(ba, len_as_int=True) else: self.__write_array(ba, self.write_byte) def write_array_short(self, na): self.__write_array(na, self.write_short) def write_array_int(self, ia): self.__write_array(ia, self.write_int) def write_array_long(self, ia): self.__write_array(ia, self.write_long) def write_array_string(self, sa): self.__write_array(sa, self.write_string) def __write_string(self, s, len_as_int=False): """ Write a string. The string is written as is, i.e. there is no codec conversion. """ if s is None: s = "" if not isinstance(s, basestring): s = str(s) l = len(s) if len_as_int: self.write_int(l) else: self.write_short(l) self.__data.extend(' ' * l) struct.pack_into('%ds' % l, self.__data, self.__off, s) self.__off += l def __write_array(self, a, fn_element_write): if a is None: l = 0 else: l = len(a) self.write_int(l) for i in range(l): fn_element_write(a[i]) class Serializable(object): def get_fmt(self): raise NotImplementedError def get_data(self): raise NotImplementedError def set_data(self, data): raise NotImplementedError def pack(serializable): fmt = serializable.get_fmt() data = serializable.get_data() if len(fmt) != len(data): log.error("** BUG ** format string and data differ in length") return None #log.debug("data to pack: %s" % str(data)) bin = Bin() try: for i in range(0,len(fmt)): type = fmt[i] bin.write_byte(type) if type == TYPE_Y: bin.write_byte(data[i]) elif type == TYPE_B: bin.write_boolean(data[i]) elif type == TYPE_N: bin.write_short(data[i]) elif type == TYPE_I: bin.write_int(data[i]) elif type == TYPE_L: bin.write_long(data[i]) elif type == TYPE_S: bin.write_string(data[i]) elif type == TYPE_AB: bin.write_array_boolean(data[i]) elif type == TYPE_AY: bin.write_array_byte(data[i]) elif type == TYPE_AN: bin.write_array_short(data[i]) elif type == TYPE_AI: bin.write_array_int(data[i]) elif type == TYPE_AL: bin.write_array_long(data[i]) elif type == TYPE_AS: bin.write_array_string(data[i]) else: log.error("** BUG ** unknown type (%d) in format string" % type) return None except struct.error, e: log.exception("** BUG ** %s" % e) return None return bin.get_buff() def unpack(serializable, bytes): """ Deserialize a Serializable. @param serializable: the Serializable to apply the binary data to (may be a class, in which case a new instance of this class is created) @param bytes: binary data (serialized Serializable) @return: 'serializable' itself if it is an instance of Serializable, a new instance of 'serializable' if it is a class or None if an error occurred """ if inspect.isclass(serializable): serializable = serializable() fmt = serializable.get_fmt() if fmt and not bytes: log.warning("there is no data to unpack") return None data = [] bin = Bin(buff=bytes) try: for type in fmt: if not bin.read_type(type): return None if type == TYPE_Y: data.append(bin.read_byte()) elif type == TYPE_B: data.append(bin.read_boolean()) elif type == TYPE_N: data.append(bin.read_short()) elif type == TYPE_I: data.append(bin.read_int()) elif type == TYPE_L: data.append(bin.read_long()) elif type == TYPE_S: data.append(bin.read_string()) elif type == TYPE_AB: data.append(bin.read_array_boolean()) elif type == TYPE_AY: data.append(bin.read_array_byte()) elif type == TYPE_AN: data.append(bin.read_array_short()) elif type == TYPE_AI: data.append(bin.read_array_int()) elif type == TYPE_AL: data.append(bin.read_array_long()) elif type == TYPE_AS: data.append(bin.read_array_string()) else: log.warning("bin data malformed (unknown data type: %d)" % type) return None except struct.error, e: log.warning("bin data malformed (%s)" % e) return None unused = bin.get_unused_data() if unused: log.warning("there are %d unused bytes" % unused) return None serializable.set_data(data) #log.debug("unpacked data : %s" % str(data)) return serializable remuco-source-0.9.6/base/module/remuco/testshell.py0000644000000000000000000000457611700415064022340 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2009 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import signal import gobject import inspect _paref = None _cmdlist = None def setup(adapter): global _paref, _cmdlist _paref = adapter _cmdlist = [getattr(adapter, f) for f in dir(adapter) if f.startswith("ctrl_")] signal.signal(signal.SIGHUP, handler) def handler(signum, frame): """Ugly handler to call PlayerAdapter's functions and test functionality. """ signal.signal(signal.SIGHUP, signal.SIG_IGN) #ignore further SIGHUPs if _paref is not None: print('Which function should I call?') for count, f in enumerate(_cmdlist): parms, _, _, _ = inspect.getargspec(f) showparms = '' if parms.__len__() > 1: showparms = parms[1:] #ignore 'self' print('[%d] %s (%s)' % (count, f.__name__, showparms)) try: command = raw_input('Choice: ').split(' ') idx = int(command[0]) args = command[1:] #cast what seems to be integer for i in range(len(args)): try: args[i] = int(args[i]) except ValueError: pass if idx >= 0 and idx < _cmdlist.__len__(): gobject.idle_add(_cmdlist[idx], *args) else: print('Invalid function') except ValueError: pass signal.signal(signal.SIGHUP, handler) #be ready for the next calls remuco-source-0.9.6/base/module/test/testadapter.py0000644000000000000000000000407211700415064022325 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest import gobject import sys import remuco.log from remuco import PlayerAdapter class AdapterTest(unittest.TestCase): def setUp(self): self.__ml = gobject.MainLoop() ia = remuco.ItemAction("ia_l", multiple=True) logarg = "--remuco-log-stdout" if not logarg in sys.argv: sys.argv.append(logarg) self.__pa = PlayerAdapter("unittest", playback_known=False, volume_known=True, repeat_known=True, shuffle_known=False, progress_known=True, max_rating=3, mime_types=["audio"], poll=1, file_actions=[ia]) #self.__pa.config.log_level = remuco.log.DEBUG #self.__pa.config.log_level = remuco.log.INFO self.__pa.config.log_level = remuco.log.WARNING def test_adapter(self): self.__pa.start() gobject.timeout_add(4000, self.__stop) self.__ml.run() def __stop(self): self.__pa.stop() self.__ml.quit() if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.test_adapter'] unittest.main()remuco-source-0.9.6/base/module/test/testall.py0000644000000000000000000000251011700415064021450 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest import remuco.log #remuco.log.set_level(remuco.log.DEBUG) #remuco.log.set_level(remuco.log.INFO) remuco.log.set_level(remuco.log.WARNING) from testdictool import DicToolTest from testserial import SerializationTest from testnet import ServerTest from testfiles import FilesTest from testadapter import AdapterTest if __name__ == "__main__": unittest.main()remuco-source-0.9.6/base/module/test/testdictool.py0000644000000000000000000000432711700415064022345 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest from remuco import dictool class DicToolTest(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_it(self): keys = ("a", "c", "b") dic1 = { "a": "1:d", "b": "2", "d": "4", "c": "3" } dic3 = { "a": "1", "b": "2,0", "d": "4", "c": "3" } flat = dictool.dict_to_string(dic1) dic2 = dictool.string_to_dict(flat) assert dic1 == dic2 flat = dictool.dict_to_string(dic1, keys=keys) assert flat == "a:1:d,c:3,b:2" dic2 = dictool.string_to_dict(flat) assert dic1 != dic2 flat = dictool.dict_to_string(dic3, keys=keys) assert flat == "a:1,c:3,b:2_0" l1 = [dic1,dic2] dictool.write_dicts_to_file("/var/tmp/dictest", l1, comment="# hallo") l2 = dictool.read_dicts_from_file("/var/tmp/dictest") assert l1 == l2 dictool.write_dicts_to_file("/var/tmp/dictest", [dic1,dic2,dic3,flat], comment="# hallo", keys=["a"]) l = dictool.read_dicts_from_file("/var/tmp/dictest") l = dictool.read_dicts_from_file("/var/tmp/non_existent") if __name__ == "__main__": unittest.main()remuco-source-0.9.6/base/module/test/testfiles.py0000644000000000000000000000434211700415064022007 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest from remuco.files import FileSystemLibrary class FilesTest(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def __test_path(self, fs, path, depth, limit): nested, ids, names = fs.get_level(path) #print("%spath : %s" % (depth, path)) #if nested: # print("%snested : %s" % (depth, nested)) #if ids: # print("%sids : %s" % (depth, ids)) #if names: # print("%snames : %s" % (depth, names)) if len(depth) == limit * 2: return if path is None: path = [] for sub in nested: self.__test_path(fs, path + [sub], depth + " ", limit) def test_files(self): #print("") fs = FileSystemLibrary(None, ["audio","video"], False, True) self.__test_path(fs, None, "", limit=0) self.__test_path(fs, [], "", limit=2) fs = FileSystemLibrary([ "/home", "/nonexistent", "auto" ], ["audio/mp3", "video/mp4", "application/x-iso9660-image"], False, True) self.__test_path(fs, [], "", limit=3) if __name__ == "__main__": unittest.main()remuco-source-0.9.6/base/module/test/testnet.py0000644000000000000000000000347511700415064021501 0ustar rootroot00000000000000# ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest import gobject from remuco.data import PlayerInfo from remuco.net import WifiServer, BluetoothServer from remuco.config import Config class ServerTest(unittest.TestCase): def setUp(self): self.__ml = gobject.MainLoop() self.__pi = PlayerInfo("xxx", 0, 0, None, ["1", "2"]) self.__config = Config("unittest") def test_wifi(self): s = WifiServer([], self.__pi, None, self.__config) gobject.timeout_add(2000, self.__stop, s) self.__ml.run() def test_bluetooth(self): s = BluetoothServer([], self.__pi, None, self.__config) gobject.timeout_add(2000, self.__stop, s) self.__ml.run() def __stop(self, s): s.down() self.__ml.quit() if __name__ == "__main__": unittest.main()remuco-source-0.9.6/base/module/test/testserial.py0000644000000000000000000001622711700415064022171 0ustar rootroot00000000000000# -*- coding: UTF-8 -*- # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= import unittest import remuco from remuco import data from remuco import serial class _SerialzableClass(remuco.serial.Serializable): def __init__(self): self.b = None self.y = None self.n = None self.i = None self.l = None self.s1 = None self.s2 = None self.ba = None self.ya = None self.na = None self.ia = None self.la = None self.sa1 = None self.sa2 = None def __eq__(self, o): if self.b != o.b: print("b differs") return False if self.y != o.y: print("y differs") return False if self.n != o.n: print("n differs") return False if self.i != o.i: print("i differs") return False if self.l != o.l: print("l differs") return False if self.s1 != o.s1: print("s1 differs") return False if self.s2 != o.s2: print("s2 differs") return False if self.ba != o.ba: print("ba differs") return False if self.ya != o.ya: print("ya differs") return False if self.na != o.na: print("na differs") return False if self.ia != o.ia: print("ia differs") return False if self.la != o.la: print("la differs") return False if self.sa1 != o.sa1: print("sa1 differs") return False if self.sa2 != o.sa2: print("sa2 differs") return False return True def init(self): self.b = True self.y = 55 self.n = 4 << 10 self.i = 4 << 20 self.l = 3 << 40 self.s1 = "dfödas" self.s2 = "" self.ba = [ False, True, False ] self.ya1 = "bytes as string" self.ya2 = [ 1, 127, -128 ] self.na = [ 2 << 10 ] self.ia1 = [ 1 << 20, 2 << 20 ] self.ia2 = None self.la = [ 5 << 40, 6 << 50 ] self.sa1 = [ "1", "2éü+", None , "" ] self.sa2 = [] def get_fmt(self): return (serial.TYPE_B, serial.TYPE_Y, serial.TYPE_N, serial.TYPE_I, serial.TYPE_L, serial.TYPE_S, serial.TYPE_S, serial.TYPE_AB, serial.TYPE_AY, serial.TYPE_AY, serial.TYPE_AN, serial.TYPE_AI, serial.TYPE_AI, serial.TYPE_AL, serial.TYPE_AS, serial.TYPE_AS) def get_data(self): return (self.b, self.y, self.n, self.i, self.l, self.s1, self.s2, self.ba, self.ya1, self.ya2, self.na, self.ia1, self.ia2, self.la, self.sa1, self.sa2) def set_data(self, data): self.b, self.y, self.n, self.i, self.l, \ self.s1, self.s2, \ self.ba, self.ya1, self.ya2, self.na, self.ia1, self.ia2, self.la, \ self.sa1, self.sa2 = data class SerializationTest(unittest.TestCase): def __serialize_and_dump(self, ser): print("--> serializable:\n%s" % ser) bindata = serial.pack(ser) print("--> binary data:") out = "" counter = 0 for byte in bindata: counter += 1 out = "%s %02X" % (out, ord(byte)) if counter % 32 == 0: out = "%s\n" % out print(out) return bindata def test_serialize_playerinfo(self): #print("") ia = remuco.ItemAction("ia_l", multiple=True) pi = data.PlayerInfo("dings", 123, 4, [ia], ["sm1", "sm2"]) #self.__serialize(pi) serial.pack(pi) def test_serialize_itemlist(self): #print("") path = [ "path", "to" ] nested = [ "n1", "n2" ] ids = ["id1", "id2", "id3" ] names = [ "na1", "na2", "na3" ] ia1 = remuco.ItemAction("ia1_l", multiple=True) ia2 = remuco.ItemAction("ia2_l", multiple=False) ias = [ ia1, ia2 ] la1 = remuco.ListAction("la1_l") las = [ la1 ] il = data.ItemList(1, path, nested, ids, names, 0, 1, 2, ias, las) #self.__serialize(il) serial.pack(il) # --------------------------------------------------------------------- path = [ ] nested = [ ] ids = None names = [ "na1", "na2", "na3" ] ia1 = remuco.ItemAction("ia1_l", multiple=True) ia2 = remuco.ItemAction("ia2_l", multiple=False) ias = [ ia1, ia2 ] #la1 = remuco.ListAction("la1_l") #las = [ la1 ] las = None il = data.ItemList(2, path, nested, ids, names, 0, 1, 2, ias, las) #self.__serialize(il) serial.pack(il) def test_serialize_deserialize(self): sc1 = _SerialzableClass() sc1.init() #bindata = self.__serialize(sc1) bindata = serial.pack(sc1) self.assertFalse(bindata is None) sc2 = _SerialzableClass() serial.unpack(sc2, bindata) self.assertFalse(sc2.sa1 is None) self.assertTrue(len(sc2.sa1) > 2) self.assertEquals(sc2.sa1[2], "") # None becomes empty string sc2.sa1[2] = None self.assertEquals(sc2.ia2, []) # None becomes empty list sc2.ia2 = None self.assertEquals(sc1, sc2) sc3 = serial.unpack(_SerialzableClass, "%strash" % bindata) self.assertTrue(sc3 is None) sc3 = serial.unpack(_SerialzableClass, "df") self.assertTrue(sc3 is None) sc3 = serial.unpack(_SerialzableClass(), "dfäsadfasd") self.assertTrue(sc3 is None) sc3 = serial.unpack(_SerialzableClass, "") self.assertTrue(sc3 is None) sc3 = serial.unpack(_SerialzableClass(), None) self.assertTrue(sc3 is None) if __name__ == '__main__': unittest.main() remuco-source-0.9.6/base/scripts/remuco-report0000644000000000000000000000765011700415064021411 0ustar rootroot00000000000000#!/bin/sh # ============================================================================= # # Remuco - A remote control system for media players. # Copyright (C) 2006-2010 by the Remuco team, see AUTHORS. # # This file is part of Remuco. # # Remuco 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. # # Remuco 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 Remuco. If not, see . # # ============================================================================= # ----------------------------------------------------------------------------- # functions # ----------------------------------------------------------------------------- message() { MPID="" if [ "$UI" = "ZENI" ] ; then if [ -z "$2" ] ; then zenity --info --title="Remuco Report" --text="$1" else zenity --info --title="Remuco Report" --text="$1" & MPID=$! fi elif [ "$UI" = "KDIA" ] ; then if [ -z "$2" ] ; then kdialog --title="Remuco Report" --msgbox="$1" else kdialog --title="Remuco Report" --msgbox="$1" & MPID=$! fi else echo $1 echo fi } # ----------------------------------------------------------------------------- # constants # ----------------------------------------------------------------------------- DEVICE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/remuco/devices" if [ -n "`which zenity`" ] ; then UI="ZENI" elif [ -n "`which kdialog`" ] ; then UI="KDIA" else UI="TERM" fi #UI="ZENI" # ----------------------------------------------------------------------------- # here we go # ----------------------------------------------------------------------------- DATA=`python -m remuco.report dump` MSG_NO_DATA=\ "Until now no client devices have been logged on this computer. There is "\ "nothing to report.\n\nPlease try again later, once a Remuco client has "\ "connected to this computer. Thanks!" if [ -z "$DATA" ] ; then message "$MSG_NO_DATA" exit fi MSG_INTRO=\ "This tool sends the names of seen Remuco client devices to "\ "remuco.sourceforge.net. It is a kind of survey to compile a list of Remuco "\ "compatible devices.\n\nTHE FOLLOWING INFORMATION WILL BE SUBMITTED:" if [ "$UI" = "ZENI" ] ; then TEXT="$MSG_INTRO\n\n$DATA\n\nPress OK to submit this report data now." zenity --question --title="Remuco Report" --text="$TEXT" [ $? = 0 ] || exit elif [ "$UI" = "KDIA" ] ; then TEXT="$MSG_INTRO\n\n$DATA\n\nDo you want to submit this data now?" kdialog --title "Remuco Report" --yesno "$TEXT" [ $? = 0 ] || exit else echo "====================================================================" echo "$MSG_INTRO" echo echo "$DATA" echo echo "Do you want to submit this data now? [Y/n]" read REPLY [ -z "$REPLY" -o "$REPLY" = "Y" -o "$REPLY" = "y" -o "$REPLY" = "yes" ] || exit fi message "Submitting data ...\n\nPlease stand by." "sub" # send data python -m remuco.report send 2>&1 OK=$? echo # kill progress dialog [ -z "$MPID" ] || kill $MPID > /dev/null 2>&1 MSG_SUCCESS=\ "Successfully submitted the device information.\n\nThank you for your "\ "contribution! Please run this tool again, once a new client device has "\ "connected." MSG_FAILED=\ "Submitting the data failed. Please try again later.\n\nIf you run this tool "\ "in a terminal, you'll see some error output." MSG_FAILED_T1=\ "Submitting the data failed. Please inspect the error output and/or try "\ "again later." if [ $OK != 0 ] ; then if [ -t 1 ] ; then message "$MSG_FAILED_T1" else message "$MSG_FAILED" fi exit 1 else message "$MSG_SUCCESS" fi remuco-source-0.9.6/client/android/AndroidManifest.xml0000644000000000000000000000724111700415064022745 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/build.properties0000644000000000000000000000150611700415064022367 0ustar rootroot00000000000000# This file is used to override default values used by the Ant build system. # # This file must be checked in Version Control Systems, as it is # integral to the build system of your project. # This file is only used by the Ant script. # You can use this to override default values such as # 'source.dir' for the location of your java source folder and # 'out.dir' for the location of your output folder. # You can also use it define how the release builds are signed by declaring # the following properties: # 'key.store' for the location of your keystore and # 'key.alias' for the name of the key to use. # The password will be asked during the build when you use the 'release' target. # The name of your application package as defined in the manifest. # Used by the 'uninstall' rule. application.package=remuco.client.android remuco-source-0.9.6/client/android/build.xml0000644000000000000000000003202411700415064020772 0ustar rootroot00000000000000 Creating output directories if needed... Generating R.java / Manifest.java from the resources... Compiling aidl files into Java classes... Converting compiled files and external libraries into ${out-folder}/${dex-file}... Packaging resources All generated packages need to be signed with jarsigner before they are published. Installing ${out-debug-package} onto default emulator... Installing ${out-debug-package} onto default emulator... Uninstalling ${application-package} from the default emulator... Android Ant Build. Available targets: help: Displays this help. debug: Builds the application and sign it with a debug key. release: Builds the application. The generated apk file must be signed before it is published. install: Installs the debug package onto a running emulator or device. This can only be used if the application has not yet been installed. reinstall: Installs the debug package on a running emulator or device that already has the application. The signatures must match. uninstall: uninstall the application from a running emulator or device. remuco-source-0.9.6/client/android/default.properties0000644000000000000000000000070111700415064022710 0ustar rootroot00000000000000# This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must be checked in Version Control Systems. # # To customize properties used by the Ant build system use, # "build.properties", and override values to adapt the script to your # project structure. # Indicates whether an apk should be generated for each density. split.density=false # Project target. target=android-7 remuco-source-0.9.6/client/android/local.properties.example0000644000000000000000000000064511700415064024017 0ustar rootroot00000000000000# This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must *NOT* be checked in Version Control Systems, # as it contains information specific to your local configuration. # location of the SDK. This is only used by Ant # For customization when using a Version Control System, please read the # header note. sdk.dir=${user.home}/opt/android-sdk remuco-source-0.9.6/client/android/res/drawable/button_mute.png0000644000000000000000000000410711700415064024577 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ !(i|ëfÇIDATXÃí—il\WÇϽï¾eæÍî™ñxÇN×¶'Q­i)I‰ÒQðÔT‰ÔˆM „Ôˆ$ŠªÒ¨ œ*DE©Æ¥ÒJ³]qb§‰e7±3ñ2cÏööå¾ËšµRiZ>AÿŸïÕù鞣óÿ_€Oôÿ.t7‡3™ ®««ãöŒþÁ§xм|ùûö‡ºÈ˜Ù “ÉV¾õÌ‹¯>­ÌÍ?$ËòÞíÛ·ÿ”ã8àÁ×rYæ&W…Kí«mBˆ—J¥Ü¾¾>ØÇz~ÇkƒäÏž{Ú3­V‘y|S²vè¹'WgÃ×§BÙrRVc†ëøy‘sž×¢˜ó®l »âÿÞl__ýH™L†¼zøÍOÏOü€ézOgSŠDã´R™í\Ò”ªNx‡ï¸,3ƒëy€Ø&pÓ X:Ã\ßïg#¿=zïë÷êwÀC›7¯oÞ·oèeYÝ·¤Côëe9E(nKƼiäÍ)6Å>Q倫è†ãŠ€=Ÿ€=Š…™ÉØ|4GÎv©—|wóëýýýÎ5È òoùA¸)HðQ rBný¢f` QîÆð®Hµ,ì)…êþèyÞ8X!.Y¼ÑÑPßTYÈŠåe¹à,<:ø¬pâÄÿ´fÍ ñ>€L&ƒ;;;I.—ã(¥xgæ'›º½©¹¹'£!Ÿ])㺸’Qzf’Z š©*¶Ÿ™ÉqÜUŽãf!^>Ö4R¨IçÒìôWı+]®1³zÎÇü LJ‹Ùlö­[3A²Ù,·uëÖí±X,Âó¼Ì#ÇÁ\ź¿%òû#)Ùa ¿.¢¡%Áüy$*Ex²CkÀOœ·u¥ã+>?)tÌ3Æ*Ñh´àº®iYÖñÉ…+¡‘lÉŸ<¸ê>ŸÔôÆmƒµaæ(PàØ±c­ªªî@õBº(¥÷8ŽsO<š”êjÃ~^’|KÁ+"¼ÇË:ŒY$“­¬#.?A˜e&¤¨OÐøØh©T*l۶;xñ¢A)­(‘¤[Wï• Sš+™jÇÞßöî½l`€––cŒãñ8¤Óé@ccc¨±±1–ƒOB>Ã*á:jCŒgáŠã”˳ñh«1ßÜš_䩘 XÃWVHo¹,ˉݻw“þþ~×0Œ9ÆØ˜°´}|z¾è¡R°î#½Ùlß ”"ÆœmÛÄq‚1&žçaÍÑvTHK¢9Cƒ<áÀŠÄÀ Õ–¦Ú—ÛZnŠ<ñã©ös‡žTsë-˪ ¢(ºãr±¥vÂv©à÷‡c%wõÌÌ ¹=étÚ<þ<.—Ë>MÓ0Çq Š"9¨‚ßaàd aºR›ó”ÄòlMs]þüIJ%Å„é>Rsv¼^~gxIKÈí·ï_å* ŠD"%UU!àB¢„xˈ{‡\×Å·¦§§J©\(‚Œ±ïì™ :7ÒðR1 º•©y€¤AWÓc×§K N9k¹r×¼½Õ­ÕÇ/÷$’ö7Íæ‡EQÎRJ£DwãÔ4¸2ö˜‘ „ïv …‚øVq„ „€ ðc€° ÂQH2Uà)‡0Æ Bh´Xlþ˵že'•¶:x%1rùLOgåø6XKiŠŒM×b×ôtdÏ-jEC©Tʽ ` „ª„S‡â ‚à8̉æã%˜×M(X:,N5@—$¦˜” J©§ªªfYÖh.ÔñжvÙ©¦ú˜µœÉØð?–×;W·ˆ¢öÀÔÛãõ ‘ n‰n¥ôåä…wMê_-ظqãÌþýû¿ —„B!^×qÿȨ±e‚/Ö'eÛ­Zyr.¯Ãº.?<Ú*C,gB"8ÇaŒ… K—ʦ¦Jº®Ÿš;×íð“ÇÂ+Z/è"6ÿ¾²³ž,8³¤È4Ý¿,xQUƒê-‡ä†††¼={öŒwttœîíí=ÙÓÓsª»»ûøä¥‹¹ù¹™‡\Ç%‰h ¢ª‚êÖ·%¡WÀM,UƦébQ£”Z Q JÙßàÞß–æ'bq챪Ô¢…®ïKüz´ôÔ;ƒƒƒì?šÑÀÀýÏühà…\ÞüB<Æ }*·"ª¡Ç‡`qX`ÃSi‹µ·Ü¨6&/NÚþ 71vÙW앆goWßhˆë^¯jGBÞXí—bÏNÐïì»Ó>àÚµOIÙg„öŸeG_*•+Ýuu§=Xå»i>·¸†u•P‚AOM>Ÿ·€™ŒRLÛ*¦œ&|ñ§'Iè´»60p¨åÛïsCôaÂÈïv¼òØÙüÕªVjõ‡yÚ‚Ô˜;ˆ¨Ú”"Z7+’h{س(BbU3òf1¾T³,þ›7Ÿ:þÞâw—ˆvìüìMÍú¹^ª6ƒeAc}íÉçŸì—ÉSc±ðÐD 2ô0ïØrˆ‚çˆØöêÅI'á?ziÃgNÛv¯þ‘Ñ¿:8¹&wéðת…+BµÑü¯>wk¡¼W–eÑw3!ý¯Eèl6ËíÚµKì\XÓýÒ‘hÓ'ŸŠOô?¡zŸÑLÏ,xIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_next.png0000644000000000000000000000310711700415064024602 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ "3È4qIÇIDATXÃíVOh×þ½ófvv&;»³@¬T츖ü·2 ¦`ÒÖŸ‹‰”S 9„-6:œf/ -´ÂXFcrkǧêkÛ`c … S°ƒÅJ»«•´ÖììÎÎÌ›÷r°äÊÆ–ÝCOñsxð½ßûÞ÷{oÞð¯ñcú/P¯×1`õz]îH.‹Y]×O•J¥IÏó´©©)ò,gjjŠpΧMÓüe½^§J©nÂó<²wïÞ·Ç™uçìüü<ƒÈ?GEº®ß™;yòäþí“<Ï#GŽ9BiQJ¥Ré³ãÇÿ¤^¯ÓçÕ¼|ù2¯V«Ÿ€âœ/M{ž÷Ô¦žLlµZ´T*íi6›]Bˆ†á{ >œŸýæÆq«Õ¢Œ±·MÓĆaÐ0 ?¸}ûö‰{÷îÍÍÌÌ\›››‹¶Bà|>kkk}Ã0°išo¶Z- éo'g³Y[)•=xð ;|ø0KÓtriié—.]š ‚à`ÇÖèè(aŒñ={öd:„MÓív»Ÿ\½zõóÉÉÉò³mBd”R„=†]©TðsÀ+Œ1€–Édøþýû‡Ýn7i4ïÞºuë‘‘‘ÏÓ4}˲,4 2–ee&&&úNg°¸¸ø«………µÛíßž9sæ/N'4MI) ¥Tš¦ !ôn·‹^(`KDEDJ™Éçóœs7Ñëׯª”b½^/S­Vc !²®ë]×{ëëëƒv»ýñµk×NîÚµëÜÍf³BHmlldÊåòê³ë=O€”òñmA¡$I¨mÛd||\&I¢ß¹s‡0Ʀi „€ápˆ ÃÈØ¶ÍcQ6›í///ÿâîÝ»‡¯\¹ò-Bè§!B)…쥄$Žc¤i0Æ C‡È0 ¢i¸® ¾ïCÀ„DQ„0Æ”RJ …gŒÅý~Ÿ>xðàÃ(Š4˲c, ÃÐz%B0 ¡Çí¢”BǦ)Äq qC`Û6Äq J)`Œ¡0 ©”’¸®Ë9çÐn·±ïûÀ3*•J壟 0šÍ&’RÆ0Æ€‚$I€1½^’$N§Ýn”R¦é±”Rh4c¬¶ëº.ƒ xãUZ€šÍæSW!J©'Ž(¥`8ÂÖYÙÎùï)¥Ô“:ý~ŸsÎ× Øl˜¦ ”Rèõz ë:! Š"@B4Mƒ­ƒ˜¦) „€1¦ƒH)º®{Ó0ŒÜâââÏ@m~O¯µ} išÀ+˲”¦i@)…R©¤8çiš¦RÓ´Ä4Í„1¦r¹pÎsŽã(Û¶…B¤i ¦i~ï8ÎïjµÚûÕjõ[)%Ú´EîèÀp8d𦠄Ñ4MqÎUéÚÚÓu}u÷îÝ_W*•ìÍ›7Ýï÷i>Ÿ„ò}_ú¾„^¹\þ[¹\þóÙ³g¿Öétr›–‡ÙÀ+!±m;¥”&ÍfSnll¨\.÷ïB¡P?wîÜGccc×cq&“‘RJ±²²’ú¾/u]P*•>>}úôo.^¼øZ­–ôû}E)B’"1ÆÂqõB„‰”R-//)%pÎ×\×ýúÀs§NúOøþýû2Š"†¡J’„PJƒb±øU¡PørffæïµZ-Ù^SJ)•RX¡Ò4]oµZò¹|ßO=zÔM’„"„R˲¾+‹:þü7ŽãDÓÓÓ©çydeeeióŸ@ǹ•Ë徸páÂ_·8O§Töz½ IX]]]¯T*â…ÉåèÑ£»LÓü2—Ë;vìXñÙ·`||¼ÉdþàºîïOœ81±SÈð<‹Åw5Mû§®ëóûöíËïÉ^5>ý/1«^¯ãJ¥BZ­VúÒHö¯ñ£Ä÷P½yˆ¬2@IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_norepeat.png0000644000000000000000000000372711700415064025451 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ #”ð}WIDATXÃíW[lÙ>çÌ™ûØž±džÄ‰¨¸ˆUP›Ô*R¡å%¦-­" >T¨Z±mµ0<„¥J#Pí˶[µš< U©„ª6R©€.ÚJ Jv£rQˆ8Ž“ñuΜ3Ó‡’*I¹…UÕ—ýžgÎ÷Íÿýÿwþà üŸ×ò°išhË–-8“Ép022ÒÔÝÝ=366Æþ§LÓD¾ïK–eíµm»oqqñ+ŽãÄ|ßw4MûÙèèè/S©[-òÁƒÜ•+W¢ÅbQ „ø€ÉÕgãW‘§Óiþܹs‡!Êåò×dY†Ñh”ø¾ï-,,‘H¤9—Ëa€×ßß/]¾|ù{º®¯+•J{\ו«ÕêJ©ÏqœÉ[›€¾¾>åôéÓ?¦”~KE½««Ëå8N‘eY¬T*¤Z­ÖDQl€eYèøñãoW*•w<ϳ5MC•JEe™lܸñ½cÇŽýöäÉ“àµtvvFÆÇLJ)¥ßˆF£¤££zž'.,,8óóó°R©xŽãÔ!„ÅX,Fs¹‡Ã!ÄÛ¼y³ …¤ÙÙYÉdÇq1ŽãxøËyÐóÈ{{{Õééé÷(¥û‰DyÛ¶m¬\.;÷îÝós¹\Îuݺ®¿‡šJ¥~•J¥¥iš†$IòC¡\¯×Åææf¬( œ˜˜8:44t,NãWV NógΜù>clÿúõë›6mÂOžBˆƒA?™L"Œ±“Ífßþ̲¬?-g…˲¸óçÏï¡”~·¹¹™Û±cšœœ=eYþõÐÐл†a8«Hÿ}Æc¬X­VùB¡Pà|>Ï' ÔÖÖ¦Ú¶í‹ÅcccØKV¬° —ËáB¡pBØÖÑÑ! )›ÍІaüñÂ… ïÖŸG±XŒ>óûáÖ­[̓þˆ2ýðáCO–e1™LzFã­7n¤,ËBÏí[·n)•Je7ÆXD‰ÓÓÓ@„'mmmï†á¬n åH¥R cü!Æø‡ø`ûöí¿×uý#JimnnÎSUUEB»žíJ–eqwïÞ݇B!ßu]T¯×A0¼;00ðI*•ò^• ™Z­öçÁÁÁšªªåööv B˜™ŸŸ÷c‚®ëÔuÝök×®…–B-/?!äË<χB¡`Û6‡òâñøgcïe_ÿ¢Šôõõ=ÿp]×o4(@×u7 …-K6üG¥‰¢¨B4ƘhÛ6ò<&“Éì›æ¼ã8LQ”¼ã8!yž'3ÆZ4MK,Ù°z Q­VfggQ¥R²,UUÏsÛ ‚ÐX:Ó÷}ÁóóÕWåQ{{û/zzzv¿ÎÔÀµK&“ÆÇÇ“óóóݶmo-—Ëm”RQUÕyEQ¦›šš>æ8Ϊªê¾hyyã?£å?®T*Áe—ŽGa'Nœ B|×Ä¿¹çrÖ%J4IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_noshuffle.png0000644000000000000000000000272111700415064025616 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ "ƒ0¥QIDATXÃíV]hU>wî½ó·»ÙŸÙM6‹YH[lZ‹1Ш-¬T„hSAŠ}ˆkK~ˆ)¬[l±°"±%Ö5¶6`ÝäEZˆ1êúéO‚¡D›Ä¦ÅÖI“ìÎNvwæŽ/‰¤ÛXl Õ‡|0 ÃáÜï¾s¾¹kXÃB/ñ<ÿ|$á;yuuµD)í%„üêb±]'+?"‘WQQA¦¦¦páA.\À ÷ôô˜÷#,<Ãf³ñãã㼪ª[“Éä±p8\‹Å:óhebÿúñññwcAà—Blé½÷îÝûþ‰'²«‘' ²gÏžƒ¦iî"„Žãò†aøDQtË Üôô4O)ý¼µµµýðáÃÆß†B!|õêÕggggß4 c½ÍfsŠ¢èF•‚à6MÓ¯iÚö‰‰ ÔÑÑqñüù󬼮®n¿®ë ãR„—1V*I’är¹ì>Ÿ¯Èï÷“t:­ÍÍͽ088˜cŒý¸r(cl†2mYÓ4MZ\\äBcŒÃs~¿*“Éìkkk ¯Ôr‰üm]×dYÖ Ã°t]g™LFPUUVU•X–e¥ÓinnnÎëñxÎù|¾Þ»$ˆÅbôÔ©SO'DQt „8„uóæÍÒk×®=§ªêSv»ýT*år¹\µ´´tD£Ñ}©Tª‘R ÙlVðz½G›ššzo߾͌Œlœœ '“Éí†a`›Í6â÷ûǬ¯¯7Q¡ŽñxOOOAîijgÏ*—/_~1öŒÝn×R©T ªªª‹1†¯\¹òÇqclA–åO9rzyÈŽ?.´··¡iÚË.—ëbuuusmmí/ËñZ犊 çœNçHiié-Y–uŒ±ét:ÿ´ÙlŠ¢¼S¸f‘H„ã8®—R: …Ê#‘y¤½nhhpú|¾o\.WZ’$– ¹7~ÒÙÙi/”c¼‹çùÍ–eÝ{`gÚ¹s§¡(Êd2™´éºŽ0ÆË†séŸrLÓÍårc!둺O$Äív·cŒ5BH!Ä!Ïó‹’$ýVYY*”`ÉìN"„>x$+^"oÅÏs—Á/”——Ÿ)))ùzɬLI’~®ªªÚ¾²ˆx<Ž)¥_€%Ër´°@´švvv…B¡Œ¦i(°¾¾>ÇÐÐÐ~MÓcƘ IÒéh4Ú ÐÒÒr&›ÍÖ8ŽÁmÛ¶µíÞ½{4N[£££®D"qr~~þU„PÞáp|FÛîÙ‚H$ÂUVVnu»ÝÝn·ûÇ“På;ŸÏ×ïõz¿áw°0Æó¢(~¶²“ššY„n„P!”“eùWEQúŠ‹‹{Eù^–åI’À"„¨v»½cÆ E…M›6½Îóü<X«=!]„îUt†X,FEQürI !d.çI’´ ƒÁ`†ã8²”Ò· ÿ†,ŸÏÏ`Œçìv»E)Å„fYäóyÓ0ŒYÆØpYYYÓj&ÒØØhlÙ²åàõë×5ØL)ÍEy)¥ž|>/f2dY’eùÏóCÉdò©‘ÇÆÆ^ ƒÇC !!$¯ªª~çÎ[EEE£ÚýÌ*sáp¸X’$¶cÇýÆOGgffBÇ-ú|¾žuëÖ}ØÜÜ<ú¯­8›Íš~¿ß¨¯¯7t{b±=pà@<—˽ât:vuu€ÜÜõ°àBû)¥oü'W²5¬á¿,5OzxžtIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_pause.png0000644000000000000000000000237711700415064024751 0ustar rootroot00000000000000‰PNG  IHDR ê‚£AsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ #6¡E´‡IDATHÇíV»nG½™YŠ[¤Š,Ȱ TQ—"H•6~Á.ìo?À½Á?V…û”qgÄ.UäQ$Ä!‹ZF¤÷1÷N q Ú‰-S)íÛ çÜ{øRŸ[áU€'OžÐÖÖ–9<|f.ßl6ËF£Ñ¨ª ˆ¬µX–%•eéF£Qí²Ö3CQÔét"cLh4ó&—"WU«ª4k˜Æã10³cdW7 ÖZ@Dˆ¢1EQXhò¢+|§!@D`f°Ö‚ª3ëü¢@DB€c`2™ Uýà¢+d/sbŒ ˆ8obvèü¿"ÂªŠˆD! "PUôÞÓÒn¯sÀ{OeY"âåUUª¢ˆ¼shEDªªc „ècYòÑÉEÄÌ\?ßm½_D 5Ž™¡^Qý aq=KMŽˆAU±ªª9yÝÈ¢áj\Qh­…²,ADàcû¾’<„€“É$:::"¢K‘Š¢ V«e˜9,Bó<7ÇÇÇd­k-åyÎÿ‡œ¦Ói4N¡6“ˆ 1Ƽ'»zïùôôCõw¤ªpmÙ«¾jµ"ÖZY¸ÂÌÊÌ ªµÓÿµž¥ ‡ˆJD!Š¢Ðn·Á˜Ë^/¯šwSU•­•i6›`­…v»1dYÖº¶á¬µž™ 3C«Õç\ ¢°8y=¥s.4›MTÕÚñˆ®'»ˆk­´ÛmvΡ÷ò<ŸK¿ »"b¨#Ø9ˆÆãq`æëÉXGæ,FëxEÁÙˆ3C£Ñ¨=Däܲ²W!„¹Œu‚!¢Šv»ÝÚñJDZßwDェª€l0èRäÆ-Š¢(Ë’f’êÌÉZEyqqñwš¦ 0Kï}Èó<‘ZkÃt:DÄ7oÞ€_Jö8޽ªþbŒN& trrBY–™,Ëʃƒƒ‹8Ž}ÇþäääTDª‹‹ ‡xttÄY–™(Š~cæ_wwwe©Éwvv¤ßïï={öìÏN§³ÑívˆðÙÙ™???ÿýñãÇ?×O£~¿¿ÿôéÓìöíÛ½F£qe<çY–??ÿi6› TUÕ)¥aË 2h™L†™¦é9޳gmmíä½{÷Š®ë>ž˜˜ø«"vUžÉdBƘ$Š"àœƒ$IBÎ9AD¦(J¬³³“†á;Ž“³,ëäâââ{„?ÇÇÇ×w+‚ìT•‚4›MÚl6Áó<ð}šÍ&pÎ!emÛ–<Ï‹'“É=}}}úþýû%!ÄÐǯLOO¹ºº:¸S{îGÄaËî§“ J)A¶mƒã8­Ï©·­òcÇŽ5¯_¿€”Ò–J „D’$…–eÑ0 AUÕµt:ýÃ*åryÉ4M'‹Û†/--IˆªªB…sqÎùÆÆ8ŽÃ4M³ÒéôB__ß…ÑÑÑŸŸº+üðáÃaEŠëºÂ0ŒàÉ“'¢V«)Œ±ZWW×ÝÝÝΞ=ûÓ‹Bw…///#!dÝqœL½^WE©š¦y#›Í^»ñ²Ðÿ¼Ã!⯈¸©ëú|ÿ‡•J%6;;ûJïp¸S¢P(Äëõzjttôñ¡C‡‚צômü¯â‰‘ç[rÞbIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_prev.png0000644000000000000000000000307311700415064024602 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ $¸·æc»IDATXÃí–]ˆÙÇϹ÷VÕ­ª®®îêo3c%8j`ÈÃ¢è‚ >˜€ BØ…ÍÊ&C`wÙƒ­Áƒ‘óà‹ AÍ“I É<™Äì‹!‚´¢#óAwMwuÕ­[÷îCF—·õ<.‡ßùŸÃ9Uൽ¶Ï»á‹Ã0$@@…a¨þ‰>3³ÓéFãJ¥òóz½þ­n·K_‚`‡aï”ËeÿeÌLONN~8===ýRf·Û¥üJ±Xü;hß÷{îÜ9ëe‰:T©V«ÇmÛžGĤT*}°†!9|øpÐjµ>ò}ÿˆ˜µÛퟮg²õÐ……fšæÎy5Žcá8Ž”R’UtáÂ…}÷ïß?ž$É…B*¥²-[¶¨N§ÃΟ?¿qqñ{q¿‰ˆÕ „æzæ3¤”$Óu]E‘ÎóÜs]×W¤µæ'OžüXñ¶iš•;wÊF£aÌÏÏkJé)¥;;;kŸ:uêýÑh4ëlß¾]ض½^LÓ”ë™ìÝ%Zk‚ˆ@ɯ\¹â†a˜A`œ9sæ­~¿ÿ"~¡Ùlb«Õ2 ÃðÇã1†‘ÕëõæíÛ·¿sýúõoÇq¼«V«±­[·RÛ¶!0Æ¢<ϟɹA€R !ZJI8çã#Gލ«W¯~ñÖ­[sJ©}år¹èû¾]­VJ© Äqæ;w¾Ñëõ¾Šˆæääd^¯×-ι-¥$išJ)%aìÙ” ¢VJQι"„l¿téÒïÝ»·/MÓ/MLLdårÙãœsD¤BTJ¥”†¡ã8v[­‚|ßÇ,ËHE¨µ­5j­7¬ý‹:@-Ë¢ËËË_ ;9çjbbB•J¥‚RÊ̲Œh­R ˆI’"¢çyÀÖJL’Ò4B˜¦ I’€‚Ú¶½¹ÏóÆZk”RRJ)­×ë¬R©hD$ËËËH)EÆ0Æ I’ÿBƒ,Ë€„Èó„e˜¦ùÔgŒå¯ìÀp8äQñ(ŠÐu]Ýï÷±ßïÃ00IXó!Žc ”B¡P€(ŠÀ²,¸{÷.<éŽR c „)%‰ãØq]ws”Rµ60`uu ! ”z2' µ~êGQBÇOß´ÖëcÌWvÀqœô ¤V«ý›s~giiéÑhÔBDÍ9J) !€sBPJeY „DÛ¶ŸVndYyžƒ”RoØù焆”µÖÀ9ÿdnnîûívûCß÷o!¢RJåœséyžæœƒmÛP«Õ´”\×Í8çb<kÈËå²bŒã8P(´a9c,ÝTÀp8´mÛišš„áìììïöîÝûÝÉÉÉ_h­‡ƒÁ —R ˲2Û¶užç`F¾k×®?îÙ³ç‚ã8ƒ]]]ÍŠÅ¢ð}_3Æ4c,—RZ› (‹C¥Ô“}Õ333rÿþýÿ Ãð'SSSo9Žó—áp˜/..*BHF)Í¥”àyÞߎ;ö³v»=S­V¯¤i:~ðà‡’Rª×¾ä¥3ÀS£Ñh85!$WJéÑh¤@‡a¨ év»º|ùò?çççßí÷û?zøðaÍq™ç¹õèÑ#Ÿ2<}úôïoܸñ×k×®ý0Žãwûýþ6­5¡”j)%]cnÐl6åãÇ{RÊH)$I‚Œ±gއ£Gæ°Üét~uöìÙ­¬¬¼·´´ôM­5æy¾¦i¾3èt:¿¼xñâŸ{½ÞG+++_O’Äϲlåyæ†_m±Xœ³,ëžçßì év»ôĉ^£ÑøA©TúõŽ;Þ|>¾ÛíÒN§ã4›ÍcÅbñ7Û¶mûÚ«ŽÃLMMUvïÞm~ÖsëæÍ›líìúŸc^Ûkû|Ú§`¢ÎZÃ5¤IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_repeat.png0000644000000000000000000000477711700415064025122 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ !;íª¸ IDATXÃÕ—[p]UÆkí˹çärÒ’”4m „$ml›Š-Ö6 v C:TtQypñÁ ôT‘å¢2ˆ ƒˆLAZa@i¥!j3MHJ“&MÎIš““sÙ{¯½—¡P˜róÍ5³ÞöÚß÷ÿö^ÿÿ÷ÁÿËÒ`é4Q­·%µîLÍïmI&ªÁú_ß+>Xc±“(mmI”QO ë ÛI ~vÔ>ÓÛñÅíÛñØÅömdÞ"Uë±c§GO€÷±è4Q.éH²¸ÜÄ\q6à Ww‚-˨L2ÅKñĤo¶¶†=º©§ŠzBFŠ<`ûYì‰açI¦Ó?­‰BSÇÌ 8|CûÞúW{ß_à™}ŽŽzX–àÆ*ùêeÉ;…táÚ)-­K…¯.CøF'½™‘QçñCýÞó×uNœï(a¾?ø’Fކ· tz×s¹È3{çxüÙ91ɲÅíÍ!Þ<®ð•Ø—v,Oé­~jêŒrYóÂ?‹ä‹=ýåJåsÍÕ—W5è8Ý}ðÞŸŒoñ\÷Ö;ïŸfçSs(¥¹ðü(TĹ|ÀLÞ'(?Xj9æ•w=0]ó㻦h9˦²B2‘õ±,Ám߯eËÆøçÐ…vº;Æ´îöNª`ž|(¶u6§nþþÏ'yò¹9Î]f³fyOiÆ&½Š¹)AHÒS* &l âQÁÚ•aRÕ&‡úßp™ ðOèÍázzvî¤äÞE@k¢ -iDÇ·¸ŽsúŽ v=7Çù«"t¬sôM}¯i¨³h=+ÄòæKÙ\°!2E`v›Úß K*â5UÙiÅÒ3-Žg7Ý•®ÚRùE ¹½ÛÚÚ2Z÷…À3ß¾jt$± kA§yl†§öαº-Äêå!8trX¿&Â%¸`m°ÐÈÝÙ…é%q‚MB€ãj‡=¤€HXrÞ'ÂTVxÜüë)šm:Ú*®†Ûä4O*`Ñã5ê¨ñåþ7Š‘GŸÊÓPg±é31ö½RâŸË|mk%?º¾<¿„çÿiUf¥Ù"Ñþl,**&§™)åk†y¬l ѼÔâxVqÿc9Ú[B«lŒ Ð6ˆî-Êùê;£Øn‹Ðîç6ÏÄ”bÍò0C.ݽe®¸(1®ÄóøÎ׉·Sˆ=ÍÞž>– ‘±µ´šœV4/µùÉwjxð¶:’’—þ]&‘|rE˜ýÿ.òdW-ýKÉÐXó Ž&1iwìï.½Õz5=ý.ç,±¹æ² À/s~Kfd/é¡âÛŸ¯£{X¼–zô‚u‘èŠû++,$_¸0Îï™e`ØcÑB“bIÓÔA±U¸~töIÀ ÕkCnì9ì03P¿À¤TÖäò>ŸZ¡åÜØòIdÐÇ.râ”n&;(2žíiIù¿Ú¸¢òkˆðïÀ`ó†(õ MŽŽº”Ý€Åõ#Ç…‚†²·†ÁÑä<¨U+4«¾æázššJÉø¤Â4kÚCø* äèaf“3l?M?OSä³äØ5ÖGkíÓ$x­v‘2XÝ¢ì@.PSe08¬She¬#­•ìé´p‹)|dOø”ÍxÆÇ÷5ç,¶0¤$b[9Jaïýš·o^™=92 ã=’ú&ùBÀ\AS*Ï* ˆ°¹‚Â\­¤(‡cH‰ 3ísèu—##.‘¨- *¼“@:_Kaß,"%±ˆd"«8<èpdÄ£ìhb Ž2‘–É ¾\@‚§4…bÀÁ~€XD2ô¦¢®Ê‚¢¶Nú‚$¡Ãe‹X`¡rsŠÙ¹€\ÞEkh¨3±M 0‹š+H:÷xØÑ,äÜe65•¶YŸ×ޏó ¸^’É\ý!b¹\%Z7¹^Àþî2~†R”A²Â@‹`±bV³Áÿh?7Ìâz“-X˜2™-ümoÏ÷qµŽÆP=¼¿Ò‹D©3›ÐzóÁ>—Ý{ ˜ÔÕšœ¿:BªVHµU™y¦?†] *MV4‡p\MØT'%]û ü¥«@È0Ö£œ­ô´·ðjGJk¢Zc²£tw¤°šÛ)³•@Õ<þlžéœÏ‚×ÓX¬]EN›ÿ¡µ7g¤w`ð›L@®¤u~$T=ÿR‰¹€¶³m†)zV¶D¨;3²VZ¢»h0q†E!æ@*αŠZŠ‹šˆ”>M"¸[^qÏC³Ü~ß ‘°¤¶Ú`x\±¾#Âöo¥PÒ¸·Bê.ª§³ÆÒi¦«},ÉY vçԌϳû‹Ä"‚e =¯9ô847,®3[lÁòÖáMÔÊåÈ`3†ýMàëž§ÏùéÝ'¸õÞxž¦íì£Ç¦!¸éÛµ¬n÷Ïåû_Î\²G¼3 ‰’mîгÜ2>®Î»ê»c¼ø¯kWFðÍø¤BÁ¦õQ.Þgek„†E&ŠrYstÄçàë.»÷Ìñ̾ñ˜dYƒÅxFñƈÇõ_©â–¤(Ía÷ašG„ÀïúèHq¬°%ï}ùÕ¼ù½Ÿey±»ÄÒ‹ÚjƒéŸbYSSiÐPg’LHª’¥²fpØedLq<£XÖ`‘ª6èt)”.ßçŽP0þ*”õKZ{{§x¯)A{·v½Xà‡¿Èpèu—ª¤AuRR(iÄ[×ýDÎÇ÷Á¶Ji*+ ‰¸dhÔCùš+/NðƒëªX²È>$lo;SCè {Ò’‰÷7¤b ÂLg2*²ãÎiþ´;Ïì\@ªÊ@kðˆGç{ ’qI¾Pr4Ó3>u Lnº¡Š«·& ÙÁa©{˜K µ7+Ä)Ãì-ùhyv¸Ö—áÎ×<î¸o†®ýEFÆ<"aAÌ?/%ä ójUkˆ¯^VÁå$h\hBØ¿›¬x‚D¨ï½àœ ÒD¹„$‹k›(Ä6h¬/ ¥—g¦úzôqò(•5 g˜,®7YÙb³ ZP4Ð>/в|˜Úò>GÇÞ›>Z2:ËV5¥ðF|gÉ …ê$ðA ðçSÎB?2à†z€áÓUý±²áióaܪ%THQö*‰Z¸¨P޲“!SÇ^˜¡£;x§«úc85!“>%|vçß™ ù„GfÇ6Šzêú/£Ô©‘[ÓÁIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_shuffle.png0000644000000000000000000000405411700415064025262 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ "%<àĬIDATXÃí–{l•õÇ?¿÷vnmOÛsNO/Zô¬X¹8heÍDtÎL11M»1§8ç†C]¢ƒ 8Ø’MC‡»˜h2¼1u ãea[40\ÔEª‚”z)P¤´´ç@{J{nïåÙ…ŠJØ_î}’_Þ?~¿÷¹¼¿çù¼_øÊ¾ì¦¾è"˜“Áög÷µ/2°l! ÍQz’SaFì zfBŸú"˜lm K™,:ONl.µ!f³~«Í:lÅç«8«D_W¯ïx"ÝžˆY¥íWùºµ€¶OÛO²g@)²JÀd Aæ$£”ÇëÉÔ’/„QbA\sœ¬›ÆÕý¼Ü™Që&^þTà Ã4ôÆ(øjpZ”—ÌïܼfàâCG~}g„+÷©qy˜9ü&’P²…0çÕ&½pô2徫,cJÀsA(¡XÐs†òž×óE¹ÝgV Bý3¢T9IÓ.Õ+”8ß@× DcÙÏxú¥Qf5úX±´œÚÊaéw“ð¿ i%[˜êÍL\90f¬Ûð`fÊÇ6¶# ¢&.©$¨1w†Ÿ;n¨Úg(w#Çòo’êí`N2Šh¯Øºé¯Ãm;ßÌ¡Ÿ¥L»ˆ@mÜ`0í°¿§È ׇY½"ò´,ÙHMg·A¬!„Gñ~gÊëïd<îR7𙊱¬‡ß§82àðÚ[9ü>}æò%±ªÖ3©œ½§Ø$"­oË\óȳÄSè:8.”—iT„u*Ê4êk¸.tl:¦©«×ÜÃ#U¡q¬üHY5ƒi—£ÇÂ¥Á€†ã‚®Á¥-6mflܳòæÈz|…]ø”-¶¶à±m©i~&CÆëoçÈ„|Qèr¸wE„-)§sßÍøöÆèê&ª.1pQcÈ×0#S+1>Ò˾nx?}zŒÏpÚÙzŠ€§6v¦ivŠ‘Âˆ¡+æÎðø¶Q,”‚ë®(@#t SØTõ\ÔR±ëšKË]†s6ýÐ•á šžżIΣ–f²öšŸJMY³aO„lNðû>KQ7xæ÷Õ4}-Ô7Ž}_I(û&®f¦­Äâ[û×FË ë¹"/« Úƒcì9ŠõzòÆ)-J=‡zÁúæ¦'g®î8F¾ X&ÜþƒrŽ 8<ºu¥àâÙ~žìˆs^µùy¿*Ц/hÿiß¼ç¶sïm•¬»=ò9#[ËîÚf÷ÀÌ•Þéÿ{¯I¼Mâ~Ø(Ò;]ÆöM—Ž_TË´„)•aM|–’;n,ù()r0)K— €\·($wMéNŠ×Ý('ßi”›ÛˆÏR²vyDäÀÒ5c©ìn®Á4€°Ô.ê=½ûOžˆô§\t t,KaÛ°û½<‡úlb•:ËZKy`u¤W»¿nAÈ?xò…“üóßYÚ—;Ìl´(+ÑHŸðèì*è wyø™S‰ÏRÒ±ªú¨¼?}‘ÁI‡Ë\ª* B Ëœh.жPÔ˜Õèã7+cª,ÿùÀ¼×“žø•¦¼œåüöžˆ ªo}x¨Hȯa;0œqÉ…bQ8‘ñp=áÛ—–0¿Å7L¥aO4á¢$’Íù¢y×î}¹+-Ý#Ð0tÁÐ4lG°,º*Õ0Íß ‘O 6#ê|”ýºŽ¾hhÄ»Üoi³KB0”rYµá8›Ÿ¥$¨¸miË—D˜RìP¡à_H¼Ñ3‰bpü¡KZG'QliPôÀ3rb¸Ï+Ý|‘â§µÀ'ëJ£Ío·zã*µO«GsZj¢ÆÒbÑ èüòöw-«@tã U–ßN´â\(Ö£”y&£šå¦ñé‡'ØÝ™93øYħ m&ƒÄcÇ™µö¡±ï×UQ¶jyä]Òß%åß‹m>­¬ÔY:C8ÆlØjöÙTí9õáNÂ$’aRùæ42ÂÁÎ,mdOûúÿÈòõ§”ðÿµ_Ù—Óþ ™£Þ[ò“IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_stop.png0000644000000000000000000000151411700415064024611 0ustar rootroot00000000000000‰PNG  IHDR ê‚£AsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ #÷öp¤ÌIDATHÇí–±nãF†gfgW2ÌPÐ!hHÆ]åÂò_ ½Ÿ%¥»{?[ù ’”Fê¤l÷@À8Ó¤–ܹâ$ÁVhÙRqÍi.¸Ëýfþ™]ÀÖ¶¶µo`¸jòôô”ùööÖœŸŸ¼÷<ê²,yy­1Fçãøøø¨ûûûŸ/..âÚðÉdbÎÎÎnnn~ !ŒEdGD˜ˆè*§U•Tµ‘ÆãñÇëëëO]ëø¥ ò<çÂ/u]ÿÊ̽Á`àUˆHcŒ´ c„¶mÛ²,TõÏÉdòÇÉÉI|3<„@Ƙ“$ÁñxlÓ4íUU…Î9PÕÕ¹DÔ¶më««+3~ÊóœàípaD$"2Î9ž½į#¢ÎÈ{½038çY–ÑZ²ÏŠ("¢Š„@DžçÌŸO"AU¥£-Š׆Ï7CTu!û|¼ 1BŒ±snÙID(ƈ³"‚¶mÁZ»€w9;ûQ­µíFpÐÖu UU-"‘gÑ/ƒ¼÷c¤#hš†ïîî¨,Ëg’?9Ó²«*ÕumE7•§Ó©õÞã<ß]wEGDŒˆºiähŒQk-ôûý¤m[@ÄÿUýSçDDcŒÑ#ç´×ëi’$Ø4Í¢Ø^¹^ADàááB¼œ™…™Å9»»»ÀÌϪ}\U•ˆdåþ¯ä\UU›¦UçÜÊsû´š¦QP"j‡Ã¡®gf©ªª!h]×X–%ˆH畺ä4ˆˆ±Ö¶EQø<Ïe-x–eÁZ{9OÓôgfþYUéÉUD¦ÞûcÌßý~ÿ¯,ËÂ&Í_^^¾O’äCš¦ï¬µhÕñ)Šbzÿßñññ¿GGGu×ïôUø¼›ÙÛÛ3Î9Ó4 ½¥=òÞÇ,ËÂKЭmíû³/Ó…©q²ªÌIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/button_unmute.png0000644000000000000000000000332711700415064025145 0ustar rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGD•••›Ï pHYs  šœtIMEÚ #+ÂCØ^WIDATXÃíV]h×>÷ÞÙùÝÙÙÝÑ®VkýFX’-dj™Æ†‚k¹qóªÚƒ Â¦•\bpKµíK¸~PqËâ?´õˆ’ºÇÔ$7-ÂØNó ™4q‹£ÝE?»ÒþÌï½·]5Ù”ª)…R0O3÷œo¾ósÀ ü¿ƒü»³Ù,vGg³³³ü¿Ê:—Ë…"‘Èë„¿Š¢øË\.jF0›ÍŠÿÇ’8p "Ëò¯!5]×?nii™;~üøeYÏÕ´,‹ìر㫚¦ÍF£Ñ7†††7#¹mLNNŠäÕ}ûöýiÿþýEÓ4‹§NzuzzZÚünxxØŒD"w%Iª&“É Ãxo×®]_ÞJrx;²_½zõgðòàà`>‘H´Õëõ!DZZZH¥RP6›Å£££iš…P(‚ Dcù|þ;¹\. hÛ&´,‹\¾|ù´ëºgûúúœd2ÙZ«ÕtUU¡T*ùowww?>sæ ›œœüz½^8{öì’(Іïûa×u…jµš`Œ½ŸËågffž›VhfžÝ»w Ïž={NnaaAY[[û^WWW`F«çyaÃ0ðúú:ó}Ÿ‹Å6€ñññÛ¶/ß¿¿G×õ·Ž=úëÇÿæúõëÊårw­VYXXxhS–e‘‰‰‰¯!„ކB!EUÕ Û¶J¥Ò«ë:¨ª圫!ì8pÎAÓ41†<øÁüüüÏ]×ýöìììËétúÁÁÁ‡ÇŽ ݸqã»årùH¹\–Àþ)LMMÅ|ßÍó¼A¼â8Î7B_ ‡Ã]]]‘X,ÆJ)A”Rq]7 p÷î]ojjêz__ß·|ßwÆlÛ–mÛ6J¥úLA(µZM¶mcÿð!›¤6DIÉdòSí\©Tb”RFÆn” BÜX,Æÿ٠⛽™!„h DQŒÿ~cìo  i*‹ƒ’$Ù‰DÂF±B¡€ ÐuýƒB¡ÀšÀª(ж$Iž¢(ž(Š€ªªTQ.IH’Š¢€$I\ …ÜM‘,Ë"·oßN×ëõMÓž2Æj”R¶¸¸hA‚ ü1•JMKJ¥‚ÖÖÖK’ô;Abªª:žç…—––-//ëºNB!EQB<ÏQ©¢(ÕÆÁ¯mll\¡”&z{{g9ç¾ïû©åååƸ„z–ÉdXS™L†Z–5_(J’DžÀ÷îÝë½sçÎo«Õj$‘H!RŠ¢Ñ(/•JcÌΟ?ÿR¥R™¢”¾4< remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_next_default.png0000644000000000000000000000317211700415064030634 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µaPLTEÿÿÿ???zzzhhhjjjxxx777ïïïÿÿÿôôôkkkZZZÒÒÒ111²²²êêê½½½###øøø„„„ÏÏÏÍÍÍ...òòò***åååöööíííûûûxxxÛÛÛ999”””~~~–––YYYºººãããFFF‘‘‘€€€{{{***¤¤¤IIIíÏÑnËtRNS  "%$! 6DKI@0(9FE:*=C?4#Nèø¥&ƒëƾ—«ýܯmð‚Vïœ-Ä[˜ÈúÇ÷üùýÙôÊÞÁß–Ú²™¬¢»Oyjàsu”MªÛ‡ŠÎr êö¦YºÞ±TgÑÙÀ‹L15S{¥Ö±\b'2; §œýIDATHÇc`´Œ¤ò50AT…ÈÌj`bfaeccceaf‚óØ98¹€<&.Nv6n^°T3+¿€ °‹('·¿€¸+3‡¤”´€ ˜×ÀÅ*"$+'¯ ¨$#ÆÊÌÉ-¥¬¢ª ¦®¡©ÅÂÌ¡-­¤£«§o`È# ×À,)`dlbjfnlai¥em£¡kkgïàèä,$¦-­ïäâêæ®. É ×Àb¥ïáéåíãëgî $¥-#ãäŸà#Å×À*£kž˜”œ’š–è™®ª#—‘™•œœ“–›—¯XPèZTœ\Rj$Í ×À]VXž– •UÕy.Ž 5©@Nm]Z}fC°IcZSrrZsa7\›eK#XÈ’úÜêÄ´T0¯5'-¢º-¬¡1_ƒ ®A«Ý¸¢hIG@4€,†jãv-„†èÎ.˜%p @Kº¡º:£qh[×¶„†äžÔT$^k/A ÉÉ}ÈœþÂ0Õ5L@æLL!¤¡²§'O!äéÖ^¤`8u`ퟄq“§`8¤¤4¡aâôi°¤19iX[¶øA4ôÏL›U4»ªhüœ¢¹ó0wÙ|Ï4¨ñ¹ 6Ïi˜¸hZxÈâ…K–‚5”/äFÎ@&Ë{’ûW¤ÍY¥P j»j5Øø¹öÆjAþkÖ®K^¿%³èÆÈM›{·,]¼ÕYPFCw›ßö;—ïZ¸{àÞ}û<ÔìœE™% t:NX|D·]SRKÊRíè‚fS×|cǵÄdö-\Üàa„\‹ÁÕe»-N²rò²YžT(T(ˆ>¥ÍÁÉ#&~BQ5h¯R1,ÈÄø…Ž Jgcábbâe9%xLˆ_ŒS”‰™GÛJ\P€_ ¹ ƒŽÖHE%;ˆÇ )*y‘¤ cQQQX‘Ëâ1!xHRt¬HÑ0 ¿œnTîÌ}IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_next_focus.png0000644000000000000000000000255611700415064030334 0ustar rootroot00000000000000‰PNG  IHDR00ý 1 5IDATXÃí—]kU€ŸùžÉîf7›Ýî6Ä£M Új«‚Ä ñ¢¿À¼Äß ‚þª”ZE UÄŠzSÔ‹*¥¦MÛ¥Ù|u7›Ìîfvfçëx‘Éf›ÚR*9†wÎûœ÷¼çýIðx‡Ì`ð¨C›zñYÐ7¤-ØM&v]'vH(Ɉ’)¶Éb""bb !#£  #I´‰QïQ¯c2€Ž‚ ‹‡‡O€T ,td¢ž,d4LL büžDlÈè¤È’gƒ›6.>ir ‘A!ÄÁ¦É*ƒ ‘A'Äa•&"±n‹:Ê DA›‹ÔX¡ƒÀ"Ï~F)bb³ÄË4ñP¤È(û0 X¡Š $ Þ P°È3Êä“/…G)÷ì‰vì¡?`sÊèøDäL)ÁK½¢(šÒwù¶¢I»”$©÷”v-ZêîµH ˆ péàÒEàú#ºŠ1>:x„8±jôp€˜ˆ.Z4qhGS·‚è£  A@‡&-:TO®½ût!ë?(`c.M–YæªýÙô¢÷FÉFCGFàÒb•eêñù;ßWƒ¸‰Eð`ADˆ›¨¨S¾¾uqÀ£MƒŸ& jüí|qmÖh‘½¯Ö6 jüi9]K"¨K‹ à°ÌB|nö§Ù0ÉûîúK¼®e;@⃃ (t˜‹ÎÞþmž6uBòbVÐp‰irÕ9}mÖ¡Aý}z|¢rÓˆ èÒ†.wY#æûÌtÍc† «È”™¤´LŒŽÿRýñNè0Í<.)Zééiã%u|Àgõn€¶]ªü:Gƒn1ƒ‰ƒé‚ÎÙk³Unp›:Y"ÒÎhº,ÒÀÁßÉ‚ˆ.M–˜ùêâ3Oý~·VKJæ\R2#Ì¿Œ‚›—Ãw¨0Ëaïã™·×^ :Äx¬¢&Ñéö;yóˆúÛC)i·¶Ž*r" ‰úZGuÇUˆ{›©q£‰;¦N±­ÉÝu•àÞ°û?þNèø¥&ƒëƾ—«ýܯmð‚Vïœ-Ä[˜ÈúÇ÷üùýÙôÊÞÁß–Ú²™¬¢»Oyjàsu”MªÛ‡ŠÎr êö¦YºÞ±TgÑÙÀ‹L15S{¥Ö±\b'2;> ïIDATHÇc`C0B EM93 +++ 3#œÇÆÎÁ ä1rr°³±rqó01"«gáåãfeadäàåãçeabdäd—”â—sà8Y„edåä¥EY˜8¸$•”UäUÕÔ54™™Øµ¤µutõô ¸Eà˜$ø ŒMLÍŒÌ-,5­¬Õullíì…Yµ¤ô]\ÝÔø%˜à˜-õÜ=<½¼}|Íüü¥ƒ‚CBÃÂ#"U¢¤ù£ícbãâÝ¢%™áX¤uÌ“’SR<ÒT´eÓ32“’²²Ssróò \ ‹’ŠKÌ¥Xà¸J ÊR“€ ¼¢²*×Ù!¾:È©©M­Ë¨2nHmLJJm*(å‚k`µhnkYR—S•šæµd§†Wµ†54䩳Â5h¶UA4-iOˆ% ÒPeÔ¦‰ÐÕÑ Ó²®hITCgG `KàÀ–ÒÔ’‚Äké!¨!)©™Ó×MX º†~d΄dBú&"{zÒdBžnéA Ö S¦Ö¾‰È7i2ÖˆCJ@ã&L› KÓ‘“†•E³/DCߌԙ…³ª¡€ÆÏ.œ33ñq•ÎóH…Ÿ3ßaAÓl† §†/Z°x XCÙR.ä d¼¬;©oyêì‘òù*6+WŸcg¤è·zÍÚ¤uëQ20‹nˆØ¸©gó’E[œ¤Õu¶únÛ¾cÙλv ìÙ»oÿƒMîÈY”IB_»cÑ¡øE‡uÚ4$4%-TÌo2qÉÓ>zLSTÚï‚Eõî†È…°˜ðWYºËü8¿ «eÀ ùùü¨“ZìÜ¢bÇT÷ #3À‚L”Oð¨€Ô1VfNFFVá“GùDÙ8D™¸µ,ÅøùDYP‹>`áh…TT²x<¢’I ¹0¹Œ #‚‡$5 †*®h-«€RÈIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_pause.xml0000644000000000000000000000071511700415064027303 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_pause_default.png0000644000000000000000000000152511700415064030773 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µPLTEÿÿÿŸŸŸÿÿÿ™™™ôôôøøøýýý¢¢¢ÁX݉_tRNS  "(+ )9GQW.Hcy‰’1%Ip—¸¿˜qNf’iÆ+ß»3óK΃˵£;Øæþ-¸!A1ÇP†ÂJn; =”×Gûý´ÏK$`’‡$@ÁMâ ËñÁP(Ès¬7Ž˜ÄठÅ1‘…x,™J%ÓŠ2àC:v$edý2Ù㜢äòª¶¦MÁ€pR8=“΋˻.¯JeuC×\´rs{w¿zò©Öju­aÐô¡€xl=Ék¡(·¡- ƒ4ØóË«)tÞªSxïúq@ÀýÝž)ôƒ¾)HÃOPø² #Q™BvýK‹âx/ì…½°+a›OÔi~e¦jÍLÏ.3zȾ… ­47©lhuK*šÀÛ¤rãÉêÉD-—ôo(ÎyÁÔžûì2÷ššo)Jk{Ò¬MîƒbLÈ4½”©Aт͠˜“5ãçld1Ys~¶¢‚Ýd9Eç³»ƒ?GÂö÷eäð¿*IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_pause_focus.png0000644000000000000000000000205011700415064030460 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µwPLTEÿÿÿTTT†††ŠŠŠ–––‹‹‹PPP€€€¬¬¬»»»­­­‚‚‚………¼¼¼ƒƒƒÆÆÆ×××ØØØÇÇÇêêêëëë———½½½”””ÂÂÂàààôôôâââÄÄÄžžžÅÅÅõõõ•••ÃÃߟŸöööUUU¬T2{}tRNS  "(+ )9GQW.Hcy‰’1%Ip—¸¿˜qNW(ˆä»¼ºF…(ÜÞd ¹Ô=x`ÙpŸÊ=>Џtþ%<±ìSM¨ 5¡ZB9O´üä‰À·ÌìÁÌÄ¿2éP)30dÏ…Œ—S™2s¡Y)•1•Z!•RŒ‹rŒ‹ÜðŒqQŽq‘sÛhŒ1Ì}@Ê}ˆëLƒÉÜCòÚr/Ê焼x¥Ayù$gXaPJ“õJ¿ÙšÄÉz£_e +MVÅ£XùìVá'P‘Pþ½+G™µZIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_pause_press.png0000644000000000000000000000151211700415064030477 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µPLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxxx'''}}}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ000---ÿÿÿÿÿÿÿÿÿ)))ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvvvÿÿÿÿÿÿÿÿÿ[Àé ^tRNS  "(+ )9GQW.Hcy‰’1%Ip—¸¿˜qN remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_play_default.png0000644000000000000000000000173511700415064030626 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µzPLTEÿÿÿ¢¢¢ôôô™™™ ýýýÿÿÿåååUUU¸¸¸xxxÒÒÒ999ûûûXXX{{{[[[€€€zzz   ¼T&~tRNS  %164." -DWbaXF2 )GkŠ›‘y\A+9”âûáÁµ’pR7#xþÿ÷п©…c(QˆéÅšv<'“Ù±‹jL[—ñÊ¢~]˜ý¹Ñ/=ÙŒ£@*nMÒzT«{O,g;ÑEÏ á‰C08›èT”IDATHǽ–gSÂ@E1¤@„ˆQÅ‚(Òl¬Æ^°¡‚ìbÁÞÛ7DqâLÄ}ãÈû~fs¶Ü¦\S9-IÑ©%0†fuúJCg$ € MæjKÕÆ8šÁ´µf{£ÞéÝìO‹(ÊÝäñ6·øZÛÚ;ü&£ºŠtu;ƒ=¡p$ëíëг£²} €å=ƒÑ8BCÃâÈè˜`×H¢ÀMLN‰¨0Ó3âlÂ17¿ É—L~×â€BKbryeÕª"¯RöôÚ'€Ðú†¸™ÉªÈ+[zë @ÛáÈN°(Hò»²üž,å÷ey,…ÄäáwùÒ€,ŸËdŽÍÅE~P\’œZò)šÀ$ù31w~aÍs$&P¿¼º¾Ñ \@:yßí]žÅºO<ð%à‰ù·OJ·zpÀ«½|Àë |@8Oà˜Ë °¨”ÃøÆRÜ Þ@Ü åÕáÄ/¹²Þ•.Exí–áO`Ï;ÜÜOýU IIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_play_focus.png0000644000000000000000000000244611700415064030321 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µ=PLTEÿÿÿUUU€€€PPP†††………†††|||---ŸŸŸ­­­®®®£££fff’’’³³³ÆÆÆÌÌ̱±±”””???œœœ¿¿¿×××âââàààÑÑѾ¾¾©©©xxxžžžÄÄÄßßßîîîñññèèèÚÚÚÉÉɶ¶¶RRRóóóûûûõõõíííãããÔÔÔ‡‡‡...þþþüüüùùùêêêÞÞÞÍÍͺºº¤¤¤öööÿÿÿýýý÷÷÷ïïïååå²²²AAAôôôëëëÊÊÊŸŸŸÕÕÕ000bbbäääÀÀÀ¥¥¥øøø–––CCC@@@TTTOFD¿tRNS  %164." -DWbaXF2 )GkŠ›‘y\A+9”âûáÁµ’pR7#xþÿÿ÷п©…c(QˆÿÿÿÿéÅšv<'“ÿÿÿÿÿûÙ±‹jL[—ÿÿÿÿÿÿÿÿñÊ¢~]˜ÿÿÿÿÿÿÿÿÿýá¹ÿÿÿÿÿÿÿ÷Ñ/ÿÿÿÿÿÿÿÿ=ÿÿÿÿÿÿÿÙŒÿÿ£@*ÿþnMÿÒzTé«{O,ÿÿÿûg;ÿÿÑEÏ á‰C0òñ<ÙIDATHÇcd 0’«Xÿ)ÒÀÿA€8 lÿ™!àë¿ÿDh`dá‚©gúÁø‹°&ÑŸŒ0ðìK4°È2"Gÿ¿`õ ’=FÆ7¢çþýe2JÁ©ŸW á¨ßª]ýgG¯5#ãÏ?<`åŸùOX22îøÁh†[¿ìGË·" ˜†î3i c3¦ç‘4$móf¼¯÷ÃUFÆ]˜žGÖ°Ùÿ¢Â×;<7³C=ÿ ·>~qˆúãVŒ{@žÏÚòü<$!õ…¤g?Øóå‡Ažÿ…[ƒã7nP„\ødÄv•´Í1ÏcÕÀÀð‘Q€ñ,ÄóQ—u ÿB-Á¡¤…û#£úmµ;;›;>1—Y¤,€âX>vzf)¤YŠÀòçrþâÒZhB (u}s«7R¤>yßÝ}'zH>Šž0ðÌýÚ–€ÒÀß =8àÕ€^>àõ> ’' pÌ€ƒŒ%XT*aüc÷’÷÷ÅBys8É E©¬w@eK^»v>`øÛ*²'¦nIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_prev.xml0000644000000000000000000000071211700415064027137 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_prev_default.png0000644000000000000000000000321111700415064030624 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µaPLTEÿÿÿ777xxxjjjhhhzzz???êêêÿÿÿ²²²111ÒÒÒZZZkkkôôôïïïÏÏÏ„„„øøø###½½½ÍÍÍ...***òòòöööåååûûûííí999ÛÛÛxxx”””~~~–––ãã㺺ºYYYIII¤¤¤***{{{€€€‘‘‘FFF6‘xœËtRNS   "!$%#4?C=0*:EIF9(@KD6WinfP8hx|t_+AZp}~q<3€¨Å.d…£¶ÒÆŽeB)7Q‘®ÃÖ·„X¥øÿèN>Uvš¿Éñ͈^a©Öûú&‚ðm¯Üý«—¾ÆëƒœïV-Ä[˜ÈÇúü÷ýùÊôÙÁÞ–ß»¢¬™²ÚM”ujsàyO¦öê rΊ‡Ûª±Ö¥{S51L‹ÀÙÑgT±ÞºY'b\2;¼ãÍ IDATHÇc`´Œ¤ 40L˜ ™Ç„̃j`bfaecçàäâŠ3qsqr°³óð23¥xyØá<¨&f>~A!aNn&0GTLP\‚‹‰I’—]JZLFPœ¬¢A’UVN^AQIYH…“™WUM]CSK[GW˜‹™GB@YOKßÀPLЇ®YDPÃÈØÄÔL^H…]JÌÜÌÂÒÊÚFQÝÖNÕÞÁÑÉÙÅÕÍÉ]P„®WØÃÈÓËÛÇÒÌCPÀWÛÏ? 0(8$4,\H,"Ò9*:&6.>AÞž®G(Ì91)9%Õ$-]/#3+;'799/¿À@I»0¾(»¸$¹´ÈYQ€®­,­<;9¹"»Ò-´*¿:»¦699¹¸ÎÓÂ4³¾¡± ÈIÎnN+cƒk`WϨkl©ÈÎi©H.Î.ªÏªÖPÙæÀ× ÚîTÖ`ãÁ€ £ ÂIήwjWEhðíì‚jèn…ªk€ÒÐÕé‹MÌx°¸ñ85ô´"T$÷&ÐÐÛ‡¤"¹™ƒ]>@ %•L$¬¡bÒddOOé#¨!{ê´ HÁŠh¸â!a (â– ihwšKSgL@JpKP“<ñÍœ•:fIqvݜԹÙó –dGµ9Ø!’·Ìüf°† - œºdIñìòEK³ –dÇ/CJÞ  ´|EòÊU«#Ã4¬f-Y³ÖF;]ËoÝììõ}ɽÜ30‹&”oÜ´yËÖm2bÛw,Ú¹a×î=Q{ÕdÌ÷-^°¿çÀAÿCÈYX¸'T-^´5B@Bõð¥ ×ò¥G5„UEÔÚ-ö<¾¸SI©d•Û¦­wBT‚•‹Så¤oºVšÖ©p{v.YÁŽ;ækGÈ 3À²KB\PFÔ^…•™I’‹CB\ìˆÌI)v&&n^öÃB2GÄÄ% 2HyhÇÎÃ)*Y@¤¢Ò­¨—¸’’’°— ÄcBð¤èY? aQoŸýÆj*IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_prev_focus.png0000644000000000000000000000261111700415064030322 0ustar rootroot00000000000000‰PNG  IHDR00ý 1 PIDATXÃí—ËkeÀ󞹓{ïäq“4ÉM¼MÓ¤ED¤…n+¢b»°ºU êÖ¥.[AŠ@·‚ îܸÐ"ˆ•­(µúHÚ&Íëæ¾æÞy‹™ÞÜ4I­– B¿Ù}gÎ÷;ùÎ9#Ä<Ø%òðp¿KØññäÁ†%tà·“Ü)î0{€€„ˆ„„@DHHDD ˆ©DÂô‰ÛZÉÃ&Ù€€„ŠŽŽŠHˆ‹ƒƒOm‰†D„G —PÚ2&Þ:¢ !O7&2uÖ€ .òX˜È„ÔY£’CÅ ‹……ˆK2UÀ%¼ ¢‘c€"=(8,¥²<} 2ˆ…ŒÃ27‰ÈÐC?;è'‹@Eæˆðñ6‡HB§›"{ŠS;‹gÏW/19¥Ä(½FâÆÏ§Q‰‰i¢ÐËc”(Z…Ç{gg¯ÎáТE° ‘g¯6µ±ñϾ¡I„‰H»˜ʼ25˜GûÍÃEÄÅ`˜q&è?0ðü„*;»>¨±Â2+iÊ7…¨‹†L ò:;©#Ñ@g˜I¬ƒÅ—J¦èQÁ0Ç!C„E‰ÉýÕ‰'úDš ÐO/&êúýêL²ŒF®ã³ÝM>]Œ e¦wï³òˆ4ÓúØÃ¬Ó£r†ˆJø,:ÊúÍèô@BAëŒ,) ‰ºˆ¨â'ºýôCN™ž|ª¯Ÿ^T   !#n剶ޒn G'÷Yô’GÅšè©ìÀÀôĘ\ ‡u‰uíS¶+€A€CÅÃ¥‚X ‡,DZdÑKykr_}Xt¡ãã mY4·(t‘§¨¿75ieÈ‘§ …ˆƒ/Û•WL,rdÐÓKqoÅ• “™Ï÷[’ŒN† " :YÞ-Yºˆ‚‰‚´1&PéQr˜Èhè¨Èéè!*zzüÝ:Ê6ý@èPîòÆ¿é„øTÄP”щ5­Ó1!·M*4ùbþ3ßW®q“e*4ðÓÎtO@‹àG_Ξ^ysïcf —<*.-ê8À‚sâìÓC¯¥Ý䀠³mˆ‰“°¶ðÓ­9û£™FÚb&!5j¸©ìÔü¹òSû¬& NR‹bâNÒ: "ìl@À~ÿ::»|lï£f›rbà eä¥Â'Î3ÃGvŽHB*ØI ƒÎxÉöû8Ô;˜ÅÆ`xnêÙÇž+¢—´UþäÝ”¾ãÕ£S{,;ñ­Ž›vòMxج²Pmå Ûc–+\¥ŠÄå`÷WѯKGööšÐr¸Âep0YfuiâSçÙ‘'KŠäú,³Jo N$ß“‚І´l}û£}Ë\g‰5j4©Óªr¦x×nþô¹Æ<+Ti`SÇ¿â«Fþ©_Ê¿s…yÖh&Mÿ8B|û®ÊI?c„*-¹Á"u4ºégXÈ´Xä:ó¬ÒBÀL›þYjÜbŽyVi$=9Þ"—:·pYBÆ£Æuš¸ø´¨²ˆ‰‚O2l\b<\lÖ¸‰‰€K•25¼õ$¯{ ^*N:x…í‘Ì@G"Â¥…ƒ‹ˆÈm-‘0(ÚƒWÜèbB‚ö‘SID°åè˜hm7n—N¡=ÂÆ›\¡½{§lK­˜×îÿøðÀÂÃ?ý‡€û^–Vöèĺ»IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_appwidget_music_prev_press.png0000644000000000000000000000316511700415064030344 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µ^PLTEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÐЙ™™æææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥¥§§§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåå嘘˜ÊÊÊÿÿÿÿÿÿÿÿÿ999'''hhhÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÕÕMMM³³³ÿÿÿÿÿÿÿÿÿÿÿÿ¤¤¤000555ÿÿÿÿÿÿPPPÿÿÿÿÿÿÿÿÿ---ÿÿÿÿÿÿÿÿÿááá___ÿÿÿÿÿÿQQQÿÿÿÿÿÿèèèÿÿÿÿÿÿØØØÛÛÛ222///===***666ÏÏÏEEE™™™øøøˆˆˆÿÿÿ‚‚‚ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”””ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€€€ÿÿÿÿÿÿÿÿÿ???aaaÿÿÿÿÿÿ´´´ÿÿÿÿÿÿ’’’ÿÿÿÁÁÁtttÛÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøø———“““ÿÿÿÿÿÿÿÿÿ„„„ÄÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ9$§€ÊtRNS   "!$%#4?C=0*:EIF9(@KD6WinfP8hx|t_+AZp}~q<3€¨Å.d…£¶ÒÆŽeB)7Q‘®ÃÖ·„X¥øÿèN>Uvš¿Éñ͈^a©Öûú&‚ðm¯Üý«—¾ÆëƒœïV-Ä[˜ÈÇúü÷ýùÊôÙÁÞ–ß»¢¬™²ÚM”ujsàyO¦öê rΊ‡Ûª±Ö¥{S51L‹ÀÙÑgT±ÞºY'b\2;)¬OJüIDATHÇc`C0‚ ‡…Èªš‰™…•ƒ“ (ÎÈÅÉÁÎÆÆÍÃÄ–âáfƒóàê¹yùø…„9¸ÁQ1qVNFF 6I)Qi1^n$,2²rò ŠJ‚ÊL<*ªjêšZÚ:B¬œLÜâüJºšzú¢’Ü\p LÂê†FÆ&¦r‚Êl’¢f¦æ–VÖ j6¶*vöŽNÎ.®ŽnÂLp Z¾~þAÁ!¡a‚¢áN‘QÑ1±qñrv

`yhËÆÍ )*™Av¤¢Ò­¨—¸°—ÄcDð¤FÁPWTix}È3ÉIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_albums.xml0000644000000000000000000000056311700415064025034 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_tab_albums_selected.png0000644000000000000000000000333711700415064026672 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µPLTE`]]ÓÑÑôóóÿÿÿ\YY¦¤£úúù÷öö¥¢¢tppûûûúúù×ÕÕòòòÛÙÙÆÄÄÕÓÓãááàÞ߉††||òòò’ëéè_\\«¨¨xtt876ÕÓÓ¼¹¹ÿÿÿ0//œ™˜ÎÌË€||˜••™–•fccHFEDBB}yyXUU10/ÈÆÆðîîÎÌËOLK865¸µµôó󊇇¯¬¬hedîííûûûŠŠb``ÈÆÆ÷ööTRQŽ‹‹ÅÃÃàÞßÏÍÍìëëìëëÐÎÎ?=<ž››)((´²±wssxttÜÚÚhed}yyb``ÌÊÊ‘ŽŽWTT ÞÜÛ^[[×ÕÕÌÊÊÒÐχ……|yyÅÃÃëéè½»»ÂÀÀ¢ŸŸŠ‡‡‚$##‹ˆˆåää„SQPØÖÖ`]]òñðÏÍÍŒ‰‰755ËÉÉ›——liiCA@jggÎ3!±tRNS  %+/231$M¼ôÿJ€øö}WýûÀï˳ÅÙÔz=-6nò"'.8äa0# *:•o ,FÂ¥!&F‡¼r† …aN7VFD' ê®?Gñbš`åúe9)dµóB{°×@±7æé4·RŠ2žjZÐf[^¹g5V/ÉBǯ¯v\¦Þ(§;®y:v=}àtYÉZ(í¾xH·ˆb8LcΉ¬ÊIDATHÇ•–÷ÛDÆ¥; ŸdmoÓ\I¨ÓÔ%’Ø!–l—Æ Ä¢Ô¥Ìec 1à²Zè`”-«@Ù«lþDî’¸‘âç,½_ÝzÞ÷=†aY9^c›Jx–eIœWTM×ÒuMUâ2'!–a%S´ôD2•Îl¢l*™Ð-Ñ”Xpb.Ͷü?Ù¶=Ÿ9À@ÙÊ_;Š· ±ëò– .®ï(à-i|‡ç^IìÄ[Ô΄Â3‚šœèÿÊ®b±¸ûú±H`"© Œ¨¥ÖŸLÞpc:55•J﹩8A¤4‘‰ééµUÍìIæ ­TÒôržyf6¤õ2ÿ xË\µäÄE×uc5«^nì½uãfg(`¬…}ö|Ó5=‰ˆxÅ­©å…Ûnß}Àbºåð±û‰¨¿LÁ©û™ÅÀØ•@–Vâ)A1(ÏÝ9>8Õãb‹€¡$‰š†}×x4p°‘“¥÷zmÁu©¡';†}(¸ÛWÚd÷:¹z}ÙÎÐãcn18\uL:0c¹Ö=÷Þ×ÈkŠhzžÜ,gvG÷Wkç,¹³«vNÍGØ;³3ärÿÊQЫòª†¡©Wl}AÇa“õ%g…UŠAgF9vö)Çqª× ì°+µºoNÃiâ­ì¶z­ö `wŽòàv50{|âü²d¦!0úti,ˆjihÑ (,¾" Jâj H0Ê?gË»J>ÞĦÎ,¾&C÷p·ÙKÐüæI!6à¶¥»Àj•"@%GtÁƒ[¦À¢( J€7çÀ=K@Ÿ)Ê Ð×Ixàké1!€M¨¶ èð`Éò¥™¦m¦É—w>n%^oŽS°áÐË´ë.E¬‘9Ä}ÎÔÒö¥†]×c`B€¶+i•IÀ+ð&˜uðš$€^€=hsEƒšΚ ˆv{ämÞ?~‚Þ'䦚¶ñ\ΟX8h_…p¤Ì¢jp}É>wÙ¿YÅ‹Çîåƒýò_‡¿Œo !'µýIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_artists.xml0000644000000000000000000000056511700415064025244 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_tab_artists_selected.png0000644000000000000000000000306511700415064027076 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µ PLTE`]]ÓÑÑôóóÿÿÿ\YY¦¤£úúù÷öö¥¢¢tppûûûãááØÖÖòòòúúù×ÕÕ›——ZWVÜÚÚàÞß?>=²¯¯òòò976ÆÄÄ´²±DBB_\\ßÞÝÿÿÿÈÆÆÅÃü¹¹'&&ÕÓÓÈÆÆkhhìë멦¦,+*ÏÍ͇ƒƒ¡žžìëëãáá{xxåääpmm¬ª©! ÈÆÆÊÈÇmjjôóó'&&||urràÞßÒÐÏåääÂÀÀÞÜÛoll#""eaaTRQ)((÷öö?=<¤¡¡½»»½»»„ÏÍÍ;98OLKnkkëé踵µÌÊÊÛÙÙîííÄÂÂOLLÕÓÓxuu•’’ÛÙÙ’WTTéè袟ŸNLK„ÒÐÏðîî987ÈÆÆ;98ÕÓÓ644ÐÎÎ532ÏÍÍÕÓÓDBBÜÚÚÉΆ¯tRNS  %+/2310.$M¼ôÿJ€øö}WýÙÉïûÀˆ74ZÐ×Q("!-9œòP)8³ž ,Sa*6Ò>µ°¥BI¯h@é “;>¸w=ŒæÖg#Ý^˜C¨´añ75_f;Ô¶'à®Ée>PXD&óGŠ˜§e±MWUÞ‘¹@0Çè£FÅ?Y4ƒÎ\â‹H2oÀä-™7¸=º?»·.³8á Á(IDATHÇå–ç{ÒPÆ Y@ˆíU«(*8Rp5( ´J¥¸‘ºj­³®¸{ï½÷Ö¿ÑK«5¹mñ³ç á½ù%Ï=÷ä¼ÃpÜANå1(—“$8Ža¸ÇKÒ>?`Yn0Ø_1D0~Mz=8†{ƒÏ ¢$‡~…,‡#’¢(R$ü[ K¢ÀòTЋc’ŠªcššÁ(ÑÜ4VR¤#h^74-Tž&0ÒÇNŒÙW'MŽÛ´)Y‰9ýÂTÛë§%äprú «>Uð;1#ZŸ5s–¬µ¦„ôì9–…¸È¸0* Yä¹ó¤Ôü¶6@Ï,°,I s³²E]jÍÒ$™óò‹,»“Y7B`q!ê‚'ä¶·v,ù{)T8+°TmzŠEœ :#Ë,‡:R¥.¼X,z]åôòF€$çë‚÷0 !ÎG t´QÀý_…†ùßÁs`FV¬\µþ„ÿœta üÖVÖÆ‘ÀºJ¥² Ö³œ*‘µTí!°ÊsÀ¤J&±aÕl®^­]nVÙÀæL¢g èí +¡­lÓËUÂãñæ²5y;;$)чb;=½ €Ýá_Íåè66¿€½û …þeèMo–4}?Hµ²?;Ÿ+<ÀaÑ3GÐÀѤnäÁ¼— ‚ )'`Îb'5C95LZçžN›ÚÉ3°c-ßÓßö\/Ô΋¦ž¼0ÜÁõ%uS¿Ø2ä¤.åMC¹Ü2Ð|%b˜…«×ÿ¿ž6L1qcøÒ˜yS1LíÖ¸Ûõ~tçî=Þß?m¤Zºÿ@ÒLCÏ+c>J‹ð2ßñ86bñ=¹ A­ÕC5õÈì¾Ø(Õš‘´T€aÊœO>›a¯V[«|þâ¥ày¦õÕë7Ñ*mÍÆÛwe†}o÷™z3¶·ûz|HqæG»\o÷CñÉTóŸmꀡ , €/š™þ –…6Eøñ3ÚѶ[ßÃ7´í¢ý;ÌÒ´±ÛG‡pÚàøR)Û­þ‡Œöᤳ;Ú^¥._îdíà bü¡\9’ º‚t•²??6lIªãŒ¸ÍIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_artists_unselected.png0000644000000000000000000000133111700415064027433 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µÆPLTEÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€8›*BtRNS$¨ðÿ!`öó]0üÌ·êù®'ÀÉ{í™~-Ü–‡ 6áo¢KfÞ<Ò3u 9ÆÕ“ºŠ?±Z½WØE«„¥b‘)€IDATHÇí–ÛBÂ0 †Ç! ¤P†¦ CÆDÐ ñ€gÑ÷)ÜXmS˜zE®²4ßIøƒeý»£³Š¥2ì°r©’åÛUÈaµƒ4¿ÎôÓF“k±V=íñ6¾}ûP;  ÞË=J>¸£ðPÂ]oS¢cåˆN²šöX /uá40? ÷y¸ö€°³Qàè[cN¡p¦ç"Ü!ú!@ € ’À }àR®"I€Í… àgù‘øÁbÔ§?¾à"ÍÜL0ã–îðâëò?5cmFCY»¸h Ñl £BÁ›ÎP0aij\ŒbüP“:å£{5P® z÷Ó7†j¼Vï‰y4ÜÊýÈn¢…ËÞZîím³ô˜jL1J<ë‰m¾gOY(1Û1­üENWœï×i/éÛÛ{.1ƱÂ\é{ÆÀ‡>Áð¼7­,à˜—" l–"±v) [»Äb׋ý÷þÒ¾l€-*€ÔIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_playback.xml0000644000000000000000000000056711700415064025343 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_tab_playback_selected.png0000644000000000000000000000345411700415064027175 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µ1PLTE\YYÓÑÑôóóÿÿÿ¥¢¢÷öötppúúù×ÕÕúúùãááòòòÜÚÚ¯¬¬_\\ÅÃÃA??<:9ÕÓÓWTTSQPûûû¬ª©ƒ€€ÿÿÿ‚‡ƒƒ´²±ÕÓÓ~~«¨¨À¾¾ûûûxttÒÐÏÛÙÙîíí987™™ÕÓÓÂÀÀÈÆÆ®¬¬<;:#""åããyvv;98xuu¬ª©xttZWV<;:¢ŸŸfccãáá_\[’ÐÎΡžž^[[âààTRQâàààÞߤ¡¡ëéè„}yyâà஫««¨¨„ãáወˆåã㎋‹çææŒ’khh?=<ÂÀÀÀ¾¾b_^ROOìëëØÖÖàÞßÏÍÍ[YXxuuµ³³‰††ßÞݘ••ÅÃÙ––‚xttãááúúù™–•xuuòñðòòò'&&"!!ÛÙÙ²¯¯sooËÉÉÛÙÙXUUÆÄÄØÖÖ;98Ça±»tRNS  %+/13$J¼ôÿ}öWûÀøÙïК[742°M"&,KÂV#Yý˜' )0:u*vw.uªY-5• ú_À·èD(8mÅ®±—J >ÛhMY…ZZ@6OÖU°ŒVÍX8!+Ó×4ŸZbo?ÌõgiíòIBÇm·GÎT³ÉL©7X(ïIDATHÇ•–ùÓdÇs5Is4Ï“&éËF)0Öδ²t-¥iZ ¸ª+S‡XÜ”:¯¡¢2QäR‘!Š'h½&Þ÷}ýu>©k¶¶¶ß_š>Ï÷ýz®Ï÷ó<†ãIùh†½n0´" Ç0ÜÏQ¼ $຀žâü8†s2Šª…Â׉¦* ÈÈŽ‰nØ8 ÿO lÜ0‘|0:8¤÷CƒÑ Ob”6Åôž"¶ æ•ÍÝ}ñ-[âÝ­›чÑuk{ó¶áí#‰d21²}x[{ÏV5@cŒ¤µ ;zCRU ´‘ÐH¥Ã7޶MW“ŒÉU-;Æ´ˆ¦À²™ñ¬”S;w¬êNaï~W¸`‰]¤l>+JF©¼{WÞK»ô€¡=š‘e}6:O|/NÈ RŽ6²ÏÛõ0\ äoš€Ú&üø^8ç3¥›o¹Uu&«ûòkû58î#ÿKG9¹M×o¿cÒIW÷¯L‡J+Çq?Ÿ5¼+]Kšîbc…,ÝÌÇýgÛoZw»3 µTÞëf5‹µ‘zÑjI™f´«0}ÛsoÈQ«³@þ0:v­‚¢Íˆë°žSï›sǾÂÑÈw3!€hæO‰°öà‘#M:jòaWöqÒÎt9ÞÀOÒ¢1Ôm:úxY«>á~=é”BÇ:€1¥"7M8¿,ÔøSåòÈ(úxº”J?ÓÄŽ/d(wyöDë`Ÿ{~²|)ö…B®v*æ®øN‡¡`»€ÍZgVÄvVUµ³ú¹t®®$N»âó€9¤CsLýÅà%§PzY?_«ƒ\r®' U^Ñ/DetëL録`,ê ËÊ…W¦´þ¢O¼ AýPŽÇzØÖùzà5øº~1Jc=ܼÏZP eâØZÒÀ=i\¼\ƒ"ÃTp¡R«ÒÈ¿­—ÅÇg²„R6ÃËü¸„5ìŸþ¦˜"=y3‚ÀÐ2ÉMé’~¾œxëíîzšE®U@¤m“á÷˦´¨Ÿ;ôî•®ºzõ½\–•9¯DQ _Ù´õ÷:K4ÿáGù%‘iËð‰¾Ôø´ÍÜ“^j\û,þ9ˆdø–Í4ó Ÿh|¡/}ïf_üú›o+Ø224-t™±œïôïÚŒ¬é­?üظöÓÏù_&Ï*mªH Tõ×UÞÚ´Jr?û½Ñhü¡Oÿé™±`ŠX«^é4ã–Ýü5ü·»»³‡=»WÔä?³]vß÷…Ò÷•Õ÷¥Ø÷µÛ÷ÅÞ÷Ó¡ïÇI¿ÏŸXe;•7–ŸtIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_playback_unselected.png0000644000000000000000000000136511700415064027537 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µ½PLTEÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ßÈK?tRNS!¨ðÿ]ó0ù®öÌêÀx*–$üuHK™6rl«áN±“ Ï<3f'iÉWœÆZÛÃÞ?`‡çí ·oŸ½¹§êf¨IDATHǽ–}W‚0ÆQ¨`0ÍÌ A ÍÔÞ¬¾ÿÇj3¶;ˆNÝÜy¶°»g÷ª(ÿ-.īڪ†~Mmëu5CÏ×wLÔ(ÌNXpÎîvm¨ZÐcå¾ã~í×uúìL/˜×ÎÊ9òÌçBÀòù´úV €‡¢sâ*À‰ndˆ|NZ_Pm„…ÀXã’$áDLDÀzI%òÕ5U§0}ÜЉ€ª¾ €PäÖ1R9ä쉀ٜ¾;"²‡9 `ïÃ"Žô7Ñòm°,ÉŠJ«„ oéèŽè1ø% ÉŒjSb@íH·ÍfZé:?ØUÚjmˆcš °-Ýé¨0[D¬¡‡ÓÄ–æ%`YË0ÿ ýIâM¯Óà6]ÖðÜ7×[ÃÕõ¬tä@ÐÈ|̇võÀ®Ñ*xö{µPù+ŠÝ~¬tPÈCžìCp°@²ºé‹ Y„ž5XÈ^^evÄoB@X[ßgdð¦Í‹±6vŽ4»¡Ç”ûPTtË’nŠÒmW¾±ËÿuøËøœL-ÜB+üIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_playlists.xml0000644000000000000000000000057111700415064025574 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_tab_playlists_selected.png0000644000000000000000000000154011700415064027425 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µPLTE`]]ÓÑÑôóóÿÿÿ\YY¦¤£úúù÷öö¥¢¢tppûûûúúù×ÕÕòòòàÞß¼¹¹˜••ROOÛÙÙ•’’›——òòòãááëéè976ÎÌËÌÊÊéèèÅÃù¶¶Œ‹ìëëåããkhhhediffjgg‹ˆˆ[YXåääÈÆÆ¯¬¬ØÖÖCAA?=507G£éÛhfec}_ݵšÉ;TRk×mŠ®¤o\Ú“IDATHÇÅ–YOÂ@€·ôz-”–Ê*J â*( EÏâ}ëÿÿ.M ¡°£~O›4_ÚÎÌÎ ãQ’ãS‘%Qàc—H Šªé„©H 4tMU„d‚\2-›0cÙYg 9ÛÊ@SN'9ä|an¾ˆfPœ_(äe!xÅ,,–KËSá Â²‹¨ðÊP€¨e*ˆ’JF¤[UZ¡jé Qc2ˆÃ,½…q"8ô‚3R¡°R›]'õ]XÅkëLB766›äàn±!´Ú¶¿ÓAhã=¿²ßťɂsh9÷Ð>>é·Cr>ÆÅÈ7 NÏ\"tÙ~ˆÓˆÈ?œ_ÃåU ¯C†ApãFDé–-Jw÷.[h2ýCáH1î6ü'ŒŸ½ÉB}$ÔuØ…ÈOzñþ+J¿/t‚ x}#5ò>V|uwVX1Uy³çác$|Ò_QÔ]xòÌo½?+s«dmÆÌížy 0,æ¡ÈNÁàùTÑóùß+Ýæƒ”+×ùª¢Q5jt¤– uW¡ž tæÓB£Ê„ Š-‘Ú$•6èØt²gîR?´ (¤<,Ÿo†#%Æ’ÓYvÏ\YRZÈRZ®Ô¯­×3¥mô\ˆ IçXå‚õH»è[)½_H²,ÛÈåÑX¾X}ëNpvÿDÙÖZëŒÌŸ@Êÿ½8gA\(âÊ—¢¸våÅ.:¼“ †*úúànIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_songs.xml0000644000000000000000000000056111700415064024700 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/ic_tab_songs_selected.png0000644000000000000000000000420511700415064026533 0ustar rootroot00000000000000‰PNG  IHDR00Wù‡LIDAThÞÍZPTW5vD)ŠˆJémi‹Rƒ¨†UǂذƒeÐÇ–ˆ=¨ˆJL4bìQÁŽ£QD°#»bŽkL¢É{7çg^6vÿßÄ?s]üå½{î»ý½jÕþº>Õ ªET‡¨Q}"3"ó*’¾©‡1jUƯŽ{µ‰LˆL‰è1^-ð(÷7óÒÀu0¨Qc¢¦D¶Dv û·?û˜¨9Q¢†`¬®ˆÂ–DÖDÍð­Îxv˜»)x±Àwº‚ÑþS“™aPþ؅ȋȗ(€Hýâç~DÞøŽ²‚ôê€ñ¼)2Xg"Ï·Ìáû^Ó¼™ ‚ѤÂlxЄ¾};–•–¼xþüE¥×ñ’’É`ÔÖŪ4J:´å«W¿ý\•q˜æ¥O|¼€mÀ«$­^™óºo×L¥Á­”qݹ}»”Ær„:YBŸ%µdµp=V|t>cþòòå˵99SÂ<3ïZ$<¸]ÊèÑ=_¿~ýG¥Ì+sá±Ì$˜µlÉÈȧ]›ÈúÎE‚}ͼÕÐ9Œ €¤újø°aÑHÖ¬J4ˆ¬>#åD|£¸ïÞõÑ£FÅÁCXÁO7[¶hz列yŒ ¨°0ÏÍÕ5éCc0oŠ_NꜜÂ)œ’+(Epæº<+k:¢£”š Õ¯„ClLtTŵëç•PSÅ<{úäEÓ~ô­ úmu‘ÒgfÞvÔð᚟=ºW©Ð¥ÖãM$Vö<3Ü¿M ÷NÙK—&W*xÉ@Ò|óiT'%;0Û¿ÚwÖÌ™1K-êÅnÓÕÅ%Xn‘¤.*öï×QU’¼5ü½ƒ•••;ôBv§ôúïT¸pâæCÆ[øAؼaC xIç­áó{Ç÷ŠúñîÝ2ñýÕ+WãèÛ#.®Í„qã⩘µß¾õçÊÊŽpñóŸ`½§j+e¡ÔBÑv¦¥¦Æ?¥w)…8±`îÜž(#mÑ©p@5Å«§vlÑ¢-œ¯oóÀ`:Òoæ&ŽßKÔqJè–À¸ñžµŽØ!Õ`RGµmGUÛU£2`À Áë°T[ÄDEEˆ.’2ЕH—ÝðžÔ˜²Ò!ùþœÜUµ¤5@Ë@µRs¹_»r¹Hz~åÒ¥3P1¨Š´€4Ū‰8G4“GŽQ•É`a!Á±¼ü.””uŸSDNG9©‚d©¨C4Žßgu³¢bYiéjr³Ý‘Z;ã—¿ ã’Óh&¤¤$#e`æ<¨H™)>ç,夯‡»[ r‰TЄ‡…Fr5&ºSn€EFD„aذƒØÎŒ `Ïžµ‚„U›Ö¯OC=Ì*Hù~ŽøŒŠ›4–ðÚœœâ}y*Ç”1^šÑ°‘¹»¹ÆHÍפ¡Cãuú¡»èþ'\°€â3.`¸ÄÆú¯6‹F‹Z9”Û2F dßmÙò%·D°­N;¶S|þù´i)ÌûøCn–ÜëÃî3&ÑerÄðók‡::òì™ÓžJŒMN%Iš¥¨Z(®Òô´´‘`(”ÜlgòN'ùÙ „„¾|"ñ·Ë‰dâñžÌqÝ¿Oï( ÿ*{ù ’ò]écÅG7uïÚµ3¯朿lhïbV=ŠÚƒ(常+?Ÿ#q¤ÊÛ»½ø½ÑÓi.Þa´ ¢5¤š6yr©Î7§NÏ%U9O«³—÷(ØÝŽTÎ^˜`5š…½X¡5ÊJb…ÞG ô=ìa'0!¨­s’¤:–Ø+cV»¥pÅà›è”šzö0ä¸Ô6—ÎAˆÇ`Þt ¦6Þ3ÎMÔÁ¯4OCŽÛü Ütä¥ÑùIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/ic_tab_songs_unselected.png0000644000000000000000000000174611700415064027105 0ustar rootroot00000000000000‰PNG  IHDR00`Ü µÿPLTEÿÿÿ€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ü+ÉÅUtRNS$¨ðÿló!`öÆ]0üNù®í x¢ ´êœÉEoi„BQºrZu·?<–6Õ-Ø™½ç'áä{K3fбÀ9Ò*‡WÃTŸH«Þ“ÏÌÛ~ñ×ïAIDATHǽ–[WÚP…÷Fv ¢4’  ±TÄ RZªâÝZë¥íÿÿ-} ¡„•èéC;/YkÎþ²²æÌÌð߃s‘¬Ê,d‹7uΚf² ù?úÅB\®¥èýË3I«éKöœ^N¼=rK!°2¯/{$ýÊêr•µÙüJÔç5’ÕuI|7›¯‡À¼^ ’›’ÔäVì xO~¨KÚ&KF€CnH²2“çëÀ"Ù’ì6É#`“lÉ^$É]# FîÕ:$Ù´Ë‹.n_F€› õ]Û8B}ïP&@ßõþ‘ €B{Úxë2ÑçðãPÀas:jŽ €O¹pDƒýÂë€LfÚûìÚ£ø($­Éh®KúÂÜñÉé¸üpè »éì<*íI6h RefÍä.R\¥«Ø^jÖÓ€ìJg^|‘Û)À%€kIE’léoº€í`À‰¤.éiRØ¥€V py*é+’î|KêU tOÞHÚgS’r@#íâ*î%}§SмÜðÚÀKõ-2w¤€·ÒÐuS›o€,>JOy6Taç¹ô_hoË!ɽÛþëç>I"óüòÄ­äcTmY¯ÎtÍéMõ¥²ÑšÑÁZÿ©ß Gf‹,Š€¼Kæ å ÿk5+Iò*ÉPâ–5pH²w/éŽì$YVÌÝhÏŒ%õè¹ ¦³ÝÕ¨@[’®Éa‚íÆŒ}g({¤•dìÿëð/ã7¸Ú@±Ä±¥ôIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/icons.jpg0000644000000000000000000004406311700415064023346 0ustar rootroot00000000000000ÿØÿàJFIFddÿìDucky<ÿîAdobedÀÿÛ„       ÿÀÌÿį !1AQaq"2‘BRÒ#S¡±br’²3“ÁÑ‚Cs45c$ðᢳt%ƒT”E6V!1Aq2Qa‘¡±"BÁáb’#3CÿÚ ?õJBBP*B¡P*€€€€P€€P€€€€€T  T U9¦Ž($ŽÒÆ\|Z²ç!0×»XÃŦgHìàÐê|(&Õ–û;ÛÐ@Õ–û;ÛÐ@2e€©†~‹duOÆÐOixÉÚZc–#Ibu*Òy|w½¡¤žq$ö‚É——w]´#É>Ì’¸³PïzPO¯-övÿÌÐ@Õ–û;ÛÐAü¨1@G„÷Ok{æHè$ŒÃpÁSãP{A ‡9 8Ñ TžÊ ³W“úÖÐ7Ê>Ì’¸¶£¼ ¢ ƒ²ßgoûoú²ßgoûoú!«+öVçÐ÷×÷POmvdy†Vgh©ŒšÔÖžÔUà‚ÄÞ\Lâ-"cM Ïv–9é .(&Õ–û;ÛÐ@Õ–û;ÛÐ@×–û8?˜ÿ ‚0Þ?Ílù2ºº8êk©Üîôh,{+åtV°‰ÃI$qÒÀyÒ¼IøG^[ìíÿ˜ÿ «-övÿ¶ÿ €_–û;æ?è 2öVJØ®âò‹Î–H×ja=‚¼%åPYÏzñ?»ÛÇæÌ_S¥Œ–¢‚]YŸ™mûr}×™ù–ß¶ÿ ‚:³?2Ûù’}|º€ƒwDgƒ¥‰ÚšßÖÔP^‡ ´¸½p¸÷x#3MJ¼V`<‹Š uf{#·ý·ý Y¯³¶ý·ý YŸ³¶ý·ý7wz×p´CÛ,N. ý`CM_üÈ-nnÜÉ0FeÃPmhÐ;Ü{Sטù–ßÌ“è Ž¼Ï̶ý·ý YŸ™mûoú%uÝü 2\ÂÃöŒs‹G}P‚õkØÓV¸×ÐPQº½l‘µ†I娎6ó4æIì(—æ+_.ÜʽõýÊ Ž¼Ï̶ý·ý yŸ™mûoúã'×41>1íœâêw€æŠ »†VMdaÔÇ ‚‚t9?bݧÙ|ìOô ¯¬WÓð åV_ˆ=¾ÍÅ‘Åf¬fÇZYÞOgP}tN÷yL.t­hÕ\ÂkBƒ§Ød¬r‘ÞX\Ewi0¬W0¼HÇ6¡mc·µ»H9xÈùvï.ñ£ÙOЍ#™%¸ÙKM ,iô9íòÁh h ÙN9>ìüCâöþ~ûÌÝøÇH!¹ºd‘FÝtÁ­wJ Ëõ ¬V»9øˆˆ¸É?-îcIb6°7ƒ‹ù“­ñw­–ðÛ‘f­`’Ô>Ia–Ö}%ì’ oi-õOð!ZáßóÖ%§‰{ÚOnÓò «—¨ÇOÆ•pñp*‡Ñ@'¿öf*ñöY,Ý•¥ä`-å™­{Aˆ-?ê§NÿIþ{Pg±¹ŒnRÍ—¸ë˜ï,寗qÃØêp4#¹.H¶No9„÷‚Ú ¼¹%¶Ò‘Ì1Çâ,™wmeŠdó½°ÛÛÀ$–GrkÍNq§€AK¹0yü{2[Øroà&Ú€=ÎÚ|SÇîý·Ë^aì²0O•Ç»Eå“]IX@©õM ©ÞÚ ¯šÎâ𘻌®Vå–¸ëFë¹¹}KXÞU:A?‘¼Y|vWc•ÆÎÛ«+‰#’Úâ:és\iQZÃɹ;n Ùù™ognžêy Ð .q#Š ð[‹žÅA–Ä]2ósSorÍA®¡ÒhyŽä²›·nb²XìŽF l†Aâ++G¿ëds¹Q‚¦‡¼ðA_7¸pØ<|™ÅìVQŠºyœ=sqðPS–þÓ!„mí¤¢kIÙöÓ³“šç4µÂ¼Pe›Z  ÇØó/<Ìï©ôp‘­Ô^ªaölQÛº#Í]4º×†sLóÂ8ÇyçØƒLéwU·öíÞm‚öÖmù šGÉm¦6HÀ ¹¨ú“N)ò"þ÷9g±ÂÁaiuzë'drWËf‰]{„M4ÔYê‚yóAÙîHu¤ÌwÆí\?Dñ*X’ë8MI¤“èAmfáæ^ÌÎZOi¢fÝÛ’&Œ»í$þT5ŠÓ·¹vï,Ô²¶¾ÎLm¬înYh.)©¬’Zét”äÎJ ³g‚âØ:'²X&Œ¹’1ÁÌ{\+¨8T{GK±Ö¦µ&WöB 0ùë×&±ƒG$Ä”åǹ4ÝpÆâ÷u¦ÝÇZú]Ãi•ÈkÓ»åvŸ-”É#Iì”þênߨÿw;3âÉLøc’5†0 œòHì<¹ Ù,oí/­ »µ•³ZÜ1²Á3xµÑ½µk‡¤ Ž'ý>!J—5£Á® ~djÿÝf'äÄÀßA&¨. £¿àAÎ:‰Ö{M±“Œ±9|³_¾®ÒËhÞAõ‹A.·ˆcBòÖˆe*Rמšø™Yº©‡ŽbÖØÞËM+awôÂàªNò¾ÉhÇ¥_Mz«Þذ»‡š·y±ƒG´ðsÎiåùг%o³à¾)Òñ¢ë¤C0o²'–Ÿ´¦â¾@@AÌ82;gˆWâ((œ„!Ü çÇ‚ æó˜Ø·v9n"kÆW#V¹ì䧈'¸ `·ì»vìÞmüË1ò»ŒÑ6F>Ú_ñ`'C¿XPø îÝ0ëžð¼v"îÓÉÌG•ÓZ>ÒF³›µûPŸÑÀPt›I™.R2ÓZ[¼ãb ùÃLd§¸Çÿ˜Ô=þî$öv òOQò¸öo× “1²ºùúXç48Õ­ì­PoyÉYÃ’ÙÏšFÆÃ‹™º¤!¢§ÊíqAº~òÎéùs­ŽÈß¹Žo¬Ò ËÏ8 èÞó—Ö!µþ#ùŠvP]æM1““Êýà‚‹¯ í¯ ”Pê>K Rw@º|"CvÃõ¥¡Ú|¦Ó™A€m·_âÚþÔ|Ðzðû}h:rÇBG–ëûÓŽ-§˜9ƒ¢›ˆå»² æ$qãú¥Nïü¬ÿ¨ïÝ(5=Ûwû.Ñ]C7güƒÊ›wC…–Û!†Ê·k,°5àêM:$ì#âAn7m¾K%{˜¾»‚´×²\{ͬ‚5ü™ÔÏÓ˜ëžF÷dävæjx2Ì»‘Ûd™#q®ÓõìL­ ö›Gw í}¸ý*Û†ºœâ)ÄnÈ„Dò(9¯SîàoI³my¦›3RGªp(8^Ûë•þ/cYm¬,°cM»¦mÆRY"’c®Báîñ×KxmÕð5›Ûkg}o˜‚ò¬¼wܺæêQ;Ÿ#íJâê¸ ñAužÞLÍÏ6C9˜fJøµÞ[䕑׎˜aiÓ{¨+âPzob\ÅÿL°L‰ÇÛ‘ÝÅùüßd|0Ö—,cçc>½ç‡¤ óNڒ˨[»)/k,÷Wð5ÃQµ³•©§²£Ö¨=+msgm -íãÁ@ŽØÆ€(4´pAÀú¯Ó³µvÄY{fx’öH²æåçL±ÞÈçŠ4ðo–÷z´AÓ:E¹åÌôÓsu)žæ(§³’zêó=غ0òG:€t<ùð™ùḇÏÁ!pl’ÈÇóì á⃌d? {cÜçv/3|2<_kï:]™]@<±­’•íiàxö סëvüž6tÆ(K·Ã§6ʺFQ±Bñêù­äÛÆš¸ ¼Ü=8«d¸ Ùr;Šîé–÷O¼1¶Í­‘®3L@éæ¢âƒ±ìm½ŽÚ;^Ûkq5Ë-ÃË®%¯­#ýg–·“_eƒ€Aµb¿Ó-ü&~èAbû–Ã}yPx¹œ¿UŸº³ÖÝÉ·÷ÞO o›f6ÊGäCä±î¤‘‚]¨µÜjƒ•Znìæ²¶·¼l³{Ôcœ\ç½þs\縑ÅÎÏ ˜~¬^FfÆÞž K\øßØs¹ZŽ;ù7è·†y4³aýºy´ñ×Åõ…ÝÛí°½@ÆI`ß&,Ã_ݳh\Ök 8™£Ä¥ã£5tü‘Åi͵·W/âß°¯×ÎïžCùUöC €€ƒœ‚ÿŸ˜ °tgQ=ˆòþÀ Š£± ³\:;Ýå/¹ÁÁÃlàéœ;¥”jk+ÜÚŸBAmí©·öæ=¸ü„8ûVól-¸”÷qs‹Š æ5´É·¸Àÿßb ¼çú\Ôïgïµ9ÌõÅy ñX¬­ÕË,Ža~(Ó@EiÃÅGüUÛA)Ù1ÌàÖ› SÈlh:ᢳ¥Vg »À×v.:¼ ¥ý•~{ÿòÊ †oý.@ýàƒèΪ òWXúsºïº›½ƒn^ßZÜÉ–÷0Ä^Ç7ËGˆA¦ÿÒÍßÛ´²?þ3¿©¨ú€Êazgec’³’ÂçÞn¤Ó7KÃ$’­$x€ƒ£@Ê_Yþ»¿ufïü¤ÿ¨ïÝ(4½Ó äÙ™v0½øÉÚÖ4T¸˜H¥4Réçáçrîæ[ÝOk÷.ô_]´¶Gí 4sÏ‹¨RwAó—Ûã/·08Ùå²ÆÜ˜NJôyP¶: =òÒ‡Á¬©AÐ÷áÛkí—î ŒŒvcq²×êî4‘O/÷xEMiòSèAÔz/gqiÒ­ñ> XÆ—Dö–¸3ˆ¨lî§÷ïüá•3øü§H:×6àŠÝÓâr2K4,=µÁúèšO2'q¡AÞ±}Zé¶NÀ^ßµŠ*jš+‡ùR°ö‡±Ô K®}L´ß¢Çgí&¾úÉ× |— i­åÈõcŠó,i5.䃼ôëg;hìQAæÍݱØ;‚ûlemä—oæœÑ¿kj^Ý_TZxýlnõ\ÞeTÝa´Ì^¾(il7T¤N<Ÿë³½ä·V*óÌg zÛ˜áŠ&F"Ó$l cØâF“ÑU³n¢ôéµg^åí¿§ßâøòW¦>žøö²;3mff½³ÌfüÆûŒ"'5–´5{‡p¯ úÇ·RÚaÉ3Õ~Uð¹ú†ïi8±~S¬ºN RÚ_ñ¤üëJlŠ »Iµl€TBöÈú|ÑP~*Õ^‘lp¨päAAga·°Øë›«¬~> K«ç™/.a¬’g»™{‡T‚îõàä±n¬‰{8Ç F78rÔ÷= ºÊÂù¬&c}ªߤ‡Sᢠ6å`‘†­waî>! )Ó­–È;#”ÛÖ7·ï¦»©¡‘Úh%Æoemlè·¬=®DZ‚ÛQs¿-§ ãË‚ Ìf‹²ŽÃgŒ5ò­`nˆÛSSFŽóÅË#×’·k8˜5>R8€ t†úMP]å"|¸ùØÁ©åµkTÕ«eŒK;ˆÿ·eDFñÁ¥ÀvPÐ ˆl¿9ßA Ö¦¦¼É¯$DÆ¿#ÄÁ©òÓäÔQ ø ÊNÂødŒ|¶–ü` ÄZ3]´T'[+{Zö€_‰gD纮=åËy¦ºG²;CÝûÅ|΂œñëžÞ&WÈ׸w1œkà;f"ƒ e–y ‘5¹-p­ +ÀúAXÂ{©à8ø‚"7 PíÉ ‚9Sš 7qÖ/(w41½¦ŽŸAš;a™‹›‹w¬t†FòšîÑè<ÐXnM£Üاâ³Ö1ߨ<×CÅÇŽOË\;Â?øAٳ݉­sY h+_!íŽg4V´kȪ û`t_dl‡›¬U«îr¯n‰2—ŽógÒyˆøÆè ÜnšÈà~¯ià¶6v¹ÎïA”´ñÛE\Æ5§Ò g–ÖÞ\ÀÿnGù¬9¤PÒ½¢ˆ* ~ÚPž+XñGйÃÅÄ“ùÐYÞ5±ä„’pŽhÃãÈ=§Ù>‚>C»¹öŽä÷ØŒ}üM†þÎ+¸šñ#cxkÚjÚû.ñ.ôÍZ‚êŽF¼½ Ù—0‘Á±´É)Ñ9¹ËǺBãÙjç9¥¦Y iæ¨%y¦¼Gr c±¶îqsKá©©=ìâ(vCö÷Ï“é }ÙÛÜ>O¤÷d=²NáÜé¤#â$ ¾´dqÆ#o ÞH+;’ tÖ0K!“Ö‰ÎöŒOtdŸ$UŸvCö×Ï“é }ÙÛÜ>O¤€qýµÁôÍ!¼‚òÊ(`g—ÎßW·Ä׊ ‡r¯r l¶ò¼È¢yæbs™_N’K÷d?oqüù>’Ýý½ÇóäúH!÷d?kp}3Éýh/,¢Š˜ã``çô÷žò‚äŽ1÷6PO)ƒùkÅ>—4„þì‹íî?Ÿ'Ò@û²·¸þ|ŸIîȾÚçÉô\YÛC-c@.öŸÍÄŽòy ½AaumÃÁsK\ÑFÈÂZñá©´à‚Ý‘}½ÇóäúHvCö÷Ï“é ‡Ý‘}µÇóäúH+ÚZÃnýMn§»•Ĺÿ_w ´½‚Š2FiùG˜ýR[ýß|ŸÌwõ }ß|ŸÌwõ }ßΓÒ$r –övðÉæjcÜKœ= ¿ZÞC À ‘pœyƒà‚ÓîÈ>|£ÿªÿë@û®Ÿ7ódþ´»-þ|ßÍ“úÐT·²¶†Q#[ªAÀ>B^à< (2 ×qÇ+ R4=§˜#þÔAi÷U§sÿmãúP>ê´îóýhuZ÷?ùþ´C¶†A#WŽNy/§¢¼d¨ª 7-kÙå¹xw0áP‚Àbm(×€9÷ÌPGî«Nçÿ1ÿÖ÷U§sÿ˜ÿëAñ¶±È$ .sO#œÿÎPd£5A2 $mS-A GHA4M£ª‚£½’‚Žž!¥B”Fß\]ì £¥4 Ž” ("ÆúõîAXò((iA 4 ™¬¡+ ¡§ (!¡@@Òj=(.Q{}câ‚P4 i@Ò‚¸äQ{}b‚P4 i@ÓZ ®9žßZ¨!¥J” (*d ’AR=$¢é@Ò‚B ±Š5È áP‚](P4 iA3EDòA&” (P4 ‹[CT#‚ t i@Ò¥¢ŽA: x i@Ò¥@ä‚d i@Ò¥Cx ™®oÒ¥J”„¹¼PCJ” (¨'A+‚Qˆ@¢ Ç$¸T †” Qˆ&o$@@@@@@@@@@¢(€€€€€D Qˆ@@@@@¢*‚A€€€PB¿PD  (A  ‚A  <F¨  …P*‚(@ªjAJP*€€€€‚ÿ¹¨" äƒÌ‹i›koº¾³ GÎ{¾HAn,³·"·9w¯÷V­hÓá­ÁÕA7Ý(‰tiË»8dø¨"ÌÝZÊØ2Ѷ/0é†ò3õ/=ί°OŠ À5Ay ½Œ"I‰%Æ‘ÄÑW½ß5£µƒFཫŸ#q±Q0 %¡ùÎ<ô}ÉzÚ9¹{½]š‹ kèÒ‚S}˜Æú×Ímí öîan™;ßhô ËÛÜEq f…í’'бí5zPTAiÉ[XÂeÄt±€UÎqäÖŽÒ‚À Áë—·¹04I1'“PGîKÖúÍËÝêý-oÅ¥®»Íc½{ÀÛëAíOtÊÁÞævü2¶×PÜÂÉ x|Ok‚ µAm}‘¶±€Í;¨ÚÑ­\çMhï(1Ìv~ÿ×ÔÜdT3H’r?J¼‚?r^{C/w«ÄǦ¾( ë¼æ8k¹kr£Û–&蕃¼³“‡¡RÒî ¸=»Ä‘yÞ#‚®sƒËÌÖKÖ³`°´RýÍ‘“Ö—/s«·Ê ckèÒ€msÖ£U½ÛoZ9ÁrÐ×D§Þ7/  ½Ü_ƶ“Úoˆñ/Ð@’ƒ6fââwÚ⢽†’ܸÒü+ò¡§””Vç+3_ómÚÈÇå †jÜjµÈ™ÀçÓAûM ¢ Œ~gÏœÙÝBmoÚ*bq«\>tnùAN¨´àƒ{šsn •Œ>õz=¶ÖŒŒwÈîÏB ?wfgõ®rŽˆŸîíšÖ4|.(ue ¶ÊÈãØÛ–¶FŸI-sÇpÛL”BÚáü"‘¦±Iú§°ø`PYe²ãa-Å5<Ø™óžî  \M‰³ƒT‡Ì½œë¹˜ós>È å–¿ˆh-÷OžÄÉ*ÒöæÎß#jLå¢ÚgB_4@j£´j«jƒªaóøŒÕƒr›ÈoìdögÁíœAð(.gŠ ˆ]íG £Ú{Aíâ‚Ó<±:|dï/’Ѓ ‡›à°~H2ÏxkKœhÑÄžà8 ÁbÁ½¸~bX¸¹¶1šȦ¡^×Q.êY÷vÜÝw8LŒÙA“Kyæ¹Ï| ¸i íAÞ½XÜø‰µs¸ÛK929òÑqâC >¤ÈtîbœPfzEÔ,ÆñÄäeÌ[Am{ºÎ÷bã|,•®þ°>½A´[ÿ홆ÂÏW‘'C(çHÁñt‘J“AN(08Úä/$ËMÆ0LxöM`à_éqíAݽ`ÙÛW.13s%ø‰³=–Ð>V±4n§4A…ÿägO«ü<ü›Ðmû7íýáa=öò˜í¥ò.#ž7Dö<·P«]ØZAAsœ^e‚?VÃ"KK;#¸AÁÈ3ä ×`•—W9«ZÚÔHÛw61ëÈ"çS‚ fÄêŽÔÞÐbgtWšu¿t<«–°ò~ƒí4÷´”öÇVöváË]áí®i”µž[fÛÝ(Ï伱π“¥ãPåZ ¹ÞýEÄlù1 ÉÁq/ßWbÎ@Ðሮ¹5FúdÈœÄoޱ¿w—+²Éù‡Ù©xò(023ï\ËÛ'­cphäÉ9ãSúˆ1{;¨¸}Ù’ÏXc ¸‰ø‘kq$ík[+hè¨I§Ú ·Ý½YÚZúÛ}p뜕ıBl­%|bY|Ôõcm]Új‚ç|õ/kl»C.bàºæ…Ñc­›æ\ÈhŒqkHÐ º’ê&Gg¹,lqÄë¸éMPÌcÜ L¯( ŠŽ ñÀ ÁåÜr&bȶ‰¾}öžn"?‡™A¡u_¬íi~ãÀÅ™vÄÙ.®&ÿ-e½MÜŽù,Aˆé;:½ºáÎn;‹÷íù-å¬w~T½ïÊ,µÍgöjÎë®ù»ÍEï™ lfé"Èû°šâ+hæ|zˆ‘Çž¨ÀqAÞòmd–ÐeñïOnÁ,r´ÔM žÚ·ˆAš´¹ŽâÚ+ˆc•¡í>U77¾^·¬ÇlÈÍÆBAÃê‡&Wô»Pa#êÿKZ[{’ÁiµäÆ”åDpž_™¨yAºŒ„!”®­\©NÔóuuÏeâ!·“w~srØnììež8xù“5£ƒ¼ºqA±Å–Æn E¶âÛ÷ º o™o1¹Ö[Jál2UöQêi‘­,Ö=’áD%­æ;umË,¶:JÇw.¬.99…ÃP»¸ ÊáïÝ{cÏedì«‡ô —9-¥‘ò8ÝNá °ý7öüŠ q¶ÙZ¶ê÷’]4§›Þy¸žß%ɺÖÁþáÿnì†C,Ö“¶<ìÃX{ÚC¤·„Öú­¨{Éàx(dÉeÛ e*ÚàÞÛÎõ‚ï·Û='L•§U  ñîiU+¹É½ÉlàÝ>e¼Œ¡¤ƒ'ž‘Ña¯ÏhDà>DÛK¡¤1ž«ÖŽÎMAæ>ºî¬^;©yx®Þb’k[ct“ýÑ ÷Ts6¶="éÍåÍYnÂÒ_JûVÄÃøjÎÚßaw Õ©ó¡“!ké§‹m"ià}:®fì>Öè£â¸‰Ì5ã]TAœÌÈbÄÞHßi°¼ÙA‰Çܶ}´Mƒ#`à|y·¯§‹ê}ؼ%ŽšÆÔ²€¸Ðw пêÝûcü· î߆œÝµîpÝZúð¿#C¸·•³G"ƒ©g.‹ìAòèø¦‰ì5íЃ`ÈÊèñ×27ƒ› Ü=!µA­ûËcÛ‰­«}ÉôãÚbq'ò ñŽ3}à ·°>õ$7vMŒÅs{%ìíkÛÇúR²ß8Y,´ä._5Ëæ–igs­Ï|…Þ`si¥Ýµj åïUï÷ÎÚÃ^_•¾? ÇÚÜÊÇ †(Áäö^Þâ}d½Üzì%:(b|ooƒšàƒfi«í Öð²Ô9Ì«æžYI¥\^Gô òCº«‘ÚÛ‹xã,¯Ž6,–EÞõue×Tç7ˉüZÞ‹¹÷ ×o7Î ÜemËÙtç2A1kœÿ1’5þa{ªK…+ë ­¿ðs²öi.举»3]JùdsöžáZW³ìAìl=È—cØBæp8¸AãÝ(6Œ<Ž“f÷{N…„þÈA†°¹Ó”ÉÈ[Wºà3ÐÖ0Só óK²Xí×Ö[¡‘¥Äö·7¹;‹yÒéâ“ˈyˆÇzhä\xè'ƼPq^¹à¶žÞØöyk (±æÆÿë$ ¾f^¹ÆvÈ}§ÕÇWH6Þ„g‘é~%îÕ4q›‹hdujaŽG5œøòA¿íGabä>FC^à?" æoÞyƒ+5ë{!5ååèö~ Ò²=é•Íͽ¾¸Ù¤c´ÞÃ+Ë¡u ×G’ÊÐxQ ¶êV฼‡¥MÏÛÅ·]yî‡q?G’ð!çÍiôWJ¯½:M±ì1k<[âÛ×’ßÛÚÍœ™ï3IšC£>_™/ÉáDCobðûwgî¶6à€ÊÕîq©tqâç¼ñq(2{UÄâ´R‚9¥£À<ѵÜúw$Ž#W•jÐÊð¦·þd]ë§Q.1]NËØK{}°ùP[ÎæF¢ZæŽ%‡a¾ñ÷7xûky£&æÝ´´¶’¶Ÿ™«ó–8»N¦mܵ£a¿ÎGye–k »f@×JÞNòÝÈø ³èUãaØ>ç ´²ÈßÛÚkõL¸qoç(:ݬ£@£|ðð<^Ê”ç%¦_× ±‚YëAæÿÄWPnpB‚Ûßo`·~2ÞFCk;£n³$¡Ä€G(ƒœE»­$Ú;»8fh̶|¦²_X¸š“ë8 ¸•Cq÷g¬O&Æ×ZmrZ¾-aéz¶üTº·Þ‘A-´o‹šâÐ~%{^ ˆäØ 6ç·‘øÑq.}¤œ̵¾Øø[GåÊÆJ r M>úxƒ=´¯wR7–+6G"üµö¨ n¢+rþ/q-k;\@AÖ6'á>É®ŽûyÌA{3êÝ4ü è°âPwÌ>‡±‰²ŠÊÊ.ÛÀÀÆÐr­9Ÿ‚ï n37Mã«=ÝŽì/q«éèäƒ7y¹µšÝÜ¥c™ñŠ Ö±eϳkÂk¨™§±Ìá_„ ò—âZÀ§ÝËqË&²·0?I£ƒZA¡äPm=j·¯D:z×ÆâÆ˜„€4ðÿ—4¯Âƒbü*ØIÑÍIäº;y²?Pç‚Ðý6ñן ì“Áï9 +óóÄÔìœE}%És g·–r‘®aþТ gûS ŸÇµ& Gm[Á§áAÄ:Óѽíºw¿ßX[{[‹9-#„‰gòž×ÆMx»‚ ÿŽS¯ú}€ôÝ ƒµô'§ùý·26™ÈàŽêöô\ÇóØ„|\8ðA¿ÝÂë‹»,{x—È&›Â8ø’}%Ñ,m’7ÆEZö–‘àA5 x¥~"îÀñº¶Ž[g7…K‹\|5 sàƒÏý5ü1ÞÝkÍð…œnmq9¯žA_ï¥a-cÍeIïAGøfËä·EÙhÙ…Û±^Mî‘ÄæÉq,ÉŒEBæÆÝ<5;ÖðA¸u+¤-†Ãfb¶N­µÇå›q|c,†i$-sÏ¥_ÈÄ..­l#q+^ÿð£5'ò Úy7‚ ^Ê6ÛßÝX¿†c4UíŠCZÿe%éÿJ-æþ°ÞxfIËd…Å—K„Œõ™Úâæž#4Nìü2å±ùkYvóY˜ÁËu¸µÍŽâD/s´²Vh¯ô ¹êWá’âÜ\_lp/-ßW=Ãdgø<Ðó_ÇÅw·¶žÏkã¬$n‹çZÁgåð$Iå´>´á‡—¥¬" h¡£kX>DíÄfÛpO¸2ô6h]Ù­‚j3õ;içúgÔ±Ô ûmÜæá³“ $”RkiéìµüÚPt gâg§W6-žý—–Waµ’ÔBg¸TG,d´ŽíZ~˨Û9ÖLå†×Û–GŒ†C$6Ï£ž÷ŸTÜÝUŒŽ6ž¿ Fí½g³¶mŽÙÅðã-Ûwkå#‹¼u=Õ6ü£í1Vð<}`f§þ³¸ŸÎƒ’ŠH3W,iÐr“lþéØÒÑùÁAŲ)ëÎZÊ\~O~Ç%…ÍYsd¼c'—ɯ¡ã'Cv+öû8Ún>´d(=ä]ÓÆ¾z¼+JpAË:…Òn­Ã¶1ø«Ã6è°÷¸mlq±ì{\Jé÷†g±mÙ8ÍÅ·öU¶èÈ ®NÒ"$¸h«õqêÂ뻎4|¯q’gן¸Ñ϶!w¹Kvá¥×’ºVÐäÏÈ‚MÎÃ-oÛÊÒO­ÿA¤üH19¯·2s6ë#‹´¾˜45’ÜDÉR©ÀšqAæíÿÒìÆÊÜ“»Š~Ogæäy1´¼Cæ¼}LÔ©hcXõWsƒÌŽzLr•Ý–ïÊ™‰inpí2Ï¿[{­» ìf&[{À’?-ÌkCZK|Öš€9ú«…­žkÓjDëÚ¹L[H¼^™fºviÇâ»Ù[ã#/òE¯½Ž?&ÞΦBÊzÇQæî$pàÞ=ê[MœÒz­tøÖ@Ãtíw…ŒÒ?´Ë¤5Îwë º|lcK¥sXÖŽ.qáäƒ뙲6¸‘¨ßaýœPgqö0YZÇmõX8“ÍÄóqô”\P`ò¸Ë¨îNFÁòÕ±4´vÒ%²É[\zÊb‘¼nòc{kú(.´<Aô'›«ù9 ÇÝe#ó|‹Po/O=f´×›ÝÈQG ‰}£džáþmõÁ¬òC¹ð2ZParøË–ÜýãhtàRâß•¾±Á+ûº±òço·m'ªð}ç“Nïˆ,.r6ñÉîö­÷»ÓìÁ¬뻓B †û_2æéâKëŠ^=–Éð2„ Âåñw&àdqô÷¦7L°»Ù™ß¬;[Ùä,®œck¼›‘íÛKêHo>h/|®¨§¦ˆ,nrVðÉä[ƒwzïfÞ/XÿmÃZ‚û Š–ÝÒ]Þ8>þl·Ù½‘³Àw ÊžH1YœT·^]Å£ÄWÐq…çÙpícü l•»ßî÷@ÙÞ‚^ $|ÇrpA|"íà|jåAiw²µ:\ï6sÁEë<Ÿ rA[‹º}ÐÉd@lÀml8ˆZy×½Åm†_BÛËÕåÍ×ÛßèïA„uÍ»ØünzFùG—#eh}´íþÐ-ãÜPjWŸ‡Î‘_\ûÓ°,Œ¸—[Ï##'õˆl˜ŒËÙö&×cmŒ…üã·n©d=š‰Õ#Ïë+}ÕýÔw·‘˜m`:­m]í|ù=À8 ²Ëã"ÈZ˜^t=§\3lxäàƒó­ä¹V‹{ŽMŸ•'ˆwa(26¸U¤8vA‘½ÕÕ•›5ÜJØê( ^êö5­©5ANÊÆç%qÕÜF Ž»{Wûr;çÈ?0A°€‚…õœ–϶µŽACÞa5ñqqŒp¶Ê©i¥½ø«‡tŸ5ÁF0Ç´¤iãV¸PüH)ÜKkm’âVDÁÚâ8ú2‚Ò+yó/h 0bZCžç=;æ^h6F1­hk@ ‚K$Ì1ãKšyPkOŽ|3ÌSµÒã+õ ÏŠ¿!àvw9ý¼LÁ%¼¬’7 Æî#/“ù¤c¬ç8xÔñB%×q˜&Ú¬³åq|Aokb¯z ŽÒÞh-Ó`5­îT=í`ãÚƒw…Å\Èdu³)?ÄeXïÈ‚œ[wLJ:1¼×9ß%b`c#ky5¢€zAY ‰AŽ¿Çã¯üų$#“Ü(ïŒqAcþÚÅV®Ïoc÷üUA•²†ÎÙž\2÷0PaAÄòAŽ¿±ÇÞÿ˜¶ŽR9=ÃÖøÇ#lâkWFç7æ9î-øªƒ'e£|¸ d-ýO袩àcïì¬/E.mã”Nxõ‡ÃÍ€ÛX ê–8·ž‚çiüè2v6Övlòíàd,<Ë+ý(/Aˆ@A@YÞÁitÏ.x;LTö±Uõc{[ó÷Óº•AccadimmUùm·Æx È4‚8 Š·L·š7E,M™‡›^oåAŠvÛÄ’K"1›œùÐ]Ybñ¶oó!µc_Û-*ɵÁ¡È¨-®›o+ RFÙXyµÀÇÒƒí¹‰'ÔˆÂ>lnsGÅT6X¬e›õÃm™ö¤jwÆäF¸pøPL€PQ›Ê-,sÁæÒ0òíÜD/d>I<ü¢æ~@‚­¶nñ#m˜ù'ÉWüD Ë1Íxáˆ'@A$Žh"µàG‚ =Æ ;ÌžìØä<ßX" möþ"7‡˜ïC¥%Ä|‚ ÌF:´À4p@€€€€M r :¹” (P4 ­$qæL‚‹êî|»CJiAJ ã&´ìAQD×A.žä (PTŒÓ‡gb ˆ)IWAšGr”§¥XÍ ;;TAJRO˵=!t ‚hýSà‚² $&”¨)ið@ @Ò‚f’ÓÃá+ –BiAÁ#¥ô ‹*§Â‚º dq‡2‚…=(#¥JŽ£š Í5 8*P5çÚy Ø¥Oò=è+±Õ"€€‚ä‚J QˆA3Ly §D Qˆ"ÑÅå4 Qˆ"ÑÄ 2(D ˆPOØ‚™P(D  ¨9 •Â¥¤ Qˆ ¼‚8qA-(D ¼JñÅ(D QÍA-(D ™‚ˆ&@@@A (P4 iABœP4 i@Ò‚ †” (P4 ‚(!D (P4 QPBˆP4 i@¢ …8 QJ” P4 i@Ò‚(Ò¥J”„Ò¥JD „   U¡¨@@@¨@¨@@@@¨@¨ï@@@@@¨ï@¨ï@¨@@@@@@庲½¼¼lLžOv®c[!!µsœÞ<9 ÀÄ®Öþ›+ü¨þš Ûau½,./1°Ü[‹I¼‹ˆn˜ö¸´¥=gs¨7n¤õ75ƒ³jY[çfż¿rZ“=­¾Lq¤8qõøÚnû[pØî=¿aœ°$ÚßÂÙ£•n¡Å®§kOƒ*€‚W=€\¥ ßý^Üw{„à¶UÄV°XL{’”1Þsã5’8Ý%XÈÛB×¾•¯%Ë.X¤k+}µ²ÛHnV›£¨8ÅâìåǸ¸6²úÇIãÜïȪ×6kF±XÓ½¡“kµÇ=µ¢ÝÌîÕÞeæšÊêÝÖkno5åÀ–×±XÅŸ¯„ð·±Ou²ò£ª³ÕIílÀ…ÝL@@@@Aâ-Ï»°Ö»qZ\]29£Ìdµ´ƒQ[ÙOô ÇÚõcz̆;(ë „cÔ»¶s™%+]/á¥íý‚z¡ýaÏïK‰1÷ÖòÞËŽá¶aŽöð •ŽàáÚÂG€AÙ[ÉP !þ!7U†ªyk{AóZ[9º[«†‡%ÅÕœµ¾7£:ÈO¨ÀÓ:EMjêpAµ~2Öùm»¸ïmõyOɱ£P¡«lᇥp@@AäïÄFç³ÃuV哵î3cí‹t4»‘w: æã¨øŽÈæ§øe¢? ÙHr{{pÞB#~Eâ‡Õ¶ŒrAÜPYæ?Òo¿ôòþáAà‹-ÿ†ŠÒÍ’‰Ãí r±¯k˜øéGFöZZ{AAJË~bM‚ù³]:WÈé# †B÷—js7qAž©™LýÖØÅMqq{вÉÇî’ÜÆâøÞòåyçÛnŸ’î>4Aî¤Éõ+·7ôÇÛ\\Xão²’6úâÞ#æ=ѹÀEçŠùmpæƒ[¼ß˜Ž}½›f·x,|ok K^ÙýAÜõ V¨*Üõë{¢ßxt×AΖw±Î|}}g½Ä“ñ ÷fÒÿù\/þ†Ûÿ%¨2ȱ”z=±Ü½q½‡%WÝØÜd/Ý Ñ×M—ËaüÆqÈ=T[P~$OñˆÛ{{§öY[[h¬È4ÀØZ\/}á´æíUÔPlÿ‡|”™“áæ5ò˜gŠÛUkäÇ3šÊ×ÁIA$¬kÚXðÇ×4ñB 3Ñþ˜ÜcnÙ&ÏDZÏ}ü lÄyù‚AJóãð ó¦üÈÏ‘‡§/Ü.»"mŽá1=±¹¼ü¶;²7:Mk¡sêKºkc€Á[1öÛr /í­ŸœdcÞ¦cþ©×@WTß=ƈ:® ŠÁâí±X«vZØ[02YØÞòy’y’Pd þ!wƒ±]VÌZLË™á1[–µ’9±†º \Ú*ƒFÆo–Ýå1ÖQYË™wlÆ;Õ¿ZÚp=‹¸ì1¶ýNÚ—vðÆÜ¥üwÖ÷ÅÓZ6¸™©í>škÞ‚Ï 1°] ¸Æ –F+ƒ.žAî­Pt¤É“¿;­Øn¥ÛÂás$RâíÜÖC#ØÖŸ:jšR(ƒ›Å»6ÎÊ\[Z½‚#Æ4ðŠCíp¯ t©TsN¹«Ë‹cmL–¯‹‡ÁêC{±cÇ塟lämíþð…•q·”ÄÑæÜT2Líí6ü'ä–.å:'†jÇêdó—v²u l\ãÙ¥½‰ægÆj#CœQÒSþå,—‰ËY¯l#·¤þ¶H¿ã1§{¡°«ú1Ó ÍlLæìê~é²ÁbfÈÞ}óæ½£D1‡\ÈC¥™ÃCE8÷ø í};ü$`,GzLÜ­àõ†2 ²Í‡¹çÛ”úhwÛ}•…¬v–VñÚÚÄ)µ¬c@ì hÈ’~%ö¾vóª—pa¯om§²€Asom4ñ ‚5F׎½ÑÖŒ&bÚeÝÌÐ:sm ¼²KÄzñµ¥ÍãÞm_„ì.O´s~ûa=ƒn2Z Žæ'Â÷5¶Ñ4¸2@×SP#’ Pp¶tyo=í÷öæÅ¶ï´ŽÝñÝkŒ“P[éA¡ñSª_ýÖ'ö¥þ¤· Ý3Ïl-½²ÍOo5Õõß¼k«CZ#l`îßV¨:z \”2Mas b²KŒ`<8¹¤>”séáQñ˜2ùñ¼Bàè𖮬n-< Ä¿(šÞ)mßµíöèÉ^nY"ÇmÑ{4–8ÛYfÒ1¥ü¢fžGŸU:Cuyi²ñ[/¶; •eÕÜlsak"khd=¯wÆPv„w¦(»´Èoë]Û·¹Ägò^óg…²²XޝZœÚá¨xÕ»ÿ —V™Û+Í¥$WxW]Àû¼Uó½x¡l­t’â3H¦—qñAuÕ´sûÆG`º8$”—K„¸4†®P,h whA×z¡²·½¾^\ßOm[>áÏc’ÉÞÏ«Üm4€ßucŽ˜Ãñ¨A¿tÿh[í Ÿ‹Û°?Í÷CeŸ—™+Ž©_ý§¸” ;¬V6éþm՜ȑ$±±îº®‚/õ#£“jîÙrW÷¦ÖÍÈqeu{±™ã\og?+QÔÇeWÜmüÚóÒÑÚ¹³ÞÎ rֳ΅Ðu^ܯÆc¯í|±¹tºAŒ44V2;­?±§LÅe~±±êë­¯I禟œØ]=8{öBFÏ’,ò£‚"…„ñ ¯žÓñ)mv~_Ýn6qõRœúV¼)õŸkwh¢¾ÊE*(‚VBÆXÐÝ\\@¸÷žôD‚Obi("Aª  QŠ PrA @@AEˆQ’DÉèÞÐæ;ƒšà ÷ƒÁ“Ñ“ßÝ›»¯bfqÔâÈÄmq<ËšÊ4×Ä ÙðÛw ƒ³m–ÂßhÏfÞÖ6ÄÎ> ¥PdZÚ Šñª"€€‚=èVˆ"€€€xŠ jmD½íc÷{-“èAoJÖ@â×¥ºÈ ‚[Þ*‚°ž#A¨TüšñøDÊÁĸJ×ýD$´89Š„l¬q!®#˜ §oyáæ'TFâ×öP„]BÁ¨Qä€áËÕ5(*X)W^U(%}ÄMcÞ\)%þ „ š!+jyjøPN%a­+QÍLŒ«€¯*”kÚâhA§: Š s°¾ßiÍ |"ˆ1cwnoñ|Ø<º¹Üc WõPNÛ9]vÇËoVFZðYRâ(ç;´ ¢ÌeõF®EÂ'ŠÿpÓP}(*6ÊïßD¦0Ú9Þ¸-ÒXEÀzÈ"Ë ˆba‚0Ù<§1Ü~Q< ~í¸‰¯`&x¤ˆG m#psO=5A<6¿Ê3ÄÒÆÈçP€ (Òà8V¨#=þd&f5Â&<7W_VþDŽ»s¦×¬èŸ$´5Îw*ÙéAwqo;íoÝ$hü¦ ¢ëY â”Zi‰šµ[ê%øpA/Ýs:Ù×ÈÛ.3^N©#⪠»+GA3ˆhk¡ùm­P^„ Q(‚4@@¢(€D¢ÑÿÙremuco-source-0.9.6/client/android/res/drawable/icons_gimp.xcf0000644000000000000000000055570511700415064024374 0ustar rootroot00000000000000gimp xcf file& nòâ¹™†fT4%ôÔĤ’sbC2BBã@gimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) jpeg-settings U            -cñxp×öÙ±Iconsÿ     ÿÿÿ3ÏócÁcÍcÙcå³¢<³W«sÛ5ªÙÈ6Ì6ÌFßmõX E-5Hð_bcbcr{U—Ù²ÝÏî ’(^,¾,Î.Ò1¯4«7:‡> E¥JˆK¬K¼KÌKÜKìKüU“aÁc±ÿþÿþÿýÿýÿøþÿÿýÿÿûÿÿúüÿÿüÿýýüÿþýÿÿþþúúÿóúûÿüýÿÿýÿüúþÿÿðþýÿÿüýÿúûüûúûúüÿÿêýüýþÿÿûüÿÿþþÿþÿýþÿÿûþÿÿôþüÿÿûúýûÿûûÿÿþþÿÿþýÿÿùüúüþûûÿÿþüÿÿýûýÿÿúüÿÿüûÿÿøûüýîèîðííîøíëêîóøùÿÿóúÿÿþÿÿþÿÿýúýÿÿûüþÿþÿÿ÷úæÚÕÎÍÌÅÉÉèÇÆÅÈÌÐÑÐáìÿÿúþÿýÿþÿÿþúüÿÿðüþÿþÿþñÔÎÑáôÿÿýÿÿþþÿÿìùêàÑÐæýüùýýûûþþûûþþÿÿþþýýôÿñÚÔíÿÿûúýÿþþÿïëÝÖêÿÿûÿüûýüûÿþóÿÿýûôüèÆêüÿüÿÿýüþþçüþÿýûûýÿÿóÊÎùÿõûÿýýûüÿúåÿÿÇýüýþÿíÕéÿüúúûûúùþòûÿõúôýþÿýùùüþüýüúúüüúùÿÿðØ×ÿùþüýúÿûÿîÖÿÿÇþüýýÿèÖïúùøùüýþýñÿûøóÿÿýúûúûýÿþûýûúúüüûùþü÷âÏÿýþýþüþûÿâÔÿÿüýøß×ùýûúúûûùúñÿóÿÿùùüøùýÿÿüûúûúúóûüüûýùþìÄüÿÿþþûüÿÒÕÿÿóûýþýÙÙÿþüûúúùùöÿàÑýÿûøÿþüüûûúûþúúëûüüûûùÿïÁüÿÿþþÿÿþÿÆÙÿÿõýûþÿÿÔÚÿøøùùéúüýûZ9rÀÿÿûù÷ôô÷ø÷ôøùùúúûúøýþíÃÿÿþÿýÂÞÿÿüÿùÒÛýøùùøøöùûî%,9|¿ÿÿæûøùÿÿþ÷øùùøøùúôþûêÄÿýÿýÿþÿÿýÄàÿÿÌýþÿþÿÒÜùùúúøöõõøã]Z6+=tâøÿÿôóøú÷øùø÷ö÷øñüûìÁÿþÿýÿûÿÿýÇÞÿÿÒþÿÿüÿÒÝ÷õö÷÷ööøûì aad_B.+Üÿÿúùù÷øùøöõö÷ïùüï½ÿÿ÷ýÿøÿüÿÈÚÿÿôþûþÿÔÙùøôòõ÷÷ÝúêedhcgZL)3ˆãÿÿ÷úÿòîøõïûóúüèÃÿÿþþÿÿûþÿËÞÿÿþÔüÿÿÔÙùùõôö÷ö÷úèjffemkhoM6–êÿþñôûùþþïðøúæÃÿÿþþÿÿûþÿËÝÿÿÒýþýÿÿÓÙùöôóôóñó÷ãjecdcddcnh=!N˜íÿúé÷õëûï÷øçÄÿÿþþÿÿûþÿÊÜÿÿöüÿþÿÿÓØøöôôÚòïñöãdbdjccfddjob?O¯ÿÿìóûððöøèÅÿþÿþÿÿûþÿÉÛÿÿÐýÿþÿÿÓÖõøöôôòïñ÷ç_]^e_`\bb[Y_b^.S¼üÿöððôöèÈÿþÿÿýÉØÿÿÐþÿþÿÿÒÓðîëêêéçèìÖVZWXSUU\]XW\][hO##sÑðãëîñæÇÿþÿÿúþÿÿÈ×ÿÿÒüÿÿÒÑëåáÞààÞÞâÛQ\YX[ZaTQZ\SQZQ\d/ påïãæéâÅÿþÿÿúþÿÿÇÖÿÿÒüÿÿÒÏèåàÞàáààâÍ RÂûÜÜàäÝÄÿþÿÿúþÿÿÇÖÿÿëþÿýÿÿÔÐçæãâäåäãåÝøè6•àëàæãäæàÆÿýüýþüÿþÿÎ×ÿÿÇþÿýÿÿÔÐèéåãååâáâÞ    <ŽÜóëâáãäåæàÆÿýýþÿüÿþÿÍÕÿÿÐþÿýÿÿÔÑèêåãååâáâÝ(+×ìñáÝääÜåæçàÅÿþÿÿùýÿþÿÍÔÿÿÐþÿýÿÿÕÒêèäâäåääçÙ "+$&)*'+sËùçãâçëèãâæçèàÅÿþÿÿùýÿþÿÌÔÿÿÐþÿýÿÿÔÓëéåãåæåæéÓ&*+80&cÈöéâåçêçáàåèçèéáÅÿþÿÿùýÿþÿÌÔÿÿÒýþÿÔÔìîéææçååè× +=1$$VºûóçïéëàÝâèìëåçéëâÅÿþÿÿùýÿþÿÍÔÿÿÉüþÿÕÔíñëççèææéà, (VÁöÿæãíéâëçîòæÝäîæéíäÆÿýÿþÿüÿþÿÍÕÿÿÉüþÿÕÕíîéæèéèêíÞ  S³úøõêçíêçðèäæåæìíàæéîåÇÿýÿýþüÿþÿÎÖÿÿüéÿõÿÚ×îïëêéèîðçÜER¯ñÿíééêçéèééèççàíøáÉþýÿÿþÿÿûÿÐÔÿ ÿêýÿÓÜëðìëéæêîëúĽåöôðåééêéïîêõáÆÿÿýÿÿþÿþÿËØÿÿçþÿýÿÿÐàìïìíìèéîïîõÿÿøèæîëëìúîííììëëïôå÷ãÄýÿüþÿüþÿúÊÚÿÿåûþýÿÿ×ÚððîïðîìíïéñðêíîîðîîïïðïëîíììíèüáÇýÿÿþÿûþÿüÔÕÿÿçûýÿúÿåÐìøõñïðïííõóñîñôòìïïðçíïðñðïíìîóõ×ÐþþÿþþüÿýÿçÎÿÿþðÿöÿóÐßøúôìîðîîóììûêìñïîîïïðïðññòñðïöùåÐáÿüþþùýÿüÿ÷ÑÿÿåþýÿùþþâÒâóöññôòñóòñôöóñóððññòñëòóôõóñÖÚ÷ÿûýþÿýÿþÿýàÿÿûèüþþÿöÌÆæùøùúöôð÷öõ÷òïùôõõöéôòñòõùüçãÐêÿýüÿýÿýþÿüþïÿþÿþÿýÿýÿøþÿÿýÿÿûÿÿúüÿÿüÿýýüÿþýÿÿþþúúÿóúûÿüýÿÿýÿüúþÿÿðþýÿÿüýÿúûüûúûúüÿÿêýüýþÿÿûüÿÿþþÿþÿýþÿÿûþÿÿôþüÿÿûúýûÿûûÿÿþþÿÿþýÿÿùüúüþûûÿÿþüÿÿýûýÿÿúüÿÿüûÿÿøûüýîèîðííîøíëêîóøùÿÿóúÿÿþÿÿþÿÿýúýÿÿûüþÿþÿÿ÷úæÚÕÎÍÌÅÉÉèÇÆÅÈÌÐÑÐáìÿÿúþÿýÿþÿÿþúüÿÿðüþÿþÿþñÔÎÑáôÿÿýÿÿþþÿÿìùêàÑÐæýüùýýûûþþûûþþÿÿþþýýôÿñÚÔíÿÿûúýÿþþÿïëÝÖêÿÿûÿüûýüûÿþóÿÿýûôüèÆêüÿüÿÿýüþþçüþÿýûûýÿÿóÊÎùÿõûÿýýûüÿúåÿÿÇýüýþÿíÕéÿüúúûûúùþòûÿõúôýþÿýùùüþüýüúúüüúùÿÿðØ×ÿùþüýúÿûÿîÖÿÿÇþüýýÿèÖïúùøùüýþýñÿûøóÿÿýúûúûýÿþûýûúúüüûùþü÷âÏÿýþýþüþûÿâÔÿÿüýøß×ùýûúúûûùúñÿóÿÿùùüøùýÿÿüûúûúúóûüüûýùþìÄüÿÿþþûüÿÒÕÿÿóûýþýÙÙÿþüûúúùùöÿàÑýÿûøÿþüüûûúûþúúëûüüûûùÿïÁüÿÿþþÿÿþÿÆÙÿÿõýûþÿÿÔÚÿøøùùéúüýûZ9rÀÿÿûù÷ôô÷ø÷ôøùùúúûúøýþíÃÿÿþÿýÂÞÿÿüÿùÒÛýøùùøøöùûî%,9|¿ÿÿæûøùÿÿþ÷øùùøøùúôþûêÄÿýÿýÿþÿÿýÄàÿÿÌýþÿþÿÒÜùùúúøöõõøã]Z6+=tâøÿÿôóøú÷øùø÷ö÷øñüûìÁÿþÿýÿûÿÿýÇÞÿÿÒþÿÿüÿÒÝ÷õö÷÷ööøûì aad_B.+Üÿÿúùù÷øùøöõö÷ïùüï½ÿÿ÷ýÿøÿüÿÈÚÿÿôþûþÿÔÙùøôòõ÷÷ÝúêedhcgZL)3ˆãÿÿ÷úÿòîøõïûóúüèÃÿÿþþÿÿûþÿËÞÿÿþÔüÿÿÔÙùùõôö÷ö÷úèjffemkhoM6–êÿþñôûùþþïðøúæÃÿÿþþÿÿûþÿËÝÿÿÒýþýÿÿÓÙùöôóôóñó÷ãjecdcddcnh=!N˜íÿúé÷õëûï÷øçÄÿÿþþÿÿûþÿÊÜÿÿöüÿþÿÿÓØøöôôÚòïñöãdbdjccfddjob?O¯ÿÿìóûððöøèÅÿþÿþÿÿûþÿÉÛÿÿÐýÿþÿÿÓÖõøöôôòïñ÷ç_]^e_`\bb[Y_b^.S¼üÿöððôöèÈÿþÿÿýÉØÿÿÐþÿþÿÿÒÓðîëêêéçèìÖVZWXSUU\]XW\][hO##sÑðãëîñæÇÿþÿÿúþÿÿÈ×ÿÿÒüÿÿÒÑëåáÞààÞÞâÛQ\YX[ZaTQZ\SQZQ\d/ påïãæéâÅÿþÿÿúþÿÿÇÖÿÿÒüÿÿÒÏèåàÞàáààâÍ RÂûÜÜàäÝÄÿþÿÿúþÿÿÇÖÿÿëþÿýÿÿÔÐçæãâäåäãåÝøè6•àëàæãäæàÆÿýüýþüÿþÿÎ×ÿÿÇþÿýÿÿÔÐèéåãååâáâÞ    <ŽÜóëâáãäåæàÆÿýýþÿüÿþÿÍÕÿÿÐþÿýÿÿÔÑèêåãååâáâÝ(+×ìñáÝääÜåæçàÅÿþÿÿùýÿþÿÍÔÿÿÐþÿýÿÿÕÒêèäâäåääçÙ "+$&)*'+sËùçãâçëèãâæçèàÅÿþÿÿùýÿþÿÌÔÿÿÐþÿýÿÿÔÓëéåãåæåæéÓ&*+80&cÈöéâåçêçáàåèçèéáÅÿþÿÿùýÿþÿÌÔÿÿÒýþÿÔÔìîéææçååè× +=1$$VºûóçïéëàÝâèìëåçéëâÅÿþÿÿùýÿþÿÍÔÿÿÉüþÿÕÔíñëççèææéà, (VÁöÿæãíéâëçîòæÝäîæéíäÆÿýÿþÿüÿþÿÍÕÿÿÉüþÿÕÕíîéæèéèêíÞ  S³úøõêçíêçðèäæåæìíàæéîåÇÿýÿýþüÿþÿÎÖÿÿüéÿõÿÚ×îïëêéèîðçÜER¯ñÿíééêçéèééèççàíøáÉþýÿÿþÿÿûÿÐÔÿ ÿêýÿÓÜëðìëéæêîëúĽåöôðåééêéïîêõáÆÿÿýÿÿþÿþÿËØÿÿçþÿýÿÿÐàìïìíìèéîïîõÿÿøèæîëëìúîííììëëïôå÷ãÄýÿüþÿüþÿúÊÚÿÿåûþýÿÿ×ÚððîïðîìíïéñðêíîîðîîïïðïëîíììíèüáÇýÿÿþÿûþÿüÔÕÿÿçûýÿúÿåÐìøõñïðïííõóñîñôòìïïðçíïðñðïíìîóõ×ÐþþÿþþüÿýÿçÎÿÿþðÿöÿóÐßøúôìîðîîóììûêìñïîîïïðïðññòñðïöùåÐáÿüþþùýÿüÿ÷ÑÿÿåþýÿùþþâÒâóöññôòñóòñôöóñóððññòñëòóôõóñÖÚ÷ÿûýþÿýÿþÿýàÿÿûèüþþÿöÌÆæùøùúöôð÷öõ÷òïùôõõöéôòñòõùüçãÐêÿýüÿýÿýþÿüþïÿþÿþÿýÿýÿøþÿÿýÿÿûÿÿúüÿÿüÿýýüÿþýÿÿþþúúÿóúûÿüýÿÿýÿüúþÿÿðþýÿÿüýÿúûüûúûúüÿÿêýüýþÿÿûüÿÿþþÿþÿýþÿÿûþÿÿôþüÿÿûúýûÿûûÿÿþþÿÿþýÿÿùüúüþûûÿÿþüÿÿýûýÿÿúüÿÿüûÿÿøûüýîèîðííîøíëêîóøùÿÿóúÿÿþÿÿþÿÿýúýÿÿûüþÿþÿÿ÷úæÚÕÎÍÌÅÉÉèÇÆÅÈÌÐÑÐáìÿÿúþÿýÿþÿÿþúüÿÿðüþÿþÿþñÔÎÑáôÿÿýÿÿþþÿÿìùêàÑÐæýüùýýûûþþûûþþÿÿþþýýôÿñÚÔíÿÿûúýÿþþÿïëÝÖêÿÿûÿüûýüûÿþóÿÿýûôüèÆêüÿüÿÿýüþþçüþÿýûûýÿÿóÊÎùÿõûÿýýûüÿúåÿÿÇýüýþÿíÕéÿüúúûûúùþòûÿõúôýþÿýùùüþüýüúúüüúùÿÿðØ×ÿùþüýúÿûÿîÖÿÿÇþüýýÿèÖïúùøùüýþýñÿûøóÿÿýúûúûýÿþûýûúúüüûùþü÷âÏÿýþýþüþûÿâÔÿÿüýøß×ùýûúúûûùúñÿóÿÿùùüøùýÿÿüûúûúúóûüüûýùþìÄüÿÿþþûüÿÒÕÿÿóûýþýÙÙÿþüûúúùùöÿàÑýÿûøÿþüüûûúûþúúëûüüûûùÿïÁüÿÿþþÿÿþÿÆÙÿÿõýûþÿÿÔÚÿøøùùéúüýûZ9rÀÿÿûù÷ôô÷ø÷ôøùùúúûúøýþíÃÿÿþÿýÂÞÿÿüÿùÒÛýøùùøøöùûî%,9|¿ÿÿæûøùÿÿþ÷øùùøøùúôþûêÄÿýÿýÿþÿÿýÄàÿÿÌýþÿþÿÒÜùùúúøöõõøã]Z6+=tâøÿÿôóøú÷øùø÷ö÷øñüûìÁÿþÿýÿûÿÿýÇÞÿÿÒþÿÿüÿÒÝ÷õö÷÷ööøûì aad_B.+Üÿÿúùù÷øùøöõö÷ïùüï½ÿÿ÷ýÿøÿüÿÈÚÿÿôþûþÿÔÙùøôòõ÷÷ÝúêedhcgZL)3ˆãÿÿ÷úÿòîøõïûóúüèÃÿÿþþÿÿûþÿËÞÿÿþÔüÿÿÔÙùùõôö÷ö÷úèjffemkhoM6–êÿþñôûùþþïðøúæÃÿÿþþÿÿûþÿËÝÿÿÒýþýÿÿÓÙùöôóôóñó÷ãjecdcddcnh=!N˜íÿúé÷õëûï÷øçÄÿÿþþÿÿûþÿÊÜÿÿöüÿþÿÿÓØøöôôÚòïñöãdbdjccfddjob?O¯ÿÿìóûððöøèÅÿþÿþÿÿûþÿÉÛÿÿÐýÿþÿÿÓÖõøöôôòïñ÷ç_]^e_`\bb[Y_b^.S¼üÿöððôöèÈÿþÿÿýÉØÿÿÐþÿþÿÿÒÓðîëêêéçèìÖVZWXSUU\]XW\][hO##sÑðãëîñæÇÿþÿÿúþÿÿÈ×ÿÿÒüÿÿÒÑëåáÞààÞÞâÛQ\YX[ZaTQZ\SQZQ\d/ påïãæéâÅÿþÿÿúþÿÿÇÖÿÿÒüÿÿÒÏèåàÞàáààâÍ RÂûÜÜàäÝÄÿþÿÿúþÿÿÇÖÿÿëþÿýÿÿÔÐçæãâäåäãåÝøè6•àëàæãäæàÆÿýüýþüÿþÿÎ×ÿÿÇþÿýÿÿÔÐèéåãååâáâÞ    <ŽÜóëâáãäåæàÆÿýýþÿüÿþÿÍÕÿÿÐþÿýÿÿÔÑèêåãååâáâÝ(+×ìñáÝääÜåæçàÅÿþÿÿùýÿþÿÍÔÿÿÐþÿýÿÿÕÒêèäâäåääçÙ "+$&)*'+sËùçãâçëèãâæçèàÅÿþÿÿùýÿþÿÌÔÿÿÐþÿýÿÿÔÓëéåãåæåæéÓ&*+80&cÈöéâåçêçáàåèçèéáÅÿþÿÿùýÿþÿÌÔÿÿÒýþÿÔÔìîéææçååè× +=1$$VºûóçïéëàÝâèìëåçéëâÅÿþÿÿùýÿþÿÍÔÿÿÉüþÿÕÔíñëççèææéà, (VÁöÿæãíéâëçîòæÝäîæéíäÆÿýÿþÿüÿþÿÍÕÿÿÉüþÿÕÕíîéæèéèêíÞ  S³úøõêçíêçðèäæåæìíàæéîåÇÿýÿýþüÿþÿÎÖÿÿüéÿõÿÚ×îïëêéèîðçÜER¯ñÿíééêçéèééèççàíøáÉþýÿÿþÿÿûÿÐÔÿ ÿêýÿÓÜëðìëéæêîëúĽåöôðåééêéïîêõáÆÿÿýÿÿþÿþÿËØÿÿçþÿýÿÿÐàìïìíìèéîïîõÿÿøèæîëëìúîííììëëïôå÷ãÄýÿüþÿüþÿúÊÚÿÿåûþýÿÿ×ÚððîïðîìíïéñðêíîîðîîïïðïëîíììíèüáÇýÿÿþÿûþÿüÔÕÿÿçûýÿúÿåÐìøõñïðïííõóñîñôòìïïðçíïðñðïíìîóõ×ÐþþÿþþüÿýÿçÎÿÿþðÿöÿóÐßøúôìîðîîóììûêìñïîîïïðïðññòñðïöùåÐáÿüþþùýÿüÿ÷ÑÿÿåþýÿùþþâÒâóöññôòñóòñôöóñóððññòñëòóôõóñÖÚ÷ÿûýþÿýÿþÿýàÿÿûèüþþÿöÌÆæùøùúöôð÷öõ÷òïùôõõöéôòñòõùüçãÐêÿýüÿýÿýþÿüþïÿXÿþ7ÿþÿþÿþÿýÿùþûþÿÿûÿÿýàþýýüýþÿÿüúýýûÿÿýþÿÿþþÿþúýÿÿûùýþüüýþ÷úüÿÿüöøüÿÿþþÿÿôþûùöüûÿÿþûþÿÿñþûûýþýÿüüÿÿþûúÿÿøýúûÿÿýûÿÿýýþÿÿúýÿÿþþÿÿý÷üûýÿÿþýþÿÿþÿ÷öýÿùòñòòïï íáìíïòõ÷øþÿýüÿÿùþýþÿÿýýÿþÿÿøòðìçëëíöÿùèÚÏÊÈËÆÇÇÉüËÊÈÅÅòÇÈÕâñüÿÿþýþýþÿÿ÷ôã×ÐËËÌÈÉÉÊøó×ÉÛñøüÿÿõýúøÙÒÓèþÿþÿÿüýúüÿÿøòÞÕáìð÷ÿÿøÊÖéûÿüüÿÿþýûüÿÿäýúøÿïÖÒéúûùýÿþùûÿýóÖÜéúÿÿþÿýýþöÿÍîÿÿúÿÿùüüþÞýþþÿþüûúÿÿðÐ×õÿÿöÿÿüþÿ÷äÕóÿÿúÿÿüýþþÿÔäýùûúòÿÿüûýúúýýüþúþÿÿôýøüÿöþýýñøùÿÿðÖàÿÿýþûÿÿ¶êÖåúýøþÿûýøÿÿúüþüÿóÿúüûôýøÿýþýùüþþóþÿÿþôüýÿÿýüõÿÿü÷ûýúÞÚûýÿÿýÿýÿäÐïþþúÿÿûÿÿëûùþÿüúþÿ÷üüúÿöóøöüýÿüüÇýñøþýüûñòùÿû÷÷ÿùôúÿåÏòþÿÿýþûÿÞÎúÿüúþüùÿûúúýýüþýÿû÷üûûÿ÷öÿÿúþýöÿþÿÿ€ôÿùîýÿõøÿåÇòÿþüüýýÿßÓýû÷øüøôüûûúþú÷ÿýÿüúü÷öýöÿú¶ƒ™Þüÿꉀ†¶ÿùüÿø÷ÿùúþäÆöÿþüþþÿÿÞØüøõùüøôûôøòøùôùóúøùú÷õùûù¸=¾üÿ´ !*ÔÿøûüòøùüþçÈúþÿþÿÿôÚÙþùùûüùøûðÿÿ×öôöøùøøÿö%?XXA0¶ÿÿ¹;[UYª÷öûý÷õöùûèÈüýÿÿùþÿÿרþúú€¾ø÷øùþÿÛÆÉÅËÇúúø÷ûøòûý†+[bWJ<¹ÿþÀ.I]Xqªôô÷óøöôõøæÄýÿÿýÿýÿÿÕÙûúùöóóõõøÑd)079-øùõó÷öõùú‰2]eeS7Àÿÿ»#Rl^p ¯ùõõòôóôôûåÊûÿþÿþýÿÿÙÒüøöôóôõ÷ÿ²$,LHBD÷úöô÷÷öûõˆ8elgS7³ûÿ»(Yrdw¨òóõô÷ö÷öþåÊûÿþÿþýÿÿÚÓöóóÀôõ÷ùù¯1Jlhbcôõòñõôôøõˆ4`ifV@¾ÿÿ»&Vpcs §õùöôöòóòúäÉûÿýÿýüÿÿÛÔüùø÷÷†û«3Xvmikôõòñôõôøõ‰3`liT:µÿÿµ"Tndx©õõññõôôóúãÉûÿýþýûþÿÛÔùø÷õôóòòÿ¦-Pjacgõ÷óñööôøü2\kiS;¹ÿÿ½)Sham¤òùôóòøøõüãÈúÿýþýüþÿÚÔõôôÁöõÿ­2Qi`adìîêèëëéíê€%Pa`J7±ùø°F_`lœæïïíçéêéòÝÅùÿýÿþýÿÿØÒñïîíììÛíð£*Hc][[ãåâÞâáÞãé….U_XE7§ïò±#F^ecœÚÚ´âßÜÝÞêØÂøÿýÿÿþÿÿÖÎèäãàÝÜÜÝí©)E…RFkia_`cgH"?i`cbYffA?ÄÿñôþÒÔúþþÿòýÿ4ZëñõäÒòÿÿþÿÿÔþÿÐàíîìí—61 2Q^S^Q]\`e=UbaVV_c\J:ÀüåìúÔÜúþþÿòýÿ2^îêèØÌïÿÿþÿÿûþÿÍÛããÛæ#M;keX[ZadYTSE+P]T`p]WZ8:ÁúßâñËÔúþþÿòýÿ MîîêÚÑûÿÿþÿÿÔþÿÍÜäçêé…  ! -¸öÝáïÊÕúþþÿòýÿTìëðÚÒ÷ÿÿþÿÿöþÿÏÞêæåóŒþ ã+ÁÿèçðÐÕûüÿÿþóÿSêíòÝÎðÿÿþÿÿÓþÿÍÙæéèð‰Ar9    ,½øÝßìÐÙûüÿÿþóÿXñîè×ÌöÿÿþÿÿÓþÿÑÚçêçî‘Béèh&%,($%&#8ÅýäèóÒÖûüÿÿþóÿ SîñéÛËöÿÿþÿÿÓþÿÌÚëìäê‹=Óÿì·T$.,(R°d)3'"2¾÷ãêõÒÕûüÿÿþóÿ[ìóïäÏóÿÿþÿÿÓþÿËÙçèçò’/Óÿà÷ç¬/(.Mëû£J,5-¼ùäæíÎØûüÿÿþóÿ^êòìÞÎõÿÿþÿÿÓþÿÐÜçèéõ9Òýêéëÿñƒ*  ?Ïñÿñ- *¾ÿíëîÎÛûüÿÿþóÿ oéïìÜÍñÿÿþÿÿÓþÿÍÝïñéð•1ÒÿâèìÜúýÓt!RÓóÚìÿßw <ÂøåìõÓÛûüÿÿþóÿo¸ýëíå×òÿÿþÿÿÓþÿÒßïìäþÎ>làöáâêðÝïùú»`’âøðâãýÿÂnzæþÞèøÒÓûüÿÿþóÿðÿòãóàÉóÿÿþÿÿÓþÿÍáðíæíÿÿææëïïéêïêççñýÿ÷ëçéëéçìøÿñóãéíöÑÜúüÿÿñþÿÿöëäêóàÏìÿÿþÿÿÓþÿÌÜìîèäçïüõîìëêèçñìèêïñîêèëííêêíðóêâíòúÐØûüÿÿñþÿÿðçéòòÙÒôÿÿþÿÿèþÿÎÛññíëåðïîëêíðîëôïëèêììûîïîìêêõïêîòî÷ÐÛüüÿÿòþÿæôóôõØÒþÿÿþÿÿþÔ×ÚöõíöïòæíðíëíîìîïððïîïððïîííîïðëïöìëøÑÝýýþÿÿþôíòñøôØÙýÿÿþÿÿþâçÓï÷ìòíìðôôïìîñðëïòòðïñòïîííîððèñïíêùúÏÞþýþþÿÿþþóéñýãÍåÿÿþþÿÿÆþýòÏà÷õòíðïïíïòôóïðññïììðòííïððïìëñíîõüéÍìÿþýþþÿþýóòõðÓÐõÿÿþþÿÿÂþýùÜÖçöùöøòððôõòìêôóòðïðñóïðòóòòñðîñ÷úéÔÝûÿþýýþÿþýôÿõ×ÐçÿýÿÿþÿÿôþýþñÓÏëúùôùöö÷óñôüõôôõööõôíõùüôøûðÓÒñýÿþýýþÿþý@ÿþ7ÿþÿþÿþÿýÿýÿýûüÿÿùúüöùÿûÿÿýÿþÿýþýÿÿûóûÿþÿÿþüÿÿýùþÿÿýûýÿÿþ÷ùÿýúÿÿûóÿ ÿúþúþÿýÿ ÿüýûüÿÿýúýÿ ÿøõôúÿýùüÿÿ÷ùøüÿÿúïêïïíïîðúúÿÿýüÿÿ÷ÔÒá÷þÿÿûÿÿ÷ùÿÿõäÖÒÍÇÇÉÈÇöÆÓÈÔéóÿÿýÿÿ÷çÝÜÞåûÿýÿÿ÷ûúéÚÐÖíûÿÿ÷öçÞÕÐèÿÿþþøÿüðßÓäþÿÿúêÎÙñüÿÿþÿöþÿÿüîÝÙëÿþþøýüÿúÛÖîÿÿ÷ôâÖñÿûýýüüþýü÷ÿþûÿøÕÒúþþøûúúÿóÖßÿÿþãòÎìýþùùýüüýÿùûüÿþýÿýøÿÿùÿýûüþþïýûúÿýóÈïýþÿÿþýþþùùúþ÷ÛÚ÷ÿÿþÇáØüÿÿü÷ôÿýôýöùüþùúýþ÷ñøÿüÿÿüûþþùöùüÿþþÍÞüýþÿþýþÿÿýùüúáÝûÿÿøþÿÖáüóùÿÿÏøýöÿÿþþûûÿýõüÿÿøþøøþüôöÿÿþûüóþÓÔûûýþýýþÿôõöýÿãÓñÿÿæþÿÑèÿõúø÷úúÿöúüùúùøøûÿÿùøüüîúùÿÿþîöóôýøÿÝØúúüýýõþÿûù÷ùÿçÓ÷ÿÿñþÿÌåÿùúóöùöõõóùùãõüùøôòúýõûüüùôõýÿÿýñùùÿÞÞúúüýýõþÿùÿÿøúáÊñÿÿÅþÿÐâûôöýÿùÿýÿùóùùýôôûÿÿýûÿøø÷øüÿÿüõÿõðóþ×Úûûýþýýþÿx¿øûþçÍðÿÿÅþÿÒãÿûûÿã‘U|ãýüÿóøûúÿÿË}”øòÿÿôÿÿÇséý÷üÿ××üýþÿþýþÿŒõÿýæÍôÿÿÂþÿÎÞü÷øù®@Üÿôòëùøÿß~*VåùöÿÿÝŠ9 ;Ðÿööÿ×Ùþþÿÿþýþþ9Zõþ÷æÙòÿÿþÿÿÔþÿÈåÿö÷ø‹/2HØÿùñøÿÿ‘1+[7NØüÿó›B0@N=»ÿø÷ÿÙÚúþþÿòýÿ<[ôÿúæÔíÿÿþÿÿÔþÿÒçüôøý•;7EÞÿôÿ÷µE9@_x9Výÿ±Y'6hgEDÂÿôóüÕ×úþþÿòýÿ=[òüöãÖöÿÿþÿÿÔþÿÒãöóùû”9/IÔÿýÕm$EYkmrIS¼u!+hpjeR@¾ÿòõÿÚÜúþþÿòýÿ=`øÿ÷ÜÏõÿÿþÿÿÔþÿÌà÷ûþù2BMåö‚+(XekodgN&.Yn_ju`PAÃÿô÷ÿÔÓúþþÿòýÿ3[õÿüãÐòÿÿþÿÿÔþÿÏãøýü÷–7>E…RFkia_`cgH"?i`cbYffA?ÄÿñôþÒÔúþþÿòýÿ4ZëñõäÒòÿÿþÿÿÔþÿÐàíîìí—61 2Q^S^Q]\`e=UbaVV_c\J:ÀüåìúÔÜúþþÿòýÿ2^îêèØÌïÿÿþÿÿûþÿÍÛããÛæ#M;keX[ZadYTSE+P]T`p]WZ8:ÁúßâñËÔúþþÿòýÿ MîîêÚÑûÿÿþÿÿÔþÿÍÜäçêé…  ! -¸öÝáïÊÕúþþÿòýÿTìëðÚÒ÷ÿÿþÿÿöþÿÏÞêæåóŒþ ã+ÁÿèçðÐÕûüÿÿþóÿSêíòÝÎðÿÿþÿÿÓþÿÍÙæéèð‰Ar9    ,½øÝßìÐÙûüÿÿþóÿXñîè×ÌöÿÿþÿÿÓþÿÑÚçêçî‘Béèh&%,($%&#8ÅýäèóÒÖûüÿÿþóÿ SîñéÛËöÿÿþÿÿÓþÿÌÚëìäê‹=Óÿì·T$.,(R°d)3'"2¾÷ãêõÒÕûüÿÿþóÿ[ìóïäÏóÿÿþÿÿÓþÿËÙçèçò’/Óÿà÷ç¬/(.Mëû£J,5-¼ùäæíÎØûüÿÿþóÿ^êòìÞÎõÿÿþÿÿÓþÿÐÜçèéõ9Òýêéëÿñƒ*  ?Ïñÿñ- *¾ÿíëîÎÛûüÿÿþóÿ oéïìÜÍñÿÿþÿÿÓþÿÍÝïñéð•1ÒÿâèìÜúýÓt!RÓóÚìÿßw <ÂøåìõÓÛûüÿÿþóÿo¸ýëíå×òÿÿþÿÿÓþÿÒßïìäþÎ>làöáâêðÝïùú»`’âøðâãýÿÂnzæþÞèøÒÓûüÿÿþóÿðÿòãóàÉóÿÿþÿÿÓþÿÍáðíæíÿÿææëïïéêïêççñýÿ÷ëçéëéçìøÿñóãéíöÑÜúüÿÿñþÿÿöëäêóàÏìÿÿþÿÿÓþÿÌÜìîèäçïüõîìëêèçñìèêïñîêèëííêêíðóêâíòúÐØûüÿÿñþÿÿðçéòòÙÒôÿÿþÿÿèþÿÎÛññíëåðïîëêíðîëôïëèêììûîïîìêêõïêîòî÷ÐÛüüÿÿòþÿæôóôõØÒþÿÿþÿÿþÔ×ÚöõíöïòæíðíëíîìîïððïîïððïîííîïðëïöìëøÑÝýýþÿÿþôíòñøôØÙýÿÿþÿÿþâçÓï÷ìòíìðôôïìîñðëïòòðïñòïîííîððèñïíêùúÏÞþýþþÿÿþþóéñýãÍåÿÿþþÿÿÆþýòÏà÷õòíðïïíïòôóïðññïììðòííïððïìëñíîõüéÍìÿþýþþÿþýóòõðÓÐõÿÿþþÿÿÂþýùÜÖçöùöøòððôõòìêôóòðïðñóïðòóòòñðîñ÷úéÔÝûÿþýýþÿþýôÿõ×ÐçÿýÿÿþÿÿôþýþñÓÏëúùôùöö÷óñôüõôôõööõôíõùüôøûðÓÒñýÿþýýþÿþý@ÿþ7ÿþÿþÿþÿýÿýÿýûüÿÿùúüöùÿûÿÿýÿþÿýþýÿÿûóûÿþÿÿþüÿÿýùþÿÿýûýÿÿþ÷ùÿýúÿÿûóÿ ÿúþúþÿýÿ ÿüýûüÿÿýúýÿ ÿøõôúÿýùüÿÿ÷ùøüÿÿúïêïïíïîðúúÿÿýüÿÿ÷ÔÒá÷þÿÿûÿÿ÷ùÿÿõäÖÒÍÇÇÉÈÇöÆÓÈÔéóÿÿýÿÿ÷çÝÜÞåûÿýÿÿ÷ûúéÚÐÖíûÿÿ÷öçÞÕÐèÿÿþþøÿüðßÓäþÿÿúêÎÙñüÿÿþÿöþÿÿüîÝÙëÿþþøýüÿúÛÖîÿÿ÷ôâÖñÿûýýüüþýü÷ÿþûÿøÕÒúþþøûúúÿóÖßÿÿþãòÎìýþùùýüüýÿùûüÿþýÿýøÿÿùÿýûüþþïýûúÿýóÈïýþÿÿþýþþùùúþ÷ÛÚ÷ÿÿþÇáØüÿÿü÷ôÿýôýöùüþùúýþ÷ñøÿüÿÿüûþþùöùüÿþþÍÞüýþÿþýþÿÿýùüúáÝûÿÿøþÿÖáüóùÿÿÏøýöÿÿþþûûÿýõüÿÿøþøøþüôöÿÿþûüóþÓÔûûýþýýþÿôõöýÿãÓñÿÿæþÿÑèÿõúø÷úúÿöúüùúùøøûÿÿùøüüîúùÿÿþîöóôýøÿÝØúúüýýõþÿûù÷ùÿçÓ÷ÿÿñþÿÌåÿùúóöùöõõóùùãõüùøôòúýõûüüùôõýÿÿýñùùÿÞÞúúüýýõþÿùÿÿøúáÊñÿÿÅþÿÐâûôöýÿùÿýÿùóùùýôôûÿÿýûÿøø÷øüÿÿüõÿõðóþ×Úûûýþýýþÿx¿øûþçÍðÿÿÅþÿÒãÿûûÿã‘U|ãýüÿóøûúÿÿË}”øòÿÿôÿÿÇséý÷üÿ××üýþÿþýþÿŒõÿýæÍôÿÿÂþÿÎÞü÷øù®@Üÿôòëùøÿß~*VåùöÿÿÝŠ9 ;Ðÿööÿ×Ùþþÿÿþýþþ9Zõþ÷æÙòÿÿþÿÿÔþÿÈåÿö÷ø‹/2HØÿùñøÿÿ‘1+[7NØüÿó›B0@N=»ÿø÷ÿÙÚúþþÿòýÿ<[ôÿúæÔíÿÿþÿÿÔþÿÒçüôøý•;7EÞÿôÿ÷µE9@_x9Výÿ±Y'6hgEDÂÿôóüÕ×úþþÿòýÿ=[òüöãÖöÿÿþÿÿÔþÿÒãöóùû”9/IÔÿýÕm$EYkmrIS¼u!+hpjeR@¾ÿòõÿÚÜúþþÿòýÿ=`øÿ÷ÜÏõÿÿþÿÿÔþÿÌà÷ûþù2BMåö‚+(XekodgN&.Yn_ju`PAÃÿô÷ÿÔÓúþþÿòýÿ3[õÿüãÐòÿÿþÿÿÔþÿÏãøýü÷–7>E…RFkia_`cgH"?i`cbYffA?ÄÿñôþÒÔúþþÿòýÿ4ZëñõäÒòÿÿþÿÿÔþÿÐàíîìí—61 2Q^S^Q]\`e=UbaVV_c\J:ÀüåìúÔÜúþþÿòýÿ2^îêèØÌïÿÿþÿÿûþÿÍÛããÛæ#M;keX[ZadYTSE+P]T`p]WZ8:ÁúßâñËÔúþþÿòýÿ MîîêÚÑûÿÿþÿÿÔþÿÍÜäçêé…  ! -¸öÝáïÊÕúþþÿòýÿTìëðÚÒ÷ÿÿþÿÿöþÿÏÞêæåóŒþ ã+ÁÿèçðÐÕûüÿÿþóÿSêíòÝÎðÿÿþÿÿÓþÿÍÙæéèð‰Ar9    ,½øÝßìÐÙûüÿÿþóÿXñîè×ÌöÿÿþÿÿÓþÿÑÚçêçî‘Béèh&%,($%&#8ÅýäèóÒÖûüÿÿþóÿ SîñéÛËöÿÿþÿÿÓþÿÌÚëìäê‹=Óÿì·T$.,(R°d)3'"2¾÷ãêõÒÕûüÿÿþóÿ[ìóïäÏóÿÿþÿÿÓþÿËÙçèçò’/Óÿà÷ç¬/(.Mëû£J,5-¼ùäæíÎØûüÿÿþóÿ^êòìÞÎõÿÿþÿÿÓþÿÐÜçèéõ9Òýêéëÿñƒ*  ?Ïñÿñ- *¾ÿíëîÎÛûüÿÿþóÿ oéïìÜÍñÿÿþÿÿÓþÿÍÝïñéð•1ÒÿâèìÜúýÓt!RÓóÚìÿßw <ÂøåìõÓÛûüÿÿþóÿo¸ýëíå×òÿÿþÿÿÓþÿÒßïìäþÎ>làöáâêðÝïùú»`’âøðâãýÿÂnzæþÞèøÒÓûüÿÿþóÿðÿòãóàÉóÿÿþÿÿÓþÿÍáðíæíÿÿææëïïéêïêççñýÿ÷ëçéëéçìøÿñóãéíöÑÜúüÿÿñþÿÿöëäêóàÏìÿÿþÿÿÓþÿÌÜìîèäçïüõîìëêèçñìèêïñîêèëííêêíðóêâíòúÐØûüÿÿñþÿÿðçéòòÙÒôÿÿþÿÿèþÿÎÛññíëåðïîëêíðîëôïëèêììûîïîìêêõïêîòî÷ÐÛüüÿÿòþÿæôóôõØÒþÿÿþÿÿþÔ×ÚöõíöïòæíðíëíîìîïððïîïððïîííîïðëïöìëøÑÝýýþÿÿþôíòñøôØÙýÿÿþÿÿþâçÓï÷ìòíìðôôïìîñðëïòòðïñòïîííîððèñïíêùúÏÞþýþþÿÿþþóéñýãÍåÿÿþþÿÿÆþýòÏà÷õòíðïïíïòôóïðññïììðòííïððïìëñíîõüéÍìÿþýþþÿþýóòõðÓÐõÿÿþþÿÿÂþýùÜÖçöùöøòððôõòìêôóòðïðñóïðòóòòñðîñ÷úéÔÝûÿþýýþÿþýôÿõ×ÐçÿýÿÿþÿÿôþýþñÓÏëúùôùöö÷óñôüõôôõööõôíõùüôøûðÓÒñýÿþýýþÿþýÿpÿþÿþ'ÿþÿý'ÿþÿûûÿÿþÿÿþüþþý ÿ÷üúýÿÿüýþÿÿþþÿÿüüûüýýþÿúýøúýýþþÿüþùÿÿþþÿÿþÿ÷ýþþûøúüúÿÿûûüþüÿÿþü ÿûýùùüþþÿùýüúùÿÿýýü÷ÿøüÿÿüõèææçûêëîõÿÿüüþþÿÿ÷üýÿþþúìéêêéçýÿûíÞ×ÐÃÃÂôÀÅÍ×áíýÿýþþÿÿþôüÿÿîßÛØÇÇÆÆÄÄ÷úÿÿéÒÐáòÿÿöûçÒÎá÷üýýþþ÷ûÿÿîÖÌÚïÿÿ÷ýÿêÔ×éüÿýýþÿúýîãäêüüýÿùíÖÖãõÿýýþ÷ÿúÚÏïÿþôýýûüæÿøöÿÿøáÍýûüüýýüüÿüÛÊéÿÿúýþþÿ«çÏïÿòýüýüûûúùøöÿûöýÿýøûÿøúûóÿõùüúúüÿööÍêÿÿûýüýýÿôÏãûÿýôûþýúùýþüýáÓóÿôüúþúþÿýþÿúÿúþýûÿÿóõÿóÿÿöýÿüýûûÿÿÙÑàûýûÿýÿÿüìÒñÿþùöóúþüúüýüû×ÚøüøûùúÿüôüÿÿøáǬ§Ûø÷þþ×ÿüÿÿõôúûöýþÿÔÖöýüÿýÿÿüäÓýÿ÷÷úöüÿþúùúûúÑßúúîùü÷ý÷òÿÿˉ^1•ÿûÿÿ€”ÎÐ¥z£ïùýùù÷ÿÝÔøÿýþüýüÿáÑýþõúýøùúùøøùúüÏáúøúúùùøðûÿç‹J4BCˆÿýÃikF:%™öúþýüöÿäÖûÿýýüþýÿáÏøû÷ýú÷õõøûüûúúÑßúøùùøùúüÿ×^6Rca].Œÿ÷v7O,)¥ÿüøöøþ÷þÞÔúÿüýþÿÿ¸áÏùþùüóùööùüùõóùÔÝúüøøöÿïÿÖGKviH!*¡ÿÿ{tcJ,tòú÷óñø÷þØÒøÿüþÿÿþýáÏùÿööõÿÿýþÿø×Ûûÿ÷÷óñÿÒO_}MA~´»ïüùˆ}juCûþûóöùÿÝÒùÿüþÿÿúÿâÎ÷ýïóþÛÜÛÚ×Ûçó÷ÓÚýùùôýôÿw$W}N pÅñÿÿôôûŽa@aƒJ¬ÿõî÷þÿ×ÒüÿûÿÿÃþãÎÿ÷õÿÊL&=0,A_ú×Ûý÷öðøÿÁ8EˆJ#|êÿùñöôýÿ‰JJ1]r3RÖÿôððþÛÒüÿûÿÿÃýäËúôøÿ»((7@$8ú×Úúôõï÷øg"jd#dòúþëêôöøï5·ÆO1v_ ÿóòôÿÝÒüÿûÿÿÄâÊùõöüÆ>1,2*.:N÷Ó×öóöóüÙ9E~/DÒÿéñîóóòöñË·ÿÿ 1Qu(rñ÷÷õÿÔÒüÿûÿÿßÞÌýùðÿîÙÇËÐÎÑ^(öÓÖóïõóþª/M](ö÷ñööçïîøøûùùüÖO/h;>Óü÷ìþØÒüÿûÿÿààÎùóêúüúöÿùÿÿÝeùÖÖïêïíø~/[D+ ôëååææçééãíìæõëp-\S$¸úìäùØÒüÿûÿÿÃþâÎëëéêçåøñîæäÿåùÖÔêâéæðp!b<*²ñâáâÞØÜâßÛÛÔÖéîŠ(DV#±õààîËÒüÿûÿÿÄâËäèæÝÜßáÍääêÎè÷ÔÑçÞåãír"»îâÛåæÛÞââææäãæï‰ ªôÝæòÒÓýÿûÿÿÒßÈæíäÛçâÝéàáÚììúÔÑéâåãðƒ©ñÚêàÞçêáÝàáåÜåðr€»õàïéÑÐÿýÿÿþýÿÿÛÎáìá×áãàãäÜàêæúÕÒëãæäðsòîçÝÛáäåâØäàÜùÞC 4ÆïàíìÓÐÿýÿÿþýÿÿßÈáìßääéçÞîíôÙaúÔÓìåçåîË0=ÎëÝâìêÝÛçìÞäðüŸeØéáåíÔÐÿýÿÿþýÿÿãÅæìßòØÛØãÏÚÏbùÓÓìåçäìç_ |åìçââãááäÙêûÓMšìçãÞîÕÐÿýÿÿþýÿþäÇðëáú¹1!øÒÓíåçâéø¥(0‡çòéÝãåäìîÿÖ] 1 IËõäçáòÓÐÿýÿÿþýÿýáÈóèäÿ¨ ÷ÒÓîçèâéõìr&9 †Ê÷ôîíìóã¸_ <¦ìñâëè÷ÒÐÿýÿÿþýÿþßÇîçæÿ·/):'5>'YøÕÕðéêåêåûÍJ.*F‡°ÆÍ¿§x,"; mèòéæìêøÓÐÿýÿÿþýÿþàÈéîåõÙ½¿ÊÜɼÞîúÖ×òëìæëòßÿÆ3 +1$ &;F8 /: [éþéäëêåöÖÐÿýÿÿþýÿþäËêøäéñòýÿ÷ýûçöÿÑÚòñíééèçïüÉF "!* ('uà÷íêáïíéîÔØÿÿüÿþýÿÿãÉïôçåâíæäæèçéë÷ÕÕëôïêìïòíóüÖx( 5šòÿåéìêòêçñØÒüÿûÿþþÿûßËìñïòæìèçéëëìîôÖÔïòëïìæìîêôÿñ»i< IÎûÿðîî€1ëîéïø×ÎøþùþþÿþÿäÓïñêîçîëëíîííîúØÖõñæôèìæííäíÿÿùÕµ”~y‚»èÿÿúåä÷ñïìíêõùÖÒøþúýþÿüýàÐïûêìøðïïððîíìÿáÑîùíïìñðñðêêïòúýÿÿôñöÿþûïåéïððíðñóñõñÔÝüÿüþþÿüÿéÑãÿóê÷îïññððïîÿñÐÚýøêóïóòðïîïóäíöøøûú÷îíôúöñððòïìôüøäÎìÿÿþÿþÿýÿùÜÓóùïéêïññòóôóÿúáÓèóïú÷ïíöúóïðòóñïðòíçõðìðóòòôöóíòøëÙÚøÿüþÿýÿÿýúêÏßñûòíóõóóõöõÿúøØÇæùü÷ðöûõôøöô÷ööùéîùøôøøõøðüþôæÍÐöþÿùýÿýÿÿñüúÙÍÜúüöúúõóôöópÿþÿþ'ÿþÿý'ÿþÿûûÿÿþÿÿþüþþý ÿ÷üúýÿÿüýþÿÿþþÿÿüüûüýýþÿúýøúýýþþÿüþùÿÿþþÿÿþÿ÷ýþþûøúüúÿÿûûüþüÿÿþü ÿûýùùüþþÿùýüúùÿÿýýü÷ÿøüÿÿüõèææçûêëîõÿÿüüþþÿÿ÷üýÿþþúìéêêéçýÿûíÞ×ÐÃÃÂôÀÅÍ×áíýÿýþþÿÿþôüÿÿîßÛØÇÇÆÆÄÄ÷úÿÿéÒÐáòÿÿöûçÒÎá÷üýýþþ÷ûÿÿîÖÌÚïÿÿ÷ýÿêÔ×éüÿýýþÿúýîãäêüüýÿùíÖÖãõÿýýþ÷ÿúÚÏïÿþôýýûüæÿøöÿÿøáÍýûüüýýüüÿüÛÊéÿÿúýþþÿ«çÏïÿòýüýüûûúùøöÿûöýÿýøûÿøúûóÿõùüúúüÿööÍêÿÿûýüýýÿôÏãûÿýôûþýúùýþüýáÓóÿôüúþúþÿýþÿúÿúþýûÿÿóõÿóÿÿöýÿüýûûÿÿÙÑàûýûÿýÿÿüìÒñÿþùöóúþüúüýüû×ÚøüøûùúÿüôüÿÿøáǬ§Ûø÷þþ×ÿüÿÿõôúûöýþÿÔÖöýüÿýÿÿüäÓýÿ÷÷úöüÿþúùúûúÑßúúîùü÷ý÷òÿÿˉ^1•ÿûÿÿ€”ÎÐ¥z£ïùýùù÷ÿÝÔøÿýþüýüÿáÑýþõúýøùúùøøùúüÏáúøúúùùøðûÿç‹J4BCˆÿýÃikF:%™öúþýüöÿäÖûÿýýüþýÿáÏøû÷ýú÷õõøûüûúúÑßúøùùøùúüÿ×^6Rca].Œÿ÷v7O,)¥ÿüøöøþ÷þÞÔúÿüýþÿÿ¸áÏùþùüóùööùüùõóùÔÝúüøøöÿïÿÖGKviH!*¡ÿÿ{tcJ,tòú÷óñø÷þØÒøÿüþÿÿþýáÏùÿööõÿÿýþÿø×Ûûÿ÷÷óñÿÒO_}MA~´»ïüùˆ}juCûþûóöùÿÝÒùÿüþÿÿúÿâÎ÷ýïóþÛÜÛÚ×Ûçó÷ÓÚýùùôýôÿw$W}N pÅñÿÿôôûŽa@aƒJ¬ÿõî÷þÿ×ÒüÿûÿÿÃþãÎÿ÷õÿÊL&=0,A_ú×Ûý÷öðøÿÁ8EˆJ#|êÿùñöôýÿ‰JJ1]r3RÖÿôððþÛÒüÿûÿÿÃýäËúôøÿ»((7@$8ú×Úúôõï÷øg"jd#dòúþëêôöøï5·ÆO1v_ ÿóòôÿÝÒüÿûÿÿÄâÊùõöüÆ>1,2*.:N÷Ó×öóöóüÙ9E~/DÒÿéñîóóòöñË·ÿÿ 1Qu(rñ÷÷õÿÔÒüÿûÿÿßÞÌýùðÿîÙÇËÐÎÑ^(öÓÖóïõóþª/M](ö÷ñööçïîøøûùùüÖO/h;>Óü÷ìþØÒüÿûÿÿààÎùóêúüúöÿùÿÿÝeùÖÖïêïíø~/[D+ ôëååææçééãíìæõëp-\S$¸úìäùØÒüÿûÿÿÃþâÎëëéêçåøñîæäÿåùÖÔêâéæðp!b<*²ñâáâÞØÜâßÛÛÔÖéîŠ(DV#±õààîËÒüÿûÿÿÄâËäèæÝÜßáÍääêÎè÷ÔÑçÞåãír"»îâÛåæÛÞââææäãæï‰ ªôÝæòÒÓýÿûÿÿÒßÈæíäÛçâÝéàáÚììúÔÑéâåãðƒ©ñÚêàÞçêáÝàáåÜåðr€»õàïéÑÐÿýÿÿþýÿÿÛÎáìá×áãàãäÜàêæúÕÒëãæäðsòîçÝÛáäåâØäàÜùÞC 4ÆïàíìÓÐÿýÿÿþýÿÿßÈáìßääéçÞîíôÙaúÔÓìåçåîË0=ÎëÝâìêÝÛçìÞäðüŸeØéáåíÔÐÿýÿÿþýÿÿãÅæìßòØÛØãÏÚÏbùÓÓìåçäìç_ |åìçââãááäÙêûÓMšìçãÞîÕÐÿýÿÿþýÿþäÇðëáú¹1!øÒÓíåçâéø¥(0‡çòéÝãåäìîÿÖ] 1 IËõäçáòÓÐÿýÿÿþýÿýáÈóèäÿ¨ ÷ÒÓîçèâéõìr&9 †Ê÷ôîíìóã¸_ <¦ìñâëè÷ÒÐÿýÿÿþýÿþßÇîçæÿ·/):'5>'YøÕÕðéêåêåûÍJ.*F‡°ÆÍ¿§x,"; mèòéæìêøÓÐÿýÿÿþýÿþàÈéîåõÙ½¿ÊÜɼÞîúÖ×òëìæëòßÿÆ3 +1$ &;F8 /: [éþéäëêåöÖÐÿýÿÿþýÿþäËêøäéñòýÿ÷ýûçöÿÑÚòñíééèçïüÉF "!* ('uà÷íêáïíéîÔØÿÿüÿþýÿÿãÉïôçåâíæäæèçéë÷ÕÕëôïêìïòíóüÖx( 5šòÿåéìêòêçñØÒüÿûÿþþÿûßËìñïòæìèçéëëìîôÖÔïòëïìæìîêôÿñ»i< IÎûÿðîî€1ëîéïø×ÎøþùþþÿþÿäÓïñêîçîëëíîííîúØÖõñæôèìæííäíÿÿùÕµ”~y‚»èÿÿúåä÷ñïìíêõùÖÒøþúýþÿüýàÐïûêìøðïïððîíìÿáÑîùíïìñðñðêêïòúýÿÿôñöÿþûïåéïððíðñóñõñÔÝüÿüþþÿüÿéÑãÿóê÷îïññððïîÿñÐÚýøêóïóòðïîïóäíöøøûú÷îíôúöñððòïìôüøäÎìÿÿþÿþÿýÿùÜÓóùïéêïññòóôóÿúáÓèóïú÷ïíöúóïðòóñïðòíçõðìðóòòôöóíòøëÙÚøÿüþÿýÿÿýúêÏßñûòíóõóóõöõÿúøØÇæùü÷ðöûõôøöô÷ööùéîùøôøøõøðüþôæÍÐöþÿùýÿýÿÿñüúÙÍÜúüöúúõóôöópÿþÿþ'ÿþÿý'ÿþÿûûÿÿþÿÿþüþþý ÿ÷üúýÿÿüýþÿÿþþÿÿüüûüýýþÿúýøúýýþþÿüþùÿÿþþÿÿþÿ÷ýþþûøúüúÿÿûûüþüÿÿþü ÿûýùùüþþÿùýüúùÿÿýýü÷ÿøüÿÿüõèææçûêëîõÿÿüüþþÿÿ÷üýÿþþúìéêêéçýÿûíÞ×ÐÃÃÂôÀÅÍ×áíýÿýþþÿÿþôüÿÿîßÛØÇÇÆÆÄÄ÷úÿÿéÒÐáòÿÿöûçÒÎá÷üýýþþ÷ûÿÿîÖÌÚïÿÿ÷ýÿêÔ×éüÿýýþÿúýîãäêüüýÿùíÖÖãõÿýýþ÷ÿúÚÏïÿþôýýûüæÿøöÿÿøáÍýûüüýýüüÿüÛÊéÿÿúýþþÿ«çÏïÿòýüýüûûúùøöÿûöýÿýøûÿøúûóÿõùüúúüÿööÍêÿÿûýüýýÿôÏãûÿýôûþýúùýþüýáÓóÿôüúþúþÿýþÿúÿúþýûÿÿóõÿóÿÿöýÿüýûûÿÿÙÑàûýûÿýÿÿüìÒñÿþùöóúþüúüýüû×ÚøüøûùúÿüôüÿÿøáǬ§Ûø÷þþ×ÿüÿÿõôúûöýþÿÔÖöýüÿýÿÿüäÓýÿ÷÷úöüÿþúùúûúÑßúúîùü÷ý÷òÿÿˉ^1•ÿûÿÿ€”ÎÐ¥z£ïùýùù÷ÿÝÔøÿýþüýüÿáÑýþõúýøùúùøøùúüÏáúøúúùùøðûÿç‹J4BCˆÿýÃikF:%™öúþýüöÿäÖûÿýýüþýÿáÏøû÷ýú÷õõøûüûúúÑßúøùùøùúüÿ×^6Rca].Œÿ÷v7O,)¥ÿüøöøþ÷þÞÔúÿüýþÿÿ¸áÏùþùüóùööùüùõóùÔÝúüøøöÿïÿÖGKviH!*¡ÿÿ{tcJ,tòú÷óñø÷þØÒøÿüþÿÿþýáÏùÿööõÿÿýþÿø×Ûûÿ÷÷óñÿÒO_}MA~´»ïüùˆ}juCûþûóöùÿÝÒùÿüþÿÿúÿâÎ÷ýïóþÛÜÛÚ×Ûçó÷ÓÚýùùôýôÿw$W}N pÅñÿÿôôûŽa@aƒJ¬ÿõî÷þÿ×ÒüÿûÿÿÃþãÎÿ÷õÿÊL&=0,A_ú×Ûý÷öðøÿÁ8EˆJ#|êÿùñöôýÿ‰JJ1]r3RÖÿôððþÛÒüÿûÿÿÃýäËúôøÿ»((7@$8ú×Úúôõï÷øg"jd#dòúþëêôöøï5·ÆO1v_ ÿóòôÿÝÒüÿûÿÿÄâÊùõöüÆ>1,2*.:N÷Ó×öóöóüÙ9E~/DÒÿéñîóóòöñË·ÿÿ 1Qu(rñ÷÷õÿÔÒüÿûÿÿßÞÌýùðÿîÙÇËÐÎÑ^(öÓÖóïõóþª/M](ö÷ñööçïîøøûùùüÖO/h;>Óü÷ìþØÒüÿûÿÿààÎùóêúüúöÿùÿÿÝeùÖÖïêïíø~/[D+ ôëååææçééãíìæõëp-\S$¸úìäùØÒüÿûÿÿÃþâÎëëéêçåøñîæäÿåùÖÔêâéæðp!b<*²ñâáâÞØÜâßÛÛÔÖéîŠ(DV#±õààîËÒüÿûÿÿÄâËäèæÝÜßáÍääêÎè÷ÔÑçÞåãír"»îâÛåæÛÞââææäãæï‰ ªôÝæòÒÓýÿûÿÿÒßÈæíäÛçâÝéàáÚììúÔÑéâåãðƒ©ñÚêàÞçêáÝàáåÜåðr€»õàïéÑÐÿýÿÿþýÿÿÛÎáìá×áãàãäÜàêæúÕÒëãæäðsòîçÝÛáäåâØäàÜùÞC 4ÆïàíìÓÐÿýÿÿþýÿÿßÈáìßääéçÞîíôÙaúÔÓìåçåîË0=ÎëÝâìêÝÛçìÞäðüŸeØéáåíÔÐÿýÿÿþýÿÿãÅæìßòØÛØãÏÚÏbùÓÓìåçäìç_ |åìçââãááäÙêûÓMšìçãÞîÕÐÿýÿÿþýÿþäÇðëáú¹1!øÒÓíåçâéø¥(0‡çòéÝãåäìîÿÖ] 1 IËõäçáòÓÐÿýÿÿþýÿýáÈóèäÿ¨ ÷ÒÓîçèâéõìr&9 †Ê÷ôîíìóã¸_ <¦ìñâëè÷ÒÐÿýÿÿþýÿþßÇîçæÿ·/):'5>'YøÕÕðéêåêåûÍJ.*F‡°ÆÍ¿§x,"; mèòéæìêøÓÐÿýÿÿþýÿþàÈéîåõÙ½¿ÊÜɼÞîúÖ×òëìæëòßÿÆ3 +1$ &;F8 /: [éþéäëêåöÖÐÿýÿÿþýÿþäËêøäéñòýÿ÷ýûçöÿÑÚòñíééèçïüÉF "!* ('uà÷íêáïíéîÔØÿÿüÿþýÿÿãÉïôçåâíæäæèçéë÷ÕÕëôïêìïòíóüÖx( 5šòÿåéìêòêçñØÒüÿûÿþþÿûßËìñïòæìèçéëëìîôÖÔïòëïìæìîêôÿñ»i< IÎûÿðîî€1ëîéïø×ÎøþùþþÿþÿäÓïñêîçîëëíîííîúØÖõñæôèìæííäíÿÿùÕµ”~y‚»èÿÿúåä÷ñïìíêõùÖÒøþúýþÿüýàÐïûêìøðïïððîíìÿáÑîùíïìñðñðêêïòúýÿÿôñöÿþûïåéïððíðñóñõñÔÝüÿüþþÿüÿéÑãÿóê÷îïññððïîÿñÐÚýøêóïóòðïîïóäíöøøûú÷îíôúöñððòïìôüøäÎìÿÿþÿþÿýÿùÜÓóùïéêïññòóôóÿúáÓèóïú÷ïíöúóïðòóñïðòíçõðìðóòòôöóíòøëÙÚøÿüþÿýÿÿýúêÏßñûòíóõóóõöõÿúøØÇæùü÷ðöûõôøöô÷ööùéîùøôøøõøðüþôæÍÐöþÿùýÿýÿÿñüúÙÍÜúüöúúõóôöóÿÿýüÿôûýÿÿûýþÿÿþþÿÿüÿýþÿþþýÿ÷ýüþÿýöøþÿÿ÷þýýþþüúúûûüÿýþøÿûùþÿýþÿÿõþýþÿþÿÿûúýÿÿýüçëøîúÿÿôüýÿ ÿýõìççþèÃÃÄõÈÉÊ×ìþÿúüþÿÿøüûÿüîÚÌÁÁÄþÅÿÿóþöè×Ñáøûýÿÿþýý÷üÿÿñßÖÚãÿÿþòûýÿÿöãÛÝûüþÿþüü÷øÿýãÒÝöÿýýþýüÿþüÿÿúçÌ÷ùüþþ÷ûÿñÛßûÿûúúüý¿úûûüüûûúÿöúÿøúý÷ÿòúþüÿúÖÒÿÿþýÿÿüþÿÛÖõþÿôøúûûúúüþýþûôûÿðÿÿúôÿÿöûúûûü÷ÄÿûòÿÿõüÿèÌÿýýüÿÿüÿÿÕÚúûýú÷øúúûûüýóþûÿùíÿööÿÿýúûýüüûûúúûûüöøýýóöøûùüÿÿöüÿìÅýýÛûÿþýþúÑÞÿùûýø÷øùúûüûûòÿíÿÿùôýü÷øúüöþûûúû…þúÿùøÿÿêõÿýóùÿÿ÷ÃüþÿûþþýýùÑáÿùùüùø÷øùúùøÿ÷üÿþ­½ýüÿúõúÿÿþùùúûûúùùúøýóöòÿÿñü÷ùúööîÃýÿÿüþþýüûÔßÿúùøúø÷÷øøöõîÿÿÃjYâÿ÷þÿíÖÞÿøøùùøÝò÷ÿò˜ÿÿöïþ÷÷ÿõÄþÿÿýÿÿþûþÖÞþúùôùø÷ööÐõô÷ÿÄ7 -EØÿïôù†8W›ùø÷öö÷øùÿúûÿîE!šþÿÿ÷îõÿ÷ÃüþÿüÿÿüøÕÞþùùöõööõæöÿÇ@(cM3´øûÿèQ 1Dýøõóóõøýÿÿîùayåÿóô÷ùïÁùûýüÿÿúüúÒßÿøø€5òôööõõ÷úíU"ayS&¶ÿïúÿ|),óÿóýùôÿäm&2976[[SÖþîÿùñÄûýÿüýþÿþöÓÝûùøøóóöÿûüþö“)]yeb$™ÿå¢â¾w,jöÿëúÿåt03=&,HtI€ÿ÷ëõñÄûýÿüýþÿÿ÷ÔÝùöôóöÿíêãïêÎJpkb[6“ÿÁ ÿítcòÿöåt49/).91e_YÏÿî÷þæÃúýÿýýþÿÿùÕÝøõóóøìbV_^;'ok_qc3{÷ò/!ÃÿÑ[!sÿùu334¦éìÕ_# UÝÿîôÿôêÃúýÿýþþÿÿøÕßøõôôÿÛU-8?MA_da\h_'{îÿÿÄ%yÿÿU1|…*<¶ûÿûûI^éýîðûôóñÃúýÿþþÿ€Î÷ÕÛôïîîÿ×O=ZU[YaOYWW[(rÿò÷ÿ_cðúY&F ' ÿìãòÚ7;Þüìäñçå÷çÂúýÿþþýþÿ÷Ò×íæãâîÖT;[^_[^YQX[W5oåèÞÿwJÖùãkŽÿáÝäèÙªÖðßÜÙâÜÚçßÃúýÿþþýþÿ÷ÒÕêâÞÝóÛM! ( (#iÜë×ù†IËóè\õâãÞîÜ—ÌðãáâëåáèÝÃúþÿÿþýþÿøÓ×ìäááìÖG×aêóá÷„CÌý]  œìóÛéáJ=ÙëääáÜÝãë¾ýÿÿÂþüþÿùÓÔéåãâîÓD   wïßäÿHZçñyl³åíøêKJçóáÙéìåß¾ýÿÿÃüþÿùÓÔêæäâòÑQ %  {âíøº |òèzîçj7¡ÞçÓQKÂôæãÝÜã¿ýÿÿÂüþÿúÔÕëçåääéÁ²¶¶§h0'!yûß‚¿ýÈeççéè_"+#UÄõæåïê¿ýþÿÿÃüþÿúÕÖìèæåàêãççñøÒ+(-3 “ÿº ”þÛhoçòÜÝóäg "1%xëàçñÚÀýþþÃÿýþÿúÕÖìéçæãåäëåáëåŽ%77 ÿÚ‚¥Í¤g ÝýÞééÜúÛgCCKG##PÆñäëéæÂýý€¥þÿýþÿúÕ×íéèçîèäéèáäîïa-©ÿèÿùgîàôëêóâôýèíÿéTvàÿæäêåëÂýüýþÿýþÿúÕÖíéèçëéèççæäéùÐK ËÿÛöÝ;*éååçæãäëêííýïM‘þøàìïäóéÂýüüþÿýþÿùÔÖìéèçæëñèäîëéèÿÐ_;Ðõéìè‡CFªëëßîíèûÛ†›ÿòëáìîâéíÀÿúýþýÿüÿöÔÙøêíìëëìíïëèþçŠApåòâåöðÝåÿëëßåïêéèäðøèðëêçåðò¾ÿûýÿýþüûùÛØ÷íïìëëïíãòýôßÙîôíêîñîîðììßëóìåëüýäåîíëíðóì»ÿýýÿþüüþýÜÒóíïñííìïñçæèùÿúìííéçîõïäííÝïóîðôëçïêîííñôñéÁÿþýÿÿúýÿýÙÐ÷ñìðññððïïëïñëçéîóïíîñòïííïïÛíïîïóñîôïóóêëôïãÏÿþþÿÿúýÿüÜÎöúòêòòññððîïîîïõôíìíîìîóðêëóññÞòêòïéòóêðòòêóþèÎäÿüÿþÿüþüÿçÇã÷ûññððïòïçéíêíèìîîêêîîìóóÝõïøõðõõ÷óìòõøñÚÏøÿúÿüþýþüÿ÷Ô×âôúòòóóïïöôõóñù÷ó÷÷òóùøñööÝñúøìøüî÷øêøÿìÎÍñÿÿøÿûþÿÿùþÿïÜÌàù÷÷øøùð÷ùôûûôøõôöøù÷õõöÿýüÿôûýÿÿûýþÿÿþþÿÿüÿýþÿþþýÿ÷ýüþÿýöøþÿÿ÷þýýþþüúúûûüÿýþøÿûùþÿýþÿÿõþýþÿþÿÿûúýÿÿýüçëøîúÿÿôüýÿ ÿýõìççþèÃÃÄõÈÉÊ×ìþÿúüþÿÿøüûÿüîÚÌÁÁÄþÅÿÿóþöè×Ñáøûýÿÿþýý÷üÿÿñßÖÚãÿÿþòûýÿÿöãÛÝûüþÿþüü÷øÿýãÒÝöÿýýþýüÿþüÿÿúçÌ÷ùüþþ÷ûÿñÛßûÿûúúüý¿úûûüüûûúÿöúÿøúý÷ÿòúþüÿúÖÒÿÿþýÿÿüþÿÛÖõþÿôøúûûúúüþýþûôûÿðÿÿúôÿÿöûúûûü÷ÄÿûòÿÿõüÿèÌÿýýüÿÿüÿÿÕÚúûýú÷øúúûûüýóþûÿùíÿööÿÿýúûýüüûûúúûûüöøýýóöøûùüÿÿöüÿìÅýýÛûÿþýþúÑÞÿùûýø÷øùúûüûûòÿíÿÿùôýü÷øúüöþûûúû…þúÿùøÿÿêõÿýóùÿÿ÷ÃüþÿûþþýýùÑáÿùùüùø÷øùúùøÿ÷üÿþ­½ýüÿúõúÿÿþùùúûûúùùúøýóöòÿÿñü÷ùúööîÃýÿÿüþþýüûÔßÿúùøúø÷÷øøöõîÿÿÃjYâÿ÷þÿíÖÞÿøøùùøÝò÷ÿò˜ÿÿöïþ÷÷ÿõÄþÿÿýÿÿþûþÖÞþúùôùø÷ööÐõô÷ÿÄ7 -EØÿïôù†8W›ùø÷öö÷øùÿúûÿîE!šþÿÿ÷îõÿ÷ÃüþÿüÿÿüøÕÞþùùöõööõæöÿÇ@(cM3´øûÿèQ 1Dýøõóóõøýÿÿîùayåÿóô÷ùïÁùûýüÿÿúüúÒßÿøø€5òôööõõ÷úíU"ayS&¶ÿïúÿ|),óÿóýùôÿäm&2976[[SÖþîÿùñÄûýÿüýþÿþöÓÝûùøøóóöÿûüþö“)]yeb$™ÿå¢â¾w,jöÿëúÿåt03=&,HtI€ÿ÷ëõñÄûýÿüýþÿÿ÷ÔÝùöôóöÿíêãïêÎJpkb[6“ÿÁ ÿítcòÿöåt49/).91e_YÏÿî÷þæÃúýÿýýþÿÿùÕÝøõóóøìbV_^;'ok_qc3{÷ò/!ÃÿÑ[!sÿùu334¦éìÕ_# UÝÿîôÿôêÃúýÿýþþÿÿøÕßøõôôÿÛU-8?MA_da\h_'{îÿÿÄ%yÿÿU1|…*<¶ûÿûûI^éýîðûôóñÃúýÿþþÿ€Î÷ÕÛôïîîÿ×O=ZU[YaOYWW[(rÿò÷ÿ_cðúY&F ' ÿìãòÚ7;Þüìäñçå÷çÂúýÿþþýþÿ÷Ò×íæãâîÖT;[^_[^YQX[W5oåèÞÿwJÖùãkŽÿáÝäèÙªÖðßÜÙâÜÚçßÃúýÿþþýþÿ÷ÒÕêâÞÝóÛM! ( (#iÜë×ù†IËóè\õâãÞîÜ—ÌðãáâëåáèÝÃúþÿÿþýþÿøÓ×ìäááìÖG×aêóá÷„CÌý]  œìóÛéáJ=ÙëääáÜÝãë¾ýÿÿÂþüþÿùÓÔéåãâîÓD   wïßäÿHZçñyl³åíøêKJçóáÙéìåß¾ýÿÿÃüþÿùÓÔêæäâòÑQ %  {âíøº |òèzîçj7¡ÞçÓQKÂôæãÝÜã¿ýÿÿÂüþÿúÔÕëçåääéÁ²¶¶§h0'!yûß‚¿ýÈeççéè_"+#UÄõæåïê¿ýþÿÿÃüþÿúÕÖìèæåàêãççñøÒ+(-3 “ÿº ”þÛhoçòÜÝóäg "1%xëàçñÚÀýþþÃÿýþÿúÕÖìéçæãåäëåáëåŽ%77 ÿÚ‚¥Í¤g ÝýÞééÜúÛgCCKG##PÆñäëéæÂýý€¥þÿýþÿúÕ×íéèçîèäéèáäîïa-©ÿèÿùgîàôëêóâôýèíÿéTvàÿæäêåëÂýüýþÿýþÿúÕÖíéèçëéèççæäéùÐK ËÿÛöÝ;*éååçæãäëêííýïM‘þøàìïäóéÂýüüþÿýþÿùÔÖìéèçæëñèäîëéèÿÐ_;Ðõéìè‡CFªëëßîíèûÛ†›ÿòëáìîâéíÀÿúýþýÿüÿöÔÙøêíìëëìíïëèþçŠApåòâåöðÝåÿëëßåïêéèäðøèðëêçåðò¾ÿûýÿýþüûùÛØ÷íïìëëïíãòýôßÙîôíêîñîîðììßëóìåëüýäåîíëíðóì»ÿýýÿþüüþýÜÒóíïñííìïñçæèùÿúìííéçîõïäííÝïóîðôëçïêîííñôñéÁÿþýÿÿúýÿýÙÐ÷ñìðññððïïëïñëçéîóïíîñòïííïïÛíïîïóñîôïóóêëôïãÏÿþþÿÿúýÿüÜÎöúòêòòññððîïîîïõôíìíîìîóðêëóññÞòêòïéòóêðòòêóþèÎäÿüÿþÿüþüÿçÇã÷ûññððïòïçéíêíèìîîêêîîìóóÝõïøõðõõ÷óìòõøñÚÏøÿúÿüþýþüÿ÷Ô×âôúòòóóïïöôõóñù÷ó÷÷òóùøñööÝñúøìøüî÷øêøÿìÎÍñÿÿøÿûþÿÿùþÿïÜÌàù÷÷øøùð÷ùôûûôøõôöøù÷õõöÿýüÿôûýÿÿûýþÿÿþþÿÿüÿýþÿþþýÿ÷ýüþÿýöøþÿÿ÷þýýþþüúúûûüÿýþøÿûùþÿýþÿÿõþýþÿþÿÿûúýÿÿýüçëøîúÿÿôüýÿ ÿýõìççþèÃÃÄõÈÉÊ×ìþÿúüþÿÿøüûÿüîÚÌÁÁÄþÅÿÿóþöè×Ñáøûýÿÿþýý÷üÿÿñßÖÚãÿÿþòûýÿÿöãÛÝûüþÿþüü÷øÿýãÒÝöÿýýþýüÿþüÿÿúçÌ÷ùüþþ÷ûÿñÛßûÿûúúüý¿úûûüüûûúÿöúÿøúý÷ÿòúþüÿúÖÒÿÿþýÿÿüþÿÛÖõþÿôøúûûúúüþýþûôûÿðÿÿúôÿÿöûúûûü÷ÄÿûòÿÿõüÿèÌÿýýüÿÿüÿÿÕÚúûýú÷øúúûûüýóþûÿùíÿööÿÿýúûýüüûûúúûûüöøýýóöøûùüÿÿöüÿìÅýýÛûÿþýþúÑÞÿùûýø÷øùúûüûûòÿíÿÿùôýü÷øúüöþûûúû…þúÿùøÿÿêõÿýóùÿÿ÷ÃüþÿûþþýýùÑáÿùùüùø÷øùúùøÿ÷üÿþ­½ýüÿúõúÿÿþùùúûûúùùúøýóöòÿÿñü÷ùúööîÃýÿÿüþþýüûÔßÿúùøúø÷÷øøöõîÿÿÃjYâÿ÷þÿíÖÞÿøøùùøÝò÷ÿò˜ÿÿöïþ÷÷ÿõÄþÿÿýÿÿþûþÖÞþúùôùø÷ööÐõô÷ÿÄ7 -EØÿïôù†8W›ùø÷öö÷øùÿúûÿîE!šþÿÿ÷îõÿ÷ÃüþÿüÿÿüøÕÞþùùöõööõæöÿÇ@(cM3´øûÿèQ 1Dýøõóóõøýÿÿîùayåÿóô÷ùïÁùûýüÿÿúüúÒßÿøø€5òôööõõ÷úíU"ayS&¶ÿïúÿ|),óÿóýùôÿäm&2976[[SÖþîÿùñÄûýÿüýþÿþöÓÝûùøøóóöÿûüþö“)]yeb$™ÿå¢â¾w,jöÿëúÿåt03=&,HtI€ÿ÷ëõñÄûýÿüýþÿÿ÷ÔÝùöôóöÿíêãïêÎJpkb[6“ÿÁ ÿítcòÿöåt49/).91e_YÏÿî÷þæÃúýÿýýþÿÿùÕÝøõóóøìbV_^;'ok_qc3{÷ò/!ÃÿÑ[!sÿùu334¦éìÕ_# UÝÿîôÿôêÃúýÿýþþÿÿøÕßøõôôÿÛU-8?MA_da\h_'{îÿÿÄ%yÿÿU1|…*<¶ûÿûûI^éýîðûôóñÃúýÿþþÿ€Î÷ÕÛôïîîÿ×O=ZU[YaOYWW[(rÿò÷ÿ_cðúY&F ' ÿìãòÚ7;Þüìäñçå÷çÂúýÿþþýþÿ÷Ò×íæãâîÖT;[^_[^YQX[W5oåèÞÿwJÖùãkŽÿáÝäèÙªÖðßÜÙâÜÚçßÃúýÿþþýþÿ÷ÒÕêâÞÝóÛM! ( (#iÜë×ù†IËóè\õâãÞîÜ—ÌðãáâëåáèÝÃúþÿÿþýþÿøÓ×ìäááìÖG×aêóá÷„CÌý]  œìóÛéáJ=ÙëääáÜÝãë¾ýÿÿÂþüþÿùÓÔéåãâîÓD   wïßäÿHZçñyl³åíøêKJçóáÙéìåß¾ýÿÿÃüþÿùÓÔêæäâòÑQ %  {âíøº |òèzîçj7¡ÞçÓQKÂôæãÝÜã¿ýÿÿÂüþÿúÔÕëçåääéÁ²¶¶§h0'!yûß‚¿ýÈeççéè_"+#UÄõæåïê¿ýþÿÿÃüþÿúÕÖìèæåàêãççñøÒ+(-3 “ÿº ”þÛhoçòÜÝóäg "1%xëàçñÚÀýþþÃÿýþÿúÕÖìéçæãåäëåáëåŽ%77 ÿÚ‚¥Í¤g ÝýÞééÜúÛgCCKG##PÆñäëéæÂýý€¥þÿýþÿúÕ×íéèçîèäéèáäîïa-©ÿèÿùgîàôëêóâôýèíÿéTvàÿæäêåëÂýüýþÿýþÿúÕÖíéèçëéèççæäéùÐK ËÿÛöÝ;*éååçæãäëêííýïM‘þøàìïäóéÂýüüþÿýþÿùÔÖìéèçæëñèäîëéèÿÐ_;Ðõéìè‡CFªëëßîíèûÛ†›ÿòëáìîâéíÀÿúýþýÿüÿöÔÙøêíìëëìíïëèþçŠApåòâåöðÝåÿëëßåïêéèäðøèðëêçåðò¾ÿûýÿýþüûùÛØ÷íïìëëïíãòýôßÙîôíêîñîîðììßëóìåëüýäåîíëíðóì»ÿýýÿþüüþýÜÒóíïñííìïñçæèùÿúìííéçîõïäííÝïóîðôëçïêîííñôñéÁÿþýÿÿúýÿýÙÐ÷ñìðññððïïëïñëçéîóïíîñòïííïïÛíïîïóñîôïóóêëôïãÏÿþþÿÿúýÿüÜÎöúòêòòññððîïîîïõôíìíîìîóðêëóññÞòêòïéòóêðòòêóþèÎäÿüÿþÿüþüÿçÇã÷ûññððïòïçéíêíèìîîêêîîìóóÝõïøõðõõ÷óìòõøñÚÏøÿúÿüþýþüÿ÷Ô×âôúòòóóïïöôõóñù÷ó÷÷òóùøñööÝñúøìøüî÷øêøÿìÎÍñÿÿøÿûþÿÿùþÿïÜÌàù÷÷øøùð÷ùôûûôøõôöøù÷õõöÿ@ÿþ'ÿþÿþÿþÿþýÿþÿøúÿÿþþÿÿþþóüýÿÿýÿýýûùÿÿþþûýûúüþþüÿþþÿÿýýûÿÿýüïýúøúþüþÿÿþþýúþüþÿÿ÷þùÿÿþüüýÿÿþüÿÿþÿþÿ÷üþÿÿþùûýÿÿûýúûüÿÿ÷úüýÿÿþû÷ýýÿýÿüþýþþÿÞèæãåðüÿûüýûýÿÿüÿüÿÿúýÿÿùòîçãäæéêèç çþèååõçêòüÿýÿÿýýÿÿøºÁÉÏÑÜóÿÿéúùÿÿýÿþüúþÿþëÙÌÈÂÀÁÃÆÇÄ ÄñÅÄÄÈÌÊÌßöýÿÿýüÿÿåþýýìÕÒÝüÿüøÿÿüýÿøþÿôÜÖØùûþÿÿþüÿÿõùèÝÛñüÿþüþÿÿùéþÿïÛÍéþÿúþþûýÿúÿüØÊáôüûûþýþþòýúùÿÿýéÕßðýÿþÿÿæùÿþøýÿó×Ö÷ÿüýþüÿþûÿíÍÙýÿýÿÿûüúùùüüôúÿÿûùýûòÐçûÿÿôöþúÿûñýùÅèÿþþïùÿýÿüÖß÷ÿùüýýþýýûûäüýüôÿüÿýûõðòüÿÿýøÿÿùýöðìÇåÿþþäÿøÿùúûúÿþÎçÿÿþýúÿþÿøÕâùÿúüüûûÓÿüõÿýüôüûøõ÷øùöóÿüöúÿöìÿðÊæÿþþÿÿ÷üùùûûüûÜáüÿýýÿüòÒéûûÚüûúùøùúûçüÿÿþþñðùúÿûöñõõùÿÿûöýüù÷Íæÿýÿÿäøô÷þüö÷úâØùÿþýÿþÿÿëÏïý÷üûúúùùôúùüùÿÿÞœ´óôÿÿðøôÿðöü÷þÿýýÑæÿýÿÿçõòþûõýÿãÐøÿÿýÿüÿÿéÎñýôûùúú’ùøøöéÿÿ¿IfÿüôçÛÜíÿøüðèô÷ùÿÿÑåÿüÿÿþõÿô÷úóÿÿáÍûÿÿüÿüÿÿêÏðüõù÷øùúùø÷öìÿü¢>#,sðÜÓáîëÛÎÉñÿùìíùùüÏäÿüÿÿþ¡øûðúòûùâÎÿÿþüþþúÿîÐëûööõÿ’˜87oweÚÒÍŶ¬·ÇÃÃäÿýæôøöÍäÿýÿþý;ßýíüôùöäÓÿþÿûýÿýÿðÑéú÷õöõôóòóôóÿÔ/ gw–ÍÞÒÏáïéÔÅéÒ¼ÚÿûíæóÉãÿýÿþý ôÿôóô÷áÓÿûÿýÿþþõìÍæõóñöñðúÿÿÏüÿOlwëÿÑÇÿÿ÷ìüùà¶ÑØåýúçûÑàÿÿýþÿ \ìú÷ïôöáÓÿüÿýÿþþÃíÎèùöóöÿþåñìôù˜2V}x½Ø˜àÖÓÿðëàòôÿÒÓÃñôóùÑàÿÿýþÿ áõüíöøßÓÿýÿýÿÿÂþíÎéû÷ôìûÛfi]\c2y{¨ç¢EªÛÎÝùìçéÞÿú¶ÖÂÿïõÏàÿÿýÿÿTÌöúðôùÞÓÿýÿýÿÿÃëÍçøôðïÿÏ.735@lwyÕÞyF{ãʺêîÿöäýÿз¼ÿÿòÎàÿÿýÿÿŠ¥õîïìòÜÒÿþÿýÿÿÃëÌãóíêìÿÐMe^^JbY‹à«RŠú¸ÄÎíóýìíõøšÒÚÿíÌàÿÿþÿÿ™ïàéâçÛÑÿþÿüÿÿÖíÊßíçåæïÄP`Z`GhS’êŸR £ÿÎÊÅÔâôÜÄïýÂã¸çéÊàþþÿñ” zïÜããçÚÐÿþÿûÿÿÖîÊÝéåãèðÅ"$91u늜ÿäÉÇÅÚðåÒßüÁñºåæÉßþþÿÄ•ˆóßàëìØÏÿýþûÿÿþÿïÊÜæääÚóÎpðˆ„ñØïÖÝÃãî×Êà¥åÖöåÈßþþÂÿþk œååäåìÛÐÿýÿýÿýÿþíÌßéåçÕúÇgѬ&xýèöõº©ÏÝçîøÚÆÕðèÊàþþÿÄL ²òæåâãÛÐÿýÿýÿýÿþíÍßèåæêô¾"  #LÊàVÿíÜåâÜØ˜Òþ¶ß¼ìïèÊàþþÿÄ!ÍöÞååçÛÐÿýÿýÿýÿÿîÍàéæçßëå²·¶¶ÆC DØ¢R˜ÿêËÏëæ¹ÅºÊåÅÔîåéËàþþÿÄVåîÞæëìÛÐÿýÿýÿýÿÿîÍàêçèáäêêìíåø« 7M§â´°èâèÛ×ÝÒßöà¿Ëìñ×ëËáþþÿ€KöéçèëéÛÐÿýÿýÿýÿÿîÎáêèéîçãçáëèóÿxG_®ãÛÓÐúþíõÿÑïÛ®øåâäêÌáÿþþÿþIÚöáéèêéÛÐÿýÿýÿýÿÿîÎâëèêæèçéáèàÚúÕ?"2a¡ÅÐÏÍÊÍÉÿ¯½ÿþäÙìëÍâÿþþÿþ±ôêàçêëíÛÐÿýÿýÿýÿÿïÎâíéëæéêêèíìäßÿÉ7$C´àåÁµÀ¿¿°ÛöõååïæìÍâÿÿþÿþõñáêëñêìÛÐÿýÿýÿýÿÿïÏâíêëëéçäæäêèéäÿÂ@]ÿîÍÄÜÛÉÝÿÿôÝÕÜòôìÍâÿÿþÿþùÝííçóìîãÌþÿÿúÿüûÿìÓÜîïåêëéçéïïêïßïüÕpC‰ñôøóêêóúêììêççéêñÍàÿÿýÿÿëæòìêòïóßÒÿÿÑúÿþûÿêÏßïíóííìëìíëèôìèæÿûÕÖêçåäåèèéæéëëêêìïñÉÜÿÿÃþìïëéðóñö×ÛÿþÿûÿÿýÿëÎâöê÷îííïïíêêçîñäðÿ÷þïêæéîïëåëíïîííðòöËÝÿÿïüôôèíñëóùÏâÿýÿüþÿÿéòÎßþðïíêëïðííïôìóóìäåùòòƒðïôôóñððóööÐäÿþÿÿþíóðóíê÷ñÍçÿüÿþýþüÿþÕÐøúðïììïïíîòõìðòñôïìñóôóðïñòõóððñõøûäÑëÿýýÿþéòðñòø÷ÛÕïÿýÿþþýùþÿàÊçù÷óññðïíïòçíôïçëðêòðïïð´òïíñöûúøÓÔóÿþþýýñôîñùõæÕçùÿþýþÿþüüÿóÚ×çõóööóòòóóõòòõóñõööóñòõöõóòïïóøõêàÙåüÿÿôýþöúøú÷ÛÎãõÿÿýûýÿÿêúùÿðÐÓéò÷û÷öøù÷û÷ô÷öóõõöþ÷øøï÷ù÷öûûïØÅìúÿýýÿþÿ@ÿþ'ÿþÿþÿþÿþýÿþÿøúÿÿþþÿÿþþóüýÿÿýÿýýûùÿÿþþûýûúüþþüÿþþÿÿýýûÿÿýüïýúøúþüþÿÿþþýúþüþÿÿ÷þùÿÿþüüýÿÿþüÿÿþÿþÿ÷üþÿÿþùûýÿÿûýúûüÿÿ÷úüýÿÿþû÷ýýÿýÿüþýþþÿÞèæãåðüÿûüýûýÿÿüÿüÿÿúýÿÿùòîçãäæéêèç çþèååõçêòüÿýÿÿýýÿÿøºÁÉÏÑÜóÿÿéúùÿÿýÿþüúþÿþëÙÌÈÂÀÁÃÆÇÄ ÄñÅÄÄÈÌÊÌßöýÿÿýüÿÿåþýýìÕÒÝüÿüøÿÿüýÿøþÿôÜÖØùûþÿÿþüÿÿõùèÝÛñüÿþüþÿÿùéþÿïÛÍéþÿúþþûýÿúÿüØÊáôüûûþýþþòýúùÿÿýéÕßðýÿþÿÿæùÿþøýÿó×Ö÷ÿüýþüÿþûÿíÍÙýÿýÿÿûüúùùüüôúÿÿûùýûòÐçûÿÿôöþúÿûñýùÅèÿþþÑùÿýÿüÖß÷ÿùüýýþýýûûôùýüóúñûûüþüùø÷öÿùÿÿ÷ýûùìÇåÿþþäÿøÿùúûúÿþÎçÿÿþýúÿþÿøÕâùÿúüüûûõþúóÿüü÷ÿýýÿÿáûõýöðóþôíÿðÊæÿþþÿÿ÷üùùûûüûÜáüÿýýÿüòÒéûûòüûúùøùúûîýúöøÿÿêöøùùõøÿÿó÷ýõïúúø÷Íæÿýÿÿäøô÷þüö÷úâØùÿþýÿþÿÿëÏïý÷üûúúùùñúÿýòõÿç±Öýøûýþÿÿóôùÿ÷üý÷ýÑæÿýÿÿçõòþûõýÿãÐøÿÿýÿüÿÿéÎñýôûùúú’ùøøÿîÿÿ¸Jwÿûä̽ÃÝ÷ýÿúòýú÷ýÿÑåÿüÿÿþõÿô÷úóÿÿáÍûÿÿüÿüÿÿêÏðüõù÷øùúùø÷öíÿÿ¥>`·™ƒ„Œ‚y°ßûúñóúøüÏäÿüÿÿþ¡øûðúòûùâÎÿÿþüþþúÿîÐëûööõûÿ¥F<\I%wm_Q@:J^m{³ñöêüÿöÍäÿýÿþý;ßýíüôùöäÓÿþÿûýÿýÿðÑéú÷õöõôóòóôóþÓ@8o]Uq¢’ŽŸ°¯¡–]^h«íüúùóÉãÿýÿþý ôÿôóô÷áÓÿûÿýÿþþõìÍæõóñöñðúÿÿÏüÿR#j\SœÇaƒåþýÿÿ߸g`q­óÿîûÑàÿÿýþÿ \ìú÷ïôöáÓÿüÿýÿþþÃíÎèùöóöÿþåñìôù7YgCk~LZpœúþûìÿøÔpcrÏöÿùÑàÿÿýþÿ áõüíöøßÓÿýÿýÿÿÂþíÎéû÷ôìûÛfi]\c(8qOM~MHhpÄÿúñýý÷»V~‡÷îöÏàÿÿýÿÿTÌöúðôùÞÓÿýÿýÿÿÃëÍçøôðïÿÏ.734Xni@csA)l–UjÚùÿãôÿí™mvÜëóÎàÿÿýÿÿŠ¥õîïìòÜÒÿþÿýÿÿÃëÌãóíêìÿÐMe^]g^JSfKC"›ÙUK€ÝòåðóîÌK«üíÌàÿÿþÿÿ™ïàéâçÛÑÿþÿüÿÿÖíÊßíçåæïÄP`Z`_WC^jD[7“ûšYHŒÑõè×îÃQvŽÿèÊàþþÿñ” zïÜããçÚÐÿþÿûÿÿÖîÊÝéåãèðÅ"#D_!ŠÿߊLGØîèêÆDr‡ÿåÉßþþÿÄ•ˆóßàëìØÏÿýþûÿÿþÿïÊÜæääÚóÎ BNls£ÕïðìîâìÍâÿÿþÿþõñáêëñêìÛÐÿýÿýÿýÿÿïÏâíêëëéçäæäêèôÞþ·I kß‚wx¥ÛåìñîáèêìÍâÿÿþÿþùÝííçóìîãÌþÿÿúÿüûÿìÓÜîïåêëéçéïïêîßïüÕpB‰ýÿÿøÿóçòðííïññÍàÿÿýÿÿëæòìêòïóßÒÿÿÑúÿþûÿêÏßïíóííìëìíëèôìèæÿûÕÖòðîíîñòòêíïïîîðóñÉÜÿÿÃþìïëéðóñö×ÛÿþÿûÿÿýÿëÎâöê÷îííïïíêêçîñäðÿ÷þðêçêïðìçëíïîííðòöËÝÿÿïüôôèíñëóùÏâÿýÿüþÿÿéòÎßþðïíêëïðííïôìóóìäåùððƒîíððïíììïòöÐäÿþÿÿþíóðóíê÷ñÍçÿüÿþýþüÿþÕÐøúðïììïïíîòõìðòñôïíìîïîìëíîñïììíñô÷äÑëÿýýÿþéòðñòø÷ÛÕïÿýÿþþýùþÿàÊçù÷óññðïíïòçíôïçëðêðîííï´îêêíòööôÔÔóÿþþýýñôîñùõæÕçùÿþýþÿþüüÿóÚ×çõóööóòòóóõòòõóñõö÷óñòõöõóòïïóøõêàÙåüÿÿôýþöúøú÷ÛÎãõÿÿýûýÿÿäúùÿðÐÓéò÷û÷öøù÷û÷ô÷öóõõö÷øùúúïùûùøýýñÚÇìúÿýýÿþÿ@ÿþ'ÿþÿþÿþÿþýÿþÿøúÿÿþþÿÿþþóüýÿÿýÿýýûùÿÿþþûýûúüþþüÿþþÿÿýýûÿÿýüïýúøúþüþÿÿþþýúþüþÿÿ÷þùÿÿþüüýÿÿþüÿÿþÿþÿ÷üþÿÿþùûýÿÿûýúûüÿÿ÷úüýÿÿþû÷ýýÿýÿüþýþþÿÞèæãåðüÿûüýûýÿÿüÿüÿÿúýÿÿùòîçãäæéêèç çþèååõçêòüÿýÿÿýýÿÿøºÁÉÏÑÜóÿÿéúùÿÿýÿþüúþÿþëÙÌÈÂÀÁÃÆÇÄ ÄñÅÄÄÈÌÊÌßöýÿÿýüÿÿåþýýìÕÒÝüÿüøÿÿüýÿøþÿôÜÖØùûþÿÿþüÿÿõùèÝÛñüÿþüþÿÿùéþÿïÛÍéþÿúþþûýÿúÿüØÊáôüûûþýþþòýúùÿÿýéÕßðýÿþÿÿæùÿþøýÿó×Ö÷ÿüýþüÿþûÿíÍÙýÿýÿÿûüúùùüüôúÿÿûùýûòÐçûÿÿôöþúÿûñýùÅèÿþþíùÿýÿüÖß÷ÿùüýýþýýûûÿÿæúîöïûþþûøô÷úú÷òýÿøúôíìÇåÿþþäÿøÿùúûúÿþÎçÿÿþýúÿþÿøÕâùÿúüüûûÿööÿúúóýúùöúúáôìüøôúÿõèûðÊæÿþþÿÿ÷üùùûûüûÜáüÿýýÿüòÒéûûóüûúùøùúûîÿþûÿÿêüûýüõöúþ÷þÿÿúÿûô÷Íæÿýÿÿäøô÷þüö÷úâØùÿþýÿþÿÿëÏïý÷üûúúùùôúþý÷ÿÿê°ÏÿþÿÿþøÿÿùùýÑæÿýÿÿçõòþûõýÿãÐøÿÿýÿüÿÿéÎñýôûùúú’ùøø÷êÿÿÃN múïÛÆ¹ºÑéôüøôÿÿüÿÿÑåÿüÿÿþõÿô÷úóÿÿáÍûÿÿüÿüÿÿêÏðüõù÷øùúùø÷öçÿÿ«CWšmq{zn`œÎñôðöÿþüÏäÿüÿÿþ¡øûðúòûùâÎÿÿþüþþúÿîÐëûööõøÿ¥G:XCaVK?-'3FYi¥èðéÿÿöÍäÿýÿþý;ßýíüôùöäÓÿþÿûýÿýÿðÑéú÷õöõôóòóôôþÓ?4kWMi|xˆ–“tLNZ¡èúûùóÉãÿýÿþý ôÿôóô÷áÓÿûÿýÿþþõìÍæõóñöñðúÿÿóüùX5rH/v¦CaÏÿÿßÖµaQWŽÛÿùûÑàÿÿýþÿ \ìú÷ïôöáÓÿüÿýÿþþÃíÎèùöóöÿþåñìôù…:fn3Of=<^–óôñêÿëÊbOXºîÿùÑàÿÿýþÿ áõüíöøßÓÿýÿýÿÿÂþíÎéû÷ôìûÛfi]\c9vN?kC6]a¨îðøÿíë±EboíñõÏàÿÿýÿÿTÌöúðôùÞÓÿýÿýÿÿÃëÍçøôðïÿÏ.734Kmf5R`85h,=ÆÿÿïïúäGTÏòòÎàÿÿýÿÿŠ¥õîïìòÜÒÿþÿýÿÿòëÌãóíêìÿÐMe^]]ÓB>O14+Â(%qÜøïïöì·#U˜ÿíÌàÿÿþÿÿ™ïàéâçÛÑÿþÿüÿÿÖíÊßíçåæïÄP`Z`Y]9CR(F;“óH-kÂüßÙô¸0NxÿèÊàþþÿñ” zïÜããçÚÐÿþÿûÿÿÖîÊÝéåãèðÅ"# )(K ÿÞz(wÕâìò¿%JtÿåÉßþþÿÄ•ˆóßàëìØÏÿýþûÿÿþÿïÊÜæääÚóÎ#IœÿܹL"(ƒÛïï¸:ƒÿäÈßþþÀÿþk œååäåìÛÐÿýÿýÿýÿþíÌßéåçÕúÇ.ŒÿééÊ[ƒÙô¦0,ÿåÈÞþþÿÿÂL ²òæåâãÛÐÿýÿýÿýÿþíÍßèåæêô¾"  =Q¡ÿíùü¹f5+œÐJBBÃÿåÈÞþþÿÿÂ!ÍöÞååçÛÐÿýÿýÿýÿÿîÍàéæçßëå²·¶¶ÆE P(”ûéäïê¬R=FMT?ŒßìçÉÝþþÿÿÂVåîÞæëìÛÐÿýÿýÿýÿÿîÍàêçèáäêêìíåù"(/QpÔììßàË‘FT-jÕøÖèÉÞþþÿÿÂöéçèëéÛÐÿýÿýÿýÿÿîÎáêèéîçãçáëèóî| #)ESƒªÕÙмAG'"¾ïòÞèÊÞÿþÿÿÂIÚöáéèêéÛÐÿýÿýÿýÿÿîÎâëèêæèçéáèàÛñÙM 3(-0DPL7"L.?±í÷åâéËàÿþÿÿıôêàçêëíÛÐÿýÿýÿýÿÿïÎâíéëæéêêèíìäåÿÌ?  JM92_’ÆêòõóÝêËàÿÿÄõñáêëñêìÛÐÿýÿýÿýÿÿïÏâíêëëéçäæäêèöæÿÁOcÞ»ŒloggÄáûÿ÷åëíêËàÿÿ×ùÝííçóìîãÌþÿÿúÿüûÿìÓÜîïåêëéçéïïêîÞïüÕpC‰ÿÿáù÷ÿÿññðîëëíïñÍàÿÿýÿÿëæòìêòïóßÒÿÿÑúÿþûÿêÏßïíóííìëìíëèôìèæÿûÕÖõóñïððññéìîîííïòñÉÜÿÿÃþìïëéðóñö×ÛÿþÿûÿÿýÿëÎâöê÷îííïïíêêçîñäðÿ÷þõðëîñòîæëíïîííðòöËÝÿÿïüôôèíñëóùÏâÿýÿüþÿÿéòÎßþðïíêëïðííïôìóóìäåùõõó€ñïîññðîííðóöÐäÿþÿÿþíóðóíê÷ñÍçÿüÿþýþüÿþÕÐøúðïììïïíîòõìðòñôïìòôóòíìîíòðííîòõøäÑëÿýýÿþéòðñòø÷ÛÕïÿýÿþþýùþÿàÊçù÷óññðïíïòçíôïçëðêóñðîîíí´ïëëîóø÷õÔÔóÿþþýýñôîñùõæÕçùÿþýþÿþüüÿóÚ×çõóööóòòóóõòòõóñõöùõóòöôóñòïïóøõêàÙåüÿÿôýþöúøú÷ÛÎãõÿÿýûýÿÿäúùÿðÐÓéò÷û÷öøù÷û÷ô÷öóõõøù÷ø÷÷ïôúø÷üüðÙÆìúÿýýÿþÿÿ ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3ÿþÿôþú÷ÝÔÔâò÷øûüüñûüþþùñê寨îüÿþÿÿþþýýÿþÿôþüúðâÖÐÉÀ¼¾»»ñº¹»¾ÅÍÐæïúþþüþÿÿûþýýüÿÿðýüýþÿÿþÿÿöðéáâêééðîëéèèêìíúýÿÿþýþÿÿûþýýüÿÿðþýýþÿÿþññòõôóöüøøóõ÷úüýüûúõøûþÿÿûþýýüÿÿñþÿÿþüúõóôøùøööúúðù÷õôóòôðòõúþÿÿþÿÿûþýýüÿ ÿôýùöúöô÷úûúù÷÷øñ÷öö÷ùù÷öö÷úýþþÿÿûþýýüÿÿñþÿþüùööõôôö÷÷öû ûðúõö÷øùøöõúø÷øúýÿÿûþýýüÿÿþþýý÷üù÷õ÷úùø÷÷öùøúôõ÷úýÿÿûþýýüÿÿ÷ýþÿÿýû÷õùùø÷öýøûÿÿþÿýüúÿÿ÷ýþÿÿýûøöùùø÷øú÷ö÷øûÿÿþÿýüúÿÿþÿûýûø÷ùùøùø÷ýùüÿÿþÿýüúÿÿþÿûýûùøúúùøúþùøøýúüÿÿþÿýüúÿÿþûýüúùúúùúù÷úûýþÿÿþþÿÿýüúÿÿþûýüûúûûúûú÷ûüýþÿÿþþÿÿýüúÿÿþýýüûûúû úûøüýþÿÿþþÿÿýüúÿÿþúýüüûüûûúûúû÷üýþþÿÿþþÿÿýüúÿ ÿúþýüûúû ûüüýþÿÿýþýÿ ÿûþüûúû ûüüýþÿÿýþýÿ ÿûþýüûü!üýýþÿÿýþýÿ ÿýþýü"üüýþþÿÿýþýÿ ÿüþýüý!ýþÿýþýÿÿþþÿÿþ ýþ ÿýþýÿÿþþÿÿ$þ ÿýþýÿÿþþÿÿ!þ ÿýþýÿ'ÿþ<ÿþ4ÿ þ4ÿ þ4ÿ þ,ÿþ,ÿþýþ,ÿþýþ"ÿðþýûþÿÿýýÿÿúÿÿýþÿÿúýûÿúýÿÿþüÿÿþÿõþýÿýüþÿþûøÿÿôôæÚÕÐÍÌÑÜíþÿÿýùúÿÿþÿøþýþÿÿúúÿÿíýæÍÁ¹®¥¡°«¨©°¹ÂÆæúÿÿüüöýþþÿÝþýúýüûþÿûí¶°ºÌÞêðöòìæÞÐÁ·²Çàúÿÿûÿþþÿíþýüõøÿÿëɱ´Êâîòôùùÿÿôûòëδ­Åëÿÿòýýþÿ×þýÿüÿþÜ´°ÅÞñÿÿþûûùüûúûþþýüÿäųºÜúúüüýýþþÿÿïþýÿÿ÷Û¸°Óûÿÿúö÷ûþþþýþþïýü÷ÿÿ㸮×ÿýüüýþþÿÿéþýÿöÕ´¼äýüøôõûýûúýþýüûúúðû÷öüÿï½­ÄýýüýþþÿÿÓþÿÿýÿÿüýÿÚ°¼íÿýûÿöÿÿôúòôùüüùùüúöÿù÷úûóѦÌþÿûÿÿûýÿÿúÿÿüþÿÿþþÎÿþâ·Ãçôûúýîÿþþ÷öýùüúýÿÿûùüööùúûýëϹ×úÿüþÿþÿþÿýÿÿùÿÿÇýÿýÿûýÿñ½ªáÿüøóÿøþëøÿ÷ýøÿùðñúÿÿùõúþúøüúî¹²èÿüýýþÿüüýÿÿùýÿÿçüÿûþüÿüÔ®Íøÿûøðûý£–ºöÿÿö÷÷ãùúù÷÷òöúù÷úÿÿÛ°ÌýÿüþÿÿüûþÿýûÿÿÈüÿúûÿÿê´¿ôýõ÷ö÷óò-sÎòÿÿôð÷ùôõý÷ö÷úùõ÷þþƲåÿýþÿÿýýÿýúþÿÿÇüÿûúÿûÒ«Þý÷÷öòÿòéK?:|Ùüÿÿöñöú÷ýú÷úûóðøÿá¯ËÿÿüýýÿþÿüúÿþÿÿÛüÿþúÿ黿óùõû÷ðûø÷[nQ2)•Ìþÿ÷õôîò÷õôøøîýö÷ǶéÿúýýÿýÿýüýîÿÿÈüþÿûÿÚ¯Öøø÷öøôòÿÞ]ehjfD:Œáÿÿóòñýùîïõõöëÿá¬Õÿùÿýÿüÿþþúáÿþÿôþú÷ÝÔÔâò÷øûüüñûüþþùñê寨îüÿþÿÿþþýýÿþÿôþüúðâÖÐÉÀ¼¾»»ñº¹»¾ÅÍÐæïúþþüþÿÿûþýýüÿÿðýüýþÿÿþÿÿöðéáâêééðîëéèèêìíúýÿÿþýþÿÿûþýýüÿÿðþýýþÿÿþññòõôóöüøøóõ÷úüýüûúõøûþÿÿûþýýüÿÿñþÿÿþüúõóôøùøööúúðù÷õôóòôðòõúþÿÿþÿÿûþýýüÿ ÿôýùöúöô÷úûúù÷÷øñ÷öö÷ùù÷öö÷úýþþÿÿûþýýüÿÿñþÿþüùööõôôö÷÷öû ûðúõö÷øùøöõúø÷øúýÿÿûþýýüÿÿþþýý÷üù÷õ÷úùø÷÷öùøúôõ÷úýÿÿûþýýüÿÿ÷ýþÿÿýû÷õùùø÷öýøûÿÿþÿýüúÿÿ÷ýþÿÿýûøöùùø÷øú÷ö÷øûÿÿþÿýüúÿÿþÿûýûø÷ùùøùø÷ýùüÿÿþÿýüúÿÿþÿûýûùøúúùøúþùøøýúüÿÿþÿýüúÿÿþûýüúùúúùúù÷úûýþÿÿþþÿÿýüúÿÿþûýüûúûûúûú÷ûüýþÿÿþþÿÿýüúÿÿþýýüûûúû úûøüýþÿÿþþÿÿýüúÿÿþúýüüûüûûúûúû÷üýþþÿÿþþÿÿýüúÿ ÿúþýüûúû ûüüýþÿÿýþýÿ ÿûþüûúû ûüüýþÿÿýþýÿ ÿûþýüûü!üýýþÿÿýþýÿ ÿýþýü"üüýþþÿÿýþýÿ ÿüþýüý!ýþÿýþýÿÿþþÿÿþ ýþ ÿýþýÿÿþþÿÿ$þ ÿýþýÿÿþþÿÿ!þ ÿýþýÿ'ÿþ<ÿþ4ÿ þ4ÿ þ4ÿ þ,ÿþ,ÿþýþ,ÿþýþ"ÿðþýûþÿÿýýÿÿúÿÿýþÿÿúýûÿúýÿÿþüÿÿþÿõþýÿýüþÿþûøÿÿôôæÚÕÐÍÌÑÜíþÿÿýùúÿÿþÿøþýþÿÿúúÿÿíýæÍÁ¹®¥¡°«¨©°¹ÂÆæúÿÿüüöýþþÿÝþýúýüûþÿûí¶°ºÌÞêðöòìæÞÐÁ·²Çàúÿÿûÿþþÿíþýüõøÿÿëɱ´Êâîòôùùÿÿôûòëδ­Åëÿÿòýýþÿ×þýÿüÿþÜ´°ÅÞñÿÿþûûùüûúûþþýüÿäųºÜúúüüýýþþÿÿïþýÿÿ÷Û¸°Óûÿÿúö÷ûþþþýþþïýü÷ÿÿ㸮×ÿýüüýþþÿÿéþýÿöÕ´¼äýüøôõûýûúýþýüûúúðû÷öüÿï½­ÄýýüýþþÿÿÓþÿÿýÿÿüýÿÚ°¼íÿýûÿöÿÿôúòôùüüùùüúöÿù÷úûóѦÌþÿûÿÿûýÿÿúÿÿüþÿÿþþÎÿþâ·Ãçôûúýîÿþþ÷öýùüúýÿÿûùüööùúûýëϹ×úÿüþÿþÿþÿýÿÿùÿÿÇýÿýÿûýÿñ½ªáÿüøóÿøþëøÿ÷ýøÿùðñúÿÿùõúþúøüúî¹²èÿüýýþÿüüýÿÿùýÿÿçüÿûþüÿüÔ®Íøÿûøðûý£–ºöÿÿö÷÷ãùúù÷÷òöúù÷úÿÿÛ°ÌýÿüþÿÿüûþÿýûÿÿÈüÿúûÿÿê´¿ôýõ÷ö÷óò-sÎòÿÿôð÷ùôõý÷ö÷úùõ÷þþƲåÿýþÿÿýýÿýúþÿÿÇüÿûúÿûÒ«Þý÷÷öòÿòéK?:|Ùüÿÿöñöú÷ýú÷úûóðøÿá¯ËÿÿüýýÿþÿüúÿþÿÿÛüÿþúÿ黿óùõû÷ðûø÷[nQ2)•Ìþÿ÷õôîò÷õôøøîýö÷ǶéÿúýýÿýÿýüýîÿÿÈüþÿûÿÚ¯Öøø÷öøôòÿÞ]ehjfD:Œáÿÿóòñýùîïõõöëÿá¬Õÿùÿýÿüÿþþúáÿþÿôþú÷ÝÔÔâò÷øûüüñûüþþùñê寨îüÿþÿÿþþýýÿþÿôþüúðâÖÐÉÀ¼¾»»ñº¹»¾ÅÍÐæïúþþüþÿÿûþýýüÿÿðýüýþÿÿþÿÿöðéáâêééðîëéèèêìíúýÿÿþýþÿÿûþýýüÿÿðþýýþÿÿþññòõôóöüøøóõ÷úüýüûúõøûþÿÿûþýýüÿÿñþÿÿþüúõóôøùøööúúðù÷õôóòôðòõúþÿÿþÿÿûþýýüÿ ÿôýùöúöô÷úûúù÷÷øñ÷öö÷ùù÷öö÷úýþþÿÿûþýýüÿÿñþÿþüùööõôôö÷÷öû ûðúõö÷øùøöõúø÷øúýÿÿûþýýüÿÿþþýý÷üù÷õ÷úùø÷÷öùøúôõ÷úýÿÿûþýýüÿÿ÷ýþÿÿýû÷õùùø÷öýøûÿÿþÿýüúÿÿ÷ýþÿÿýûøöùùø÷øú÷ö÷øûÿÿþÿýüúÿÿþÿûýûø÷ùùøùø÷ýùüÿÿþÿýüúÿÿþÿûýûùøúúùøúþùøøýúüÿÿþÿýüúÿÿþûýüúùúúùúù÷úûýþÿÿþþÿÿýüúÿÿþûýüûúûûúûú÷ûüýþÿÿþþÿÿýüúÿÿþýýüûûúû úûøüýþÿÿþþÿÿýüúÿÿþúýüüûüûûúûúû÷üýþþÿÿþþÿÿýüúÿ ÿúþýüûúû ûüüýþÿÿýþýÿ ÿûþüûúû ûüüýþÿÿýþýÿ ÿûþýüûü!üýýþÿÿýþýÿ ÿýþýü"üüýþþÿÿýþýÿ ÿüþýüý!ýþÿýþýÿÿþþÿÿþ ýþ ÿýþýÿÿþþÿÿ$þ ÿýþýÿÿþþÿÿ!þ ÿýþýÿ'ÿþ<ÿþ4ÿ þ4ÿ þ4ÿ þ,ÿþ,ÿþýþ,ÿþýþ"ÿðþýûþÿÿýýÿÿúÿÿýþÿÿúýûÿúýÿÿþüÿÿþÿõþýÿýüþÿþûøÿÿôôæÚÕÐÍÌÑÜíþÿÿýùúÿÿþÿøþýþÿÿúúÿÿíýæÍÁ¹®¥¡°«¨©°¹ÂÆæúÿÿüüöýþþÿÝþýúýüûþÿûí¶°ºÌÞêðöòìæÞÐÁ·²Çàúÿÿûÿþþÿíþýüõøÿÿëɱ´Êâîòôùùÿÿôûòëδ­Åëÿÿòýýþÿ×þýÿüÿþÜ´°ÅÞñÿÿþûûùüûúûþþýüÿäųºÜúúüüýýþþÿÿïþýÿÿ÷Û¸°Óûÿÿúö÷ûþþþýþþïýü÷ÿÿ㸮×ÿýüüýþþÿÿéþýÿöÕ´¼äýüøôõûýûúýþýüûúúðû÷öüÿï½­ÄýýüýþþÿÿÓþÿÿýÿÿüýÿÚ°¼íÿýûÿöÿÿôúòôùüüùùüúöÿù÷úûóѦÌþÿûÿÿûýÿÿúÿÿüþÿÿþþÎÿþâ·Ãçôûúýîÿþþ÷öýùüúýÿÿûùüööùúûýëϹ×úÿüþÿþÿþÿýÿÿùÿÿÇýÿýÿûýÿñ½ªáÿüøóÿøþëøÿ÷ýøÿùðñúÿÿùõúþúøüúî¹²èÿüýýþÿüüýÿÿùýÿÿçüÿûþüÿüÔ®Íøÿûøðûý£–ºöÿÿö÷÷ãùúù÷÷òöúù÷úÿÿÛ°ÌýÿüþÿÿüûþÿýûÿÿÈüÿúûÿÿê´¿ôýõ÷ö÷óò-sÎòÿÿôð÷ùôõý÷ö÷úùõ÷þþƲåÿýþÿÿýýÿýúþÿÿÇüÿûúÿûÒ«Þý÷÷öòÿòéK?:|Ùüÿÿöñöú÷ýú÷úûóðøÿá¯ËÿÿüýýÿþÿüúÿþÿÿÛüÿþúÿ黿óùõû÷ðûø÷[nQ2)•Ìþÿ÷õôîò÷õôøøîýö÷ǶéÿúýýÿýÿýüýîÿÿÈüþÿûÿÚ¯Öøø÷öøôòÿÞ]ehjfD:Œáÿÿóòñýùîïõõöëÿá¬ÕÿùÿýÿüÿþþúáÿöùáÏÖëùýûûúúþûüüýôû÷ôóÐÌÖìýÿþÿÿüõýÿíßÑÓãóùøüü÷ÿúìÜʾº»¼¼»þ¼»»ø½¿ÂÄÚäóÿÿóýüýþÿøéØËÿ¾»»÷ýÿýöîëêëêêéýêéèèõêìíõþÿÿûûþÿÿóýüýýÿÿýöíééìéé÷ùøóñôûûöøøù÷øõóòïóøüÿÿþýÿÿòþýýü÷öö÷öõóòùøøùôùùôòöùùúôûüüýüùøðíïøÿÿþýÿÿôþýûöôô÷üýúöúú÷ò÷ùøöö÷÷öö÷üø÷öõõó÷øÿû÷øùùüÿÿþÿÿùüûôõõö÷ ÷÷øööúýüù÷ùùûûúüúøöö÷ýòøûûþýÿÿþÿõüúõö÷÷öõö÷ûû÷ùö÷øõòóù÷÷öìõ÷øùùú÷÷õúøïñûÿüÿþþÿÿýüúööú÷ùúùùööø÷øøùùøø÷÷øø÷ööøüÿþÿÿüþüûøø÷øù ø÷ øø÷ööøüÿþÿÿüþüûøø÷øùø÷ûùýÿþÿÿüþüûùùøùúùøùøûúýÿþÿÿüþüûùùøþùúúùûúýÿþÿÿüþüûúúùúûúùúûûþÿþÿÿüþüûúúû úûúöùúûúúüþÿþÿÿýþüûûøúûûüüûûúúûúýùúûûûüþÿþÿÿýþüû0ûúúûýÿÿýþþüýüüû0ûúúûýÿÿýþþýþüûû üûûüýÿÿþþý5üôþÿÿþþÿÿþþýýüü$ýúþÿÿþþÿÿþþý2ýþÿþþÿÿþý"þÿþþÿÿþþýþ0þÿþþÿÿýþýþþ7ÿþ7ÿþ}ÿþÿþ.ÿþÿþÿþ-ÿþÿþÿ þ#ÿþÿþýýþÿÿýþýþþ!ÿþþýÿÿþýùþÿÿþýýþ þÿþýÿþýþýþýþÿþýÿþýþýûüýýþÿÿþýÿþùýüüýþþýýüüýþþÿÿþýÿõþÿÿþüÿúûÿýÿÿþþÿÿùüùüÿÿûÿÿýÿþþÿ ÿóýüÿÿûøúÿÿþÿýÿÿúüýÿþýþþóÿôÞÖÒÎÌÍÔàêþÿÿúýÿÿúþÿÿþýÿ ÿýþýÿÿáñßÿúúÿÿùùÿüÿÿîÑÀ·±««ª§¨¬°±»ÍçûÿÿúÎýüþþöÿÿüîØÃ·µþýüúúûþÿÿåµ´ºËÛèîòñïëâØ¶²³Ääþÿúÿüûüþþ ÿßúûÿûûÿýÿîÖ¾°¯ÁÓùÿÿúúÿýòÀ²±Ìêö÷ùüÿÿíûõöäʶ´Èêÿûùøüÿÿýúÿ ÿòûÿÿùÒÀ´ÀÚñüÿúýýíÿýݹ­ÈäòùúûÿýþýûûýÿÿúìŪ¼ÞÿÿþÿþþÿÿóûÿüùÿÿçÅ®¼ÖñÿÿÙþýøùþõÚ¾°áõþüýýúùüüþÿýúûýõ÷ÿÿûß¿«âôÿÿüÿ ÿÝýûõùúῲÖíÿÿûôøþýûÿþׯ¾éÿþöôüüúýüüÿÿùîýÿÿ÷òþÿèÂ¤Ïøÿþÿÿüÿÿ³üúÿê´¯Üüÿÿüüÿÿýþÿÿá«¿ìýøóøýûûùõùýøùûøøôýúúþúùþñƱÍûÿþÿûþÿÿýþÿÿûÿûÿ赺éÿøûöýóùùñýüÝ¿ëÿÿøóûûúýÿÿüøôýÿÿ€Õþøøûÿøú÷±Úÿÿõýþÿÿüüþýúøÿ￸Þý÷òþûøðúúûÿí½²×þúöòýÿòíóñìîÿûùÿíëðæò÷üî÷÷ûÿè¼³æÿ÷ýýÿÿüûüýûÿýÇ®Õ÷ÿøùýûüûÿùúÿÎ¶ÒøÿöùóÿázD@A;iÒÿÿ¼L?@F]Šõøöüñøÿà«ÀúÿþüÿÿüûýþþÿÞ«Ãöüøöúîñüþÿúýë±Ãöÿúöùýòš$!#)Äÿÿ¤ #Ïÿñýõ÷úñijáÿÿûÿÿþýÿÿÂõųáþûúðñòÿÿùù÷øÕ°Ûÿøòõìÿåx*[mdFGÔ÷ÿ« V`j\²ýñù÷ööþã´Âöÿúþÿþþÿÿ„ܶÉ÷ùôü÷ôÿõª‡Š‹¾Âõüöüþôþô{._ZZM9ÆÿÿªS`Wo²ÿûõòòøÿøÅ²äÿûýþýþÿüúùâÿøóôýüý®'$!*¬Îÿóòöôõ÷øt(gcdRBÀÿÿ¨&Wk`h¹öïëûøòîÿâ¯Òÿûýþýýîùõ­Éøùóüñõ÷÷(GhRWöùáÏÖëùýûûúúþûüüýôû÷ôóÐÌÖìýÿþÿÿüõýÿíßÑÓãóùøüü÷ÿúìÜʾº»¼¼»þ¼»»ø½¿ÂÄÚäóÿÿóýüýþÿøéØËÿ¾»»÷ýÿýöîëêëêêéýêéèèõêìíõþÿÿûûþÿÿóýüýýÿÿýöíééìéé÷ùøóñôûûöøøù÷øõóòïóøüÿÿþýÿÿòþýýü÷öö÷öõóòùøøùôùùôòöùùúôûüüýüùøðíïøÿÿþýÿÿôþýûöôô÷üýúöúú÷ò÷ùøöö÷÷öö÷üø÷öõõó÷øÿû÷øùùüÿÿþÿÿùüûôõõö÷ ÷÷øööúýüù÷ùùûûúüúøöö÷ýòøûûþýÿÿþÿõüúõö÷÷öõö÷ûû÷ùö÷øõòóù÷÷öìõ÷øùùú÷÷õúøïñûÿüÿþþÿÿýüúööú÷ùúùùööø÷øøùùøø÷÷øø÷ööøüÿþÿÿüþüûøø÷øù ø÷ øø÷ööøüÿþÿÿüþüûøø÷øùø÷ûùýÿþÿÿüþüûùùøùúùøùøûúýÿþÿÿüþüûùùøþùúúùûúýÿþÿÿüþüûúúùúûúùúûûþÿþÿÿüþüûúúû úûúöùúûúúüþÿþÿÿýþüûûøúûûüüûûúúûúýùúûûûüþÿþÿÿýþüû0ûúúûýÿÿýþþüýüüû0ûúúûýÿÿýþþýþüûû üûûüýÿÿþþý5üôþÿÿþþÿÿþþýýüü$ýúþÿÿþþÿÿþþý2ýþÿþþÿÿþý"þÿþþÿÿþþýþ0þÿþþÿÿýþýþþ7ÿþ7ÿþ}ÿþÿþ.ÿþÿþÿþ-ÿþÿþÿ þ#ÿþÿþýýþÿÿýþýþþ!ÿþþýÿÿþýùþÿÿþýýþ þÿþýÿþýþýþýþÿþýÿþýþýûüýýþÿÿþýÿþùýüüýþþýýüüýþþÿÿþýÿõþÿÿþüÿúûÿýÿÿþþÿÿùüùüÿÿûÿÿýÿþþÿ ÿóýüÿÿûøúÿÿþÿýÿÿúüýÿþýþþóÿôÞÖÒÎÌÍÔàêþÿÿúýÿÿúþÿÿþýÿ ÿýþýÿÿáñßÿúúÿÿùùÿüÿÿîÑÀ·±««ª§¨¬°±»ÍçûÿÿúÎýüþþöÿÿüîØÃ·µþýüúúûþÿÿåµ´ºËÛèîòñïëâØ¶²³Ääþÿúÿüûüþþ ÿßúûÿûûÿýÿîÖ¾°¯ÁÓùÿÿúúÿýòÀ²±Ìêö÷ùüÿÿíûõöäʶ´Èêÿûùøüÿÿýúÿ ÿòûÿÿùÒÀ´ÀÚñüÿúýýíÿýݹ­ÈäòùúûÿýþýûûýÿÿúìŪ¼ÞÿÿþÿþþÿÿóûÿüùÿÿçÅ®¼ÖñÿÿÙþýøùþõÚ¾°áõþüýýúùüüþÿýúûýõ÷ÿÿûß¿«âôÿÿüÿ ÿÝýûõùúῲÖíÿÿûôøþýûÿþׯ¾éÿþöôüüúýüüÿÿùîýÿÿ÷òþÿèÂ¤Ïøÿþÿÿüÿÿ³üúÿê´¯Üüÿÿüüÿÿýþÿÿá«¿ìýøóøýûûùõùýøùûøøôýúúþúùþñƱÍûÿþÿûþÿÿýþÿÿûÿûÿ赺éÿøûöýóùùñýüÝ¿ëÿÿøóûûúýÿÿüøôýÿÿ€Õþøøûÿøú÷±Úÿÿõýþÿÿüüþýúøÿ￸Þý÷òþûøðúúûÿí½²×þúöòýÿòíóñìîÿûùÿíëðæò÷üî÷÷ûÿè¼³æÿ÷ýýÿÿüûüýûÿýÇ®Õ÷ÿøùýûüûÿùúÿÎ¶ÒøÿöùóÿázD@A;iÒÿÿ¼L?@F]Šõøöüñøÿà«ÀúÿþüÿÿüûýþþÿÞ«Ãöüøöúîñüþÿúýë±Ãöÿúöùýòš$!#)Äÿÿ¤ #Ïÿñýõ÷úñijáÿÿûÿÿþýÿÿÂõųáþûúðñòÿÿùù÷øÕ°Ûÿøòõìÿåx*[mdFGÔ÷ÿ« V`j\²ýñù÷ööþã´Âöÿúþÿþþÿÿ„ܶÉ÷ùôü÷ôÿõª‡Š‹¾Âõüöüþôþô{._ZZM9ÆÿÿªS`Wo²ÿûõòòøÿøÅ²äÿûýþýþÿüúùâÿøóôýüý®'$!*¬Îÿóòöôõ÷øt(gcdRBÀÿÿ¨&Wk`h¹öïëûøòîÿâ¯Òÿûýþýýîùõ­Éøùóüñõ÷÷(GhRWöùáÏÖëùýûûúúþûüüýôû÷ôóÐÌÖìýÿþÿÿüõýÿíßÑÓãóùøüü÷ÿúìÜʾº»¼¼»þ¼»»ø½¿ÂÄÚäóÿÿóýüýþÿøéØËÿ¾»»÷ýÿýöîëêëêêéýêéèèõêìíõþÿÿûûþÿÿóýüýýÿÿýöíééìéé÷ùøóñôûûöøøù÷øõóòïóøüÿÿþýÿÿòþýýü÷öö÷öõóòùøøùôùùôòöùùúôûüüýüùøðíïøÿÿþýÿÿôþýûöôô÷üýúöúú÷ò÷ùøöö÷÷öö÷üø÷öõõó÷øÿû÷øùùüÿÿþÿÿùüûôõõö÷ ÷÷øööúýüù÷ùùûûúüúøöö÷ýòøûûþýÿÿþÿõüúõö÷÷öõö÷ûû÷ùö÷øõòóù÷÷öìõ÷øùùú÷÷õúøïñûÿüÿþþÿÿýüúööú÷ùúùùööø÷øøùùøø÷÷øø÷ööøüÿþÿÿüþüûøø÷øù ø÷ øø÷ööøüÿþÿÿüþüûøø÷øùø÷ûùýÿþÿÿüþüûùùøùúùøùøûúýÿþÿÿüþüûùùøþùúúùûúýÿþÿÿüþüûúúùúûúùúûûþÿþÿÿüþüûúúû úûúöùúûúúüþÿþÿÿýþüûûøúûûüüûûúúûúýùúûûûüþÿþÿÿýþüû0ûúúûýÿÿýþþüýüüû0ûúúûýÿÿýþþýþüûû üûûüýÿÿþþý5üôþÿÿþþÿÿþþýýüü$ýúþÿÿþþÿÿþþý2ýþÿþþÿÿþý"þÿþþÿÿþþýþ0þÿþþÿÿýþýþþ7ÿþ7ÿþ}ÿþÿþ.ÿþÿþÿþ-ÿþÿþÿ þ#ÿþÿþýýþÿÿýþýþþ!ÿþþýÿÿþýùþÿÿþýýþ þÿþýÿþýþýþýþÿþýÿþýþýûüýýþÿÿþýÿþùýüüýþþýýüüýþþÿÿþýÿõþÿÿþüÿúûÿýÿÿþþÿÿùüùüÿÿûÿÿýÿþþÿ ÿóýüÿÿûøúÿÿþÿýÿÿúüýÿþýþþóÿôÞÖÒÎÌÍÔàêþÿÿúýÿÿúþÿÿþýÿ ÿýþýÿÿáñßÿúúÿÿùùÿüÿÿîÑÀ·±««ª§¨¬°±»ÍçûÿÿúÎýüþþöÿÿüîØÃ·µþýüúúûþÿÿåµ´ºËÛèîòñïëâØ¶²³Ääþÿúÿüûüþþ ÿßúûÿûûÿýÿîÖ¾°¯ÁÓùÿÿúúÿýòÀ²±Ìêö÷ùüÿÿíûõöäʶ´Èêÿûùøüÿÿýúÿ ÿòûÿÿùÒÀ´ÀÚñüÿúýýíÿýݹ­ÈäòùúûÿýþýûûýÿÿúìŪ¼ÞÿÿþÿþþÿÿóûÿüùÿÿçÅ®¼ÖñÿÿÙþýøùþõÚ¾°áõþüýýúùüüþÿýúûýõ÷ÿÿûß¿«âôÿÿüÿ ÿÝýûõùúῲÖíÿÿûôøþýûÿþׯ¾éÿþöôüüúýüüÿÿùîýÿÿ÷òþÿèÂ¤Ïøÿþÿÿüÿÿ³üúÿê´¯Üüÿÿüüÿÿýþÿÿá«¿ìýøóøýûûùõùýøùûøøôýúúþúùþñƱÍûÿþÿûþÿÿýþÿÿûÿûÿ赺éÿøûöýóùùñýüÝ¿ëÿÿøóûûúýÿÿüøôýÿÿ€Õþøøûÿøú÷±Úÿÿõýþÿÿüüþýúøÿ￸Þý÷òþûøðúúûÿí½²×þúöòýÿòíóñìîÿûùÿíëðæò÷üî÷÷ûÿè¼³æÿ÷ýýÿÿüûüýûÿýÇ®Õ÷ÿøùýûüûÿùúÿÎ¶ÒøÿöùóÿázD@A;iÒÿÿ¼L?@F]Šõøöüñøÿà«ÀúÿþüÿÿüûýþþÿÞ«Ãöüøöúîñüþÿúýë±Ãöÿúöùýòš$!#)Äÿÿ¤ #Ïÿñýõ÷úñijáÿÿûÿÿþýÿÿÂõųáþûúðñòÿÿùù÷øÕ°Ûÿøòõìÿåx*[mdFGÔ÷ÿ« V`j\²ýñù÷ööþã´Âöÿúþÿþþÿÿ„ܶÉ÷ùôü÷ôÿõª‡Š‹¾Âõüöüþôþô{._ZZM9ÆÿÿªS`Wo²ÿûõòòøÿøÅ²äÿûýþýþÿüúùâÿøóôýüý®'$!*¬Îÿóòöôõ÷øt(gcdRBÀÿÿ¨&Wk`h¹öïëûøòîÿâ¯Òÿûýþýýîùõ­Éøùóüñõ÷÷(GhRWÿüïúùø÷ööõØÊÑòÿÿúÿýþþõýüüÿðØÊÒç÷ýýüû »¼þ½¾¾öÚçõûúûþÿýþþýöüþÿùêÙ˾¶¼¼»½éïåææèéêêëëúÿûúÿÿûþþýöüùÿÿüóìéçééþëììþëøøþùüüûûùõô÷ÿÿîúþþÿÿþþýýÿüóìíó÷ú÷÷øþùøøú÷ïöõôôóóõññ÷ûüýÿþþÿÿôþýýÿ÷òôùüùöùùú÷ööôõõô÷ýÿþþÿÿþöýôóôøúøõò÷÷ûö÷øùõóøÿÿûÿÿþýþúùùü÷ùþûûüþûöö÷ö÷ýùýÿÿõþýúõô÷øöõ÷ööøùúøöõ÷üÿÿþþÿÿýþýøø÷øùúøööøüÿÿþþÿÿýþýøø÷ùúø÷÷ùüÿÿþþÿÿýþýùùøùýúùøøýúýÿÿþþÿÿýþýùùøúõùøøùûýþÿÿþÿÿýþýúúùúôûúøùûüýþÿÿþÿÿýþýúúûõúùùüýþýÿÿþÿÿýþýû.ûôüúùúüþþýÿÿþÿÿýþýû/ûúýûýÿÿüûú*ûúýûýÿÿýýüûûüûúüûýþÿÿýþüûû*üûýýþÿÿúþýüüûüüýùüûûüýþÿÿþþýüü(ýøþýüûüýþÿÿûþýýüýýþþýüüýýþÿ ÿþþýý*þúýüüýþÿ ÿþþýýþÿþÿþ'ÿþÿþ'ÿþÿþØÿþ&ÿþÿþ$ÿ þÿþ#ÿ þÿþÿþýþÿþýþýþÿþ ýþ ÿøüúúýÿüþÿÿþþÿ ÿúúÿÿþüÿÿÞþúöúÿÿþÿþþÿÿþþÿüÿÿüüÿÿýÖÒÎÌÑÚåì÷þÿÿþÿþÿüüúüÿÿüþüþÿÿôöëߨÑÎÏÓÛâþÿÿìýÿÿ¬ª¨§¨«®±ºÌãñûÿÿüþþüÿþüþþüÿþüÿÿéüþþÿÿôÚ÷¶ªª¨¤¥©¬¬»ÇÝõÿÿðýêíðóîæÜ׿³¯¿ÜõýýøþýúûýþýþþÞÿüÿÿüøþÿÿïÖ¾²´ÃÑäìññðîæÞ½µ°ºØõÿýýÿÿîüûúå̼¶Âáÿþÿÿûúýÿþþîÿúýüöÿÿö×Á±¸ÕòÿÿûÿÿóüöõìØ¿¯¸Ùøþýüüþþÿÿòñ̳½ÔñüÿÿûýÿÿþþÈýþüýÿïŧ¼×îþÿÿùûûúøùûýýþÿÿùÔ±²Èýýüüúùø÷ôùÿÿþçÆ­ÏæûÿüýþþýýÝüÿþÿþçÇ·ÅåÿÿûøúûüûüþÿþþÿüôôÿÿìʰüýÿÿîýüþýùøÿÿëάÎðüüýþýýüÙ÷üò¾¬ÔýÿúñöÿÿøûùúþþúøúùÿýøýÿóØúø÷÷ùúùøýýóÿùÿÿùÔ±ÁíÿüöÿÿþÇýúþ÷¸±ßýÿøùúöøüùýøÿøùÿüýþüÿýúúøûýüûûýüýüýûóøúóÿÿõË³ÉøÿúüÿÿþßýÿòÊ©Ñýüôúüùøùùôóùüññùùøÿóï÷þýúûøø÷íøùýþû÷ÿõýøÿðÄ®ØÿÿúÿÿþâøÿÓ±Ëÿÿîúùôôøø÷úúûùúÿüúôùÿþúø÷÷çúûûúùùúüûúÿðùøÿóùÿê³µîÿúÿÿþöýÿì²¶îÿøøþþîüøúùóòÿÿüøöþî÷úòõÿÿå÷ùúüúøøúûþñÿýøóù÷öÿýЬÕÿúÿþþýßÿ̱ØùóôöáæôöîôüôÿÓçÿÿìöÿùôðÿðÈÕþ‹‹êЉЋŒŽ‰´óÿñïûøñþð¸¸ïÿþþýÆþð²ÆúùûÿÉ+cÂÿÿëðÿÎ9R»ÿÿóîõòüþ”:¹#"!!""#"/¼ÿðò÷÷ïøÿЫÔÿþþýÃÿÙ²Ùÿñþÿµ<Šßÿÿû³:€áÿÿóðøø‚œZXWWYZZYXQªÿôõìøõîûè·Âõÿþþýýßÿº½ìÿñðö¾!]HRÁüÿ¯"\FSªöúÿýõ”3‹üïúùø÷ööõØÊÑòÿÿúÿýþþõýüüÿðØÊÒç÷ýýüû »¼þ½¾¾öÚçõûúûþÿýþþýöüþÿùêÙ˾¶¼¼»½éïåææèéêêëëúÿûúÿÿûþþýöüùÿÿüóìéçééþëììþëøøþùüüûûùõô÷ÿÿîúþþÿÿþþýýÿüóìíó÷ú÷÷øþùøøú÷ïöõôôóóõññ÷ûüýÿþþÿÿôþýýÿ÷òôùüùöùùú÷ööôõõô÷ýÿþþÿÿþöýôóôøúøõò÷÷ûö÷øùõóøÿÿûÿÿþýþúùùü÷ùþûûüþûöö÷ö÷ýùýÿÿõþýúõô÷øöõ÷ööøùúøöõ÷üÿÿþþÿÿýþýøø÷øùúøööøüÿÿþþÿÿýþýøø÷ùúø÷÷ùüÿÿþþÿÿýþýùùøùýúùøøýúýÿÿþþÿÿýþýùùøúõùøøùûýþÿÿþÿÿýþýúúùúôûúøùûüýþÿÿþÿÿýþýúúûõúùùüýþýÿÿþÿÿýþýû.ûôüúùúüþþýÿÿþÿÿýþýû/ûúýûýÿÿüûú*ûúýûýÿÿýýüûûüûúüûýþÿÿýþüûû*üûýýþÿÿúþýüüûüüýùüûûüýþÿÿþþýüü(ýøþýüûüýþÿÿûþýýüýýþþýüüýýþÿ ÿþþýý*þúýüüýþÿ ÿþþýýþÿþÿþ'ÿþÿþ'ÿþÿþØÿþ&ÿþÿþ$ÿ þÿþ#ÿ þÿþÿþýþÿþýþýþÿþ ýþ ÿøüúúýÿüþÿÿþþÿ ÿúúÿÿþüÿÿÞþúöúÿÿþÿþþÿÿþþÿüÿÿüüÿÿýÖÒÎÌÑÚåì÷þÿÿþÿþÿüüúüÿÿüþüþÿÿôöëߨÑÎÏÓÛâþÿÿìýÿÿ¬ª¨§¨«®±ºÌãñûÿÿüþþüÿþüþþüÿþüÿÿéüþþÿÿôÚ÷¶ªª¨¤¥©¬¬»ÇÝõÿÿðýêíðóîæÜ׿³¯¿ÜõýýøþýúûýþýþþÞÿüÿÿüøþÿÿïÖ¾²´ÃÑäìññðîæÞ½µ°ºØõÿýýÿÿîüûúå̼¶Âáÿþÿÿûúýÿþþîÿúýüöÿÿö×Á±¸ÕòÿÿûÿÿóüöõìØ¿¯¸Ùøþýüüþþÿÿòñ̳½ÔñüÿÿûýÿÿþþÈýþüýÿïŧ¼×îþÿÿùûûúøùûýýþÿÿùÔ±²Èýýüüúùø÷ôùÿÿþçÆ­ÏæûÿüýþþýýÝüÿþÿþçÇ·ÅåÿÿûøúûüûüþÿþþÿüôôÿÿìʰüýÿÿîýüþýùøÿÿëάÎðüüýþýýüÙ÷üò¾¬ÔýÿúñöÿÿøûùúþþúøúùÿýøýÿóØúø÷÷ùúùøýýóÿùÿÿùÔ±ÁíÿüöÿÿþÇýúþ÷¸±ßýÿøùúöøüùýøÿøùÿüýþüÿýúúøûýüûûýüýüýûóøúóÿÿõË³ÉøÿúüÿÿþßýÿòÊ©Ñýüôúüùøùùôóùüññùùøÿóï÷þýúûøø÷íøùýþû÷ÿõýøÿðÄ®ØÿÿúÿÿþâøÿÓ±Ëÿÿîúùôôøø÷úúûùúÿüúôùÿþúø÷÷çúûûúùùúüûúÿðùøÿóùÿê³µîÿúÿÿþöýÿì²¶îÿøøþþîüøúùóòÿÿüøöþî÷úòõÿÿå÷ùúüúøøúûþñÿýøóù÷öÿýЬÕÿúÿþþýßÿ̱ØùóôöáæôöîôüôÿÓçÿÿìöÿùôðÿðÈÕþ‹‹êЉЋŒŽ‰´óÿñïûøñþð¸¸ïÿþþýÆþð²ÆúùûÿÉ+cÂÿÿëðÿÎ9R»ÿÿóîõòüþ”:¹#"!!""#"/¼ÿðò÷÷ïøÿЫÔÿþþýÃÿÙ²Ùÿñþÿµ<Šßÿÿû³:€áÿÿóðøø‚œZXWWYZZYXQªÿôõìøõîûè·Âõÿþþýýßÿº½ìÿñðö¾!]HRÁüÿ¯"\FSªöúÿýõ”3‹üïúùø÷ööõØÊÑòÿÿúÿýþþõýüüÿðØÊÒç÷ýýüû »¼þ½¾¾öÚçõûúûþÿýþþýöüþÿùêÙ˾¶¼¼»½éïåææèéêêëëúÿûúÿÿûþþýöüùÿÿüóìéçééþëììþëøøþùüüûûùõô÷ÿÿîúþþÿÿþþýýÿüóìíó÷ú÷÷øþùøøú÷ïöõôôóóõññ÷ûüýÿþþÿÿôþýýÿ÷òôùüùöùùú÷ööôõõô÷ýÿþþÿÿþöýôóôøúøõò÷÷ûö÷øùõóøÿÿûÿÿþýþúùùü÷ùþûûüþûöö÷ö÷ýùýÿÿõþýúõô÷øöõ÷ööøùúøöõ÷üÿÿþþÿÿýþýøø÷øùúøööøüÿÿþþÿÿýþýøø÷ùúø÷÷ùüÿÿþþÿÿýþýùùøùýúùøøýúýÿÿþþÿÿýþýùùøúõùøøùûýþÿÿþÿÿýþýúúùúôûúøùûüýþÿÿþÿÿýþýúúûõúùùüýþýÿÿþÿÿýþýû.ûôüúùúüþþýÿÿþÿÿýþýû/ûúýûýÿÿüûú*ûúýûýÿÿýýüûûüûúüûýþÿÿýþüûû*üûýýþÿÿúþýüüûüüýùüûûüýþÿÿþþýüü(ýøþýüûüýþÿÿûþýýüýýþþýüüýýþÿ ÿþþýý*þúýüüýþÿ ÿþþýýþÿþÿþ'ÿþÿþ'ÿþÿþØÿþ&ÿþÿþ$ÿ þÿþ#ÿ þÿþÿþýþÿþýþýþÿþ ýþ ÿøüúúýÿüþÿÿþþÿ ÿúúÿÿþüÿÿÞþúöúÿÿþÿþþÿÿþþÿüÿÿüüÿÿýÖÒÎÌÑÚåì÷þÿÿþÿþÿüüúüÿÿüþüþÿÿôöëߨÑÎÏÓÛâþÿÿìýÿÿ¬ª¨§¨«®±ºÌãñûÿÿüþþüÿþüþþüÿþüÿÿéüþþÿÿôÚ÷¶ªª¨¤¥©¬¬»ÇÝõÿÿðýêíðóîæÜ׿³¯¿ÜõýýøþýúûýþýþþÞÿüÿÿüøþÿÿïÖ¾²´ÃÑäìññðîæÞ½µ°ºØõÿýýÿÿîüûúå̼¶Âáÿþÿÿûúýÿþþîÿúýüöÿÿö×Á±¸ÕòÿÿûÿÿóüöõìØ¿¯¸Ùøþýüüþþÿÿòñ̳½ÔñüÿÿûýÿÿþþÈýþüýÿïŧ¼×îþÿÿùûûúøùûýýþÿÿùÔ±²Èýýüüúùø÷ôùÿÿþçÆ­ÏæûÿüýþþýýÝüÿþÿþçÇ·ÅåÿÿûøúûüûüþÿþþÿüôôÿÿìʰüýÿÿîýüþýùøÿÿëάÎðüüýþýýüÙ÷üò¾¬ÔýÿúñöÿÿøûùúþþúøúùÿýøýÿóØúø÷÷ùúùøýýóÿùÿÿùÔ±ÁíÿüöÿÿþÇýúþ÷¸±ßýÿøùúöøüùýøÿøùÿüýþüÿýúúøûýüûûýüýüýûóøúóÿÿõË³ÉøÿúüÿÿþßýÿòÊ©Ñýüôúüùøùùôóùüññùùøÿóï÷þýúûøø÷íøùýþû÷ÿõýøÿðÄ®ØÿÿúÿÿþâøÿÓ±Ëÿÿîúùôôøø÷úúûùúÿüúôùÿþúø÷÷çúûûúùùúüûúÿðùøÿóùÿê³µîÿúÿÿþöýÿì²¶îÿøøþþîüøúùóòÿÿüøöþî÷úòõÿÿå÷ùúüúøøúûþñÿýøóù÷öÿýЬÕÿúÿþþýßÿ̱ØùóôöáæôöîôüôÿÓçÿÿìöÿùôðÿðÈÕþ‹‹êЉЋŒŽ‰´óÿñïûøñþð¸¸ïÿþþýÆþð²ÆúùûÿÉ+cÂÿÿëðÿÎ9R»ÿÿóîõòüþ”:¹#"!!""#"/¼ÿðò÷÷ïøÿЫÔÿþþýÃÿÙ²Ùÿñþÿµ<Šßÿÿû³:€áÿÿóðøø‚œZXWWYZZYXQªÿôõìøõîûè·Âõÿþþýýßÿº½ìÿñðö¾!]HRÁüÿ¯"\FSªöúÿýõ”3‹ÿ÷éØÈÓðüúúÿÿ÷ôÿ÷ÖÈÛñøýýüûúè÷ë×Î×ìüÿýþÿÿýýþÿÎÛçôþýüÿÿ÷ýÿÿùçÒÅ¿¼¼»úÅÌÖãôÿÿïýþÿÿýýþÿäñùýÿüøøÿÿ÷úøûÿÿóèæééçáêôüÿÿüõýþÿÿýýþÿ÷öóð÷þþûÿÿøúðñùüøø÷÷ø÷èøö÷öõöùýÿýþÿÿýýþÿñõöóóúÿÿ÷÷üùîïúüõùùúøóéòññôûÿýþÿÿýýþÿøùüúõøýüÿÿ÷öøùø÷÷øø÷÷ôæõýüýü÷óõùýþÿÿýýþÿþõô÷÷ûÿþÿÿöý÷ôôóðòøúû ûùçôóöøøöùþýþÿÿýýþÿûóöûõõûþÿÿöø÷ö÷ùûùøõööçø÷øúøõ÷üýþÿÿýýþÿõö÷ø÷øúüÿÿûúùøø÷÷ø÷ö÷ù÷øùøö÷ûÿÿýö÷øøüùûüÿÿù ø÷÷ù÷÷ùøõ÷ûÿÿ÷÷øùùøùûýÿÿùøùþúùùø÷ù÷÷ùøõ÷úÿÿüøùúùùýûýÿÿùøûùúúûùùøù÷úùøõ÷úÿÿüùúûúúýüýÿÿùüúûüúúùú÷ùøøùøö÷ûÿÿûùüûúûüþÿÿúûúùúúù÷øüÿÿ÷ûüýüûûüþÿÿüüûûúúûú÷ûúúûúøùýÿÿ÷üýýüûûýþÿÿüýüûúúûú÷üúúüûøúýÿÿ÷ûüýýüüýþÿÿüûþúûûüûüüýýÿÿ÷ûüýýüüýþÿÿüûüûüýÿ÷ûüýýüüýþÿÿüûüýþþÿÿøüýþþýüþÿÿýüýüüýþþÿÿøüýþþýýþÿÿýüýþÿøüýþþýýþÿÿþýþýþ ÿøüýþþýýþÿÿþýþ ÿøüþÿþýýþÿÿþýþþÿþþÿþ7ÿþ7ÿþ†ÿýþýÿ;ÿþþýÿ6ÿþþÿÿþþýÿÿþþÿ-ÿþÿüþýýÿÿþ,ÿþÿþýÿþ+ÿþýþüþ þ*ÿþýþþýþüþþþýþþ*ÿþýþþüýüüþþýþÿþ ÿþøÿþÿÿþýþÿÿïþýýÿÿýüÿÿýýþÿþýþÿÿþÿþÿûýûûýÿÿüþùøÿÿóýþìáÔÍÌÎÕÜîöÿ ÿýüþÿÿýüýþþüÿþþÿÿýÿþþÿÿøùâ̱®«¬¬ï­¶·ÂÙòÿÿþüÿýüÿÿûÿÿ÷ûþþûûýþþÿ ÿÝþúüÿùÝ¿°°µØßéóöñèã×Å´°ºÏìÿýÿúõÿÿûúÿÿ÷üÿÿýùûþþÿÿ×úþÿþþÿþûÿå¾°¾Øïù÷úüþýþýüþýôܽ°¿Öñÿÿýüýüþÿÿ÷îúÿÿüüþþÿÿñúþþýÿÿþøË²©Åêþÿÿêþûúýÿÿôûÿÿ÷Ú½¬Åãÿÿþöúÿÿ÷Èàøÿýÿÿþÿ ÿÚþÿþëÕ¥Åíÿÿùöúöüÿþýÿÿýÿùñ÷ÿÿëÔµ»Üýÿùûþÿÿú¢Æêúýÿ ÿóþüüþòÊ£ÑðÿùôÿÿçúýýùöúýýùþÿüúûýýÓ®¶äüþÿýÿÿøÚ°»êÿÿùÿÿþþÿÿÈþýÿüüÿ÷Á§Öûû÷øûøõüòøúúüüùóòøüüúùùüøã²«çÿýüÿüþÿúýÿüþغÀëÿÿþþÿÿ×þýÿýÿñɹÍðÿøóøÿÿøòúÿÿ÷÷ÿÿûÿüöüÿÿùöÿÿⲸèÿÿíúýÿýþÿüÿüÔ­ÎþÿþÿÿþÿÿÒþýÿýÿÚ§Âõÿõøûóòóùøôôòýöðîÿôûÿüñî÷ÿñüþÙ«ÌüûÿúûÿÿóýïÿñÀºâýþÿÿþÿÿþþýýÊíĵâÿûýüÿÿþ÷úõçþý÷ôÿ÷ÿøïòûùõüÿÿðûýÀ´ÞøÿûûÿÿþýþùüûÚ³ÉøÿÿþþÿÿÆþýÿþγÚýúöÿÚËßþóöýüôëøýÿÏõõùùò÷ÿúÖìûõÿè·ºõÿþûýÿýüþÿùÿöõæÿÿþþÿÿÂþýÿõº¶ôÿòÿäLYîÿøéóíÿÿÏ{/¦ÿóóÿÿÚˆ2šÿúúÿÒ¦àþÿýüýýüþÿùüÿà²ÊûÿÿþÿÿÂþýÿܵÑýùóÿ·.Rìþóüþÿò @þîÿÿ²Iuÿþêýæ¯Äõÿÿûýÿýýÿùëþ÷»·îÿÿþÿÿÎþýýŸìÿòúÿ¶F`îüòýÿÈo".dŠÿÿÔk*>Q4zøþóýûɳïþÿüþÿþý÷éØÈÓðüúúÿÿ÷ôÿ÷ÖÈÛñøýýüûúè÷ë×Î×ìüÿýþÿÿýýþÿÎÛçôþýüÿÿ÷ýÿÿùçÒÅ¿¼¼»úÅÌÖãôÿÿïýþÿÿýýþÿäñùýÿüøøÿÿ÷úøûÿÿóèæééçáêôüÿÿüõýþÿÿýýþÿ÷öóð÷þþûÿÿøúðñùüøø÷÷ø÷èøö÷öõöùýÿýþÿÿýýþÿñõöóóúÿÿ÷÷üùîïúüõùùúøóéòññôûÿýþÿÿýýþÿøùüúõøýüÿÿ÷öøùø÷÷øø÷÷ôæõýüýü÷óõùýþÿÿýýþÿþõô÷÷ûÿþÿÿöý÷ôôóðòøúû ûùçôóöøøöùþýþÿÿýýþÿûóöûõõûþÿÿöø÷ö÷ùûùøõööçø÷øúøõ÷üýþÿÿýýþÿõö÷ø÷øúüÿÿûúùøø÷÷ø÷ö÷ù÷øùøö÷ûÿÿýö÷øøüùûüÿÿù ø÷÷ù÷÷ùøõ÷ûÿÿ÷÷øùùøùûýÿÿùøùþúùùø÷ù÷÷ùøõ÷úÿÿüøùúùùýûýÿÿùøûùúúûùùøù÷úùøõ÷úÿÿüùúûúúýüýÿÿùüúûüúúùú÷ùøøùøö÷ûÿÿûùüûúûüþÿÿúûúùúúù÷øüÿÿ÷ûüýüûûüþÿÿüüûûúúûú÷ûúúûúøùýÿÿ÷üýýüûûýþÿÿüýüûúúûú÷üúúüûøúýÿÿ÷ûüýýüüýþÿÿüûþúûûüûüüýýÿÿ÷ûüýýüüýþÿÿüûüûüýÿ÷ûüýýüüýþÿÿüûüýþþÿÿøüýþþýüþÿÿýüýüüýþþÿÿøüýþþýýþÿÿýüýþÿøüýþþýýþÿÿþýþýþ ÿøüýþþýýþÿÿþýþ ÿøüþÿþýýþÿÿþýþþÿþþÿþ7ÿþ7ÿþ†ÿýþýÿ;ÿþþýÿ6ÿþþÿÿþþýÿÿþþÿ-ÿþÿüþýýÿÿþ,ÿþÿþýÿþ+ÿþýþüþ þ*ÿþýþþýþüþþþýþþ*ÿþýþþüýüüþþýþÿþ ÿþøÿþÿÿþýþÿÿïþýýÿÿýüÿÿýýþÿþýþÿÿþÿþÿûýûûýÿÿüþùøÿÿóýþìáÔÍÌÎÕÜîöÿ ÿýüþÿÿýüýþþüÿþþÿÿýÿþþÿÿøùâ̱®«¬¬ï­¶·ÂÙòÿÿþüÿýüÿÿûÿÿ÷ûþþûûýþþÿ ÿÝþúüÿùÝ¿°°µØßéóöñèã×Å´°ºÏìÿýÿúõÿÿûúÿÿ÷üÿÿýùûþþÿÿ×úþÿþþÿþûÿå¾°¾Øïù÷úüþýþýüþýôܽ°¿Öñÿÿýüýüþÿÿ÷îúÿÿüüþþÿÿñúþþýÿÿþøË²©Åêþÿÿêþûúýÿÿôûÿÿ÷Ú½¬Åãÿÿþöúÿÿ÷Èàøÿýÿÿþÿ ÿÚþÿþëÕ¥Åíÿÿùöúöüÿþýÿÿýÿùñ÷ÿÿëÔµ»Üýÿùûþÿÿú¢Æêúýÿ ÿóþüüþòÊ£ÑðÿùôÿÿçúýýùöúýýùþÿüúûýýÓ®¶äüþÿýÿÿøÚ°»êÿÿùÿÿþþÿÿÈþýÿüüÿ÷Á§Öûû÷øûøõüòøúúüüùóòøüüúùùüøã²«çÿýüÿüþÿúýÿüþغÀëÿÿþþÿÿ×þýÿýÿñɹÍðÿøóøÿÿøòúÿÿ÷÷ÿÿûÿüöüÿÿùöÿÿⲸèÿÿíúýÿýþÿüÿüÔ­ÎþÿþÿÿþÿÿÒþýÿýÿÚ§Âõÿõøûóòóùøôôòýöðîÿôûÿüñî÷ÿñüþÙ«ÌüûÿúûÿÿóýïÿñÀºâýþÿÿþÿÿþþýýÊíĵâÿûýüÿÿþ÷úõçþý÷ôÿ÷ÿøïòûùõüÿÿðûýÀ´ÞøÿûûÿÿþýþùüûÚ³ÉøÿÿþþÿÿÆþýÿþγÚýúöÿÚËßþóöýüôëøýÿÏõõùùò÷ÿúÖìûõÿè·ºõÿþûýÿýüþÿùÿöõæÿÿþþÿÿÂþýÿõº¶ôÿòÿäLYîÿøéóíÿÿÏ{/¦ÿóóÿÿÚˆ2šÿúúÿÒ¦àþÿýüýýüþÿùüÿà²ÊûÿÿþÿÿÂþýÿܵÑýùóÿ·.Rìþóüþÿò @þîÿÿ²Iuÿþêýæ¯Äõÿÿûýÿýýÿùëþ÷»·îÿÿþÿÿÎþýýŸìÿòúÿ¶F`îüòýÿÈo".dŠÿÿÔk*>Q4zøþóýûɳïþÿüþÿþý÷éØÈÓðüúúÿÿ÷ôÿ÷ÖÈÛñøýýüûúè÷ë×Î×ìüÿýþÿÿýýþÿÎÛçôþýüÿÿ÷ýÿÿùçÒÅ¿¼¼»úÅÌÖãôÿÿïýþÿÿýýþÿäñùýÿüøøÿÿ÷úøûÿÿóèæééçáêôüÿÿüõýþÿÿýýþÿ÷öóð÷þþûÿÿøúðñùüøø÷÷ø÷èøö÷öõöùýÿýþÿÿýýþÿñõöóóúÿÿ÷÷üùîïúüõùùúøóéòññôûÿýþÿÿýýþÿøùüúõøýüÿÿ÷öøùø÷÷øø÷÷ôæõýüýü÷óõùýþÿÿýýþÿþõô÷÷ûÿþÿÿöý÷ôôóðòøúû ûùçôóöøøöùþýþÿÿýýþÿûóöûõõûþÿÿöø÷ö÷ùûùøõööçø÷øúøõ÷üýþÿÿýýþÿõö÷ø÷øúüÿÿûúùøø÷÷ø÷ö÷ù÷øùøö÷ûÿÿýö÷øøüùûüÿÿù ø÷÷ù÷÷ùøõ÷ûÿÿ÷÷øùùøùûýÿÿùøùþúùùø÷ù÷÷ùøõ÷úÿÿüøùúùùýûýÿÿùøûùúúûùùøù÷úùøõ÷úÿÿüùúûúúýüýÿÿùüúûüúúùú÷ùøøùøö÷ûÿÿûùüûúûüþÿÿúûúùúúù÷øüÿÿ÷ûüýüûûüþÿÿüüûûúúûú÷ûúúûúøùýÿÿ÷üýýüûûýþÿÿüýüûúúûú÷üúúüûøúýÿÿ÷ûüýýüüýþÿÿüûþúûûüûüüýýÿÿ÷ûüýýüüýþÿÿüûüûüýÿ÷ûüýýüüýþÿÿüûüýþþÿÿøüýþþýüþÿÿýüýüüýþþÿÿøüýþþýýþÿÿýüýþÿøüýþþýýþÿÿþýþýþ ÿøüýþþýýþÿÿþýþ ÿøüþÿþýýþÿÿþýþþÿþþÿþ7ÿþ7ÿþ†ÿýþýÿ;ÿþþýÿ6ÿþþÿÿþþýÿÿþþÿ-ÿþÿüþýýÿÿþ,ÿþÿþýÿþ+ÿþýþüþ þ*ÿþýþþýþüþþþýþþ*ÿþýþþüýüüþþýþÿþ ÿþøÿþÿÿþýþÿÿïþýýÿÿýüÿÿýýþÿþýþÿÿþÿþÿûýûûýÿÿüþùøÿÿóýþìáÔÍÌÎÕÜîöÿ ÿýüþÿÿýüýþþüÿþþÿÿýÿþþÿÿøùâ̱®«¬¬ï­¶·ÂÙòÿÿþüÿýüÿÿûÿÿ÷ûþþûûýþþÿ ÿÝþúüÿùÝ¿°°µØßéóöñèã×Å´°ºÏìÿýÿúõÿÿûúÿÿ÷üÿÿýùûþþÿÿ×úþÿþþÿþûÿå¾°¾Øïù÷úüþýþýüþýôܽ°¿Öñÿÿýüýüþÿÿ÷îúÿÿüüþþÿÿñúþþýÿÿþøË²©Åêþÿÿêþûúýÿÿôûÿÿ÷Ú½¬Åãÿÿþöúÿÿ÷Èàøÿýÿÿþÿ ÿÚþÿþëÕ¥Åíÿÿùöúöüÿþýÿÿýÿùñ÷ÿÿëÔµ»Üýÿùûþÿÿú¢Æêúýÿ ÿóþüüþòÊ£ÑðÿùôÿÿçúýýùöúýýùþÿüúûýýÓ®¶äüþÿýÿÿøÚ°»êÿÿùÿÿþþÿÿÈþýÿüüÿ÷Á§Öûû÷øûøõüòøúúüüùóòøüüúùùüøã²«çÿýüÿüþÿúýÿüþغÀëÿÿþþÿÿ×þýÿýÿñɹÍðÿøóøÿÿøòúÿÿ÷÷ÿÿûÿüöüÿÿùöÿÿⲸèÿÿíúýÿýþÿüÿüÔ­ÎþÿþÿÿþÿÿÒþýÿýÿÚ§Âõÿõøûóòóùøôôòýöðîÿôûÿüñî÷ÿñüþÙ«ÌüûÿúûÿÿóýïÿñÀºâýþÿÿþÿÿþþýýÊíĵâÿûýüÿÿþ÷úõçþý÷ôÿ÷ÿøïòûùõüÿÿðûýÀ´ÞøÿûûÿÿþýþùüûÚ³ÉøÿÿþþÿÿÆþýÿþγÚýúöÿÚËßþóöýüôëøýÿÏõõùùò÷ÿúÖìûõÿè·ºõÿþûýÿýüþÿùÿöõæÿÿþþÿÿÂþýÿõº¶ôÿòÿäLYîÿøéóíÿÿÏ{/¦ÿóóÿÿÚˆ2šÿúúÿÒ¦àþÿýüýýüþÿùüÿà²ÊûÿÿþÿÿÂþýÿܵÑýùóÿ·.Rìþóüþÿò @þîÿÿ²Iuÿþêýæ¯Äõÿÿûýÿýýÿùëþ÷»·îÿÿþÿÿÎþýýŸìÿòúÿ¶F`îüòýÿÈo".dŠÿÿÔk*>Q4zøþóýûɳïþÿüþÿþýÿ÷üÿÿóÛÍÐÙííëðìîïðîéßÒÎÙðÿýýþÿÿþ÷ýÿÿ÷âÏÍÕííîðÿúþ÷ëÞÔÑÑÓôÒÑÑÐÐÑÖàëöüýýþþÿÿþÿûùíãßÇÇ÷üúúýÿýôêïïóêëììëêèçíêëôÿÿûùýýþÿÿþÿýôéììëêÿúüôðó÷ùùýúûüüõúöõöùüþýýþÿÿþõüÿþùö÷öòùùøø÷÷ûÿÿüñìðøööðóòòóôõööñòõôóõùýýþþÿÿþõüÿýôîñö÷ôôõõö÷ýùõõ÷ùùøõõøûúø÷ö÷÷øøùùø÷öýýþÿÿþøû÷õøùùõööþ÷øø÷ÿþôòöùøóøøûùøø÷ööôø÷öö÷ø÷öýýþÿÿþýúùúúù÷øüûúù÷÷þø÷÷óóôö÷øø÷÷öøùùøøûúýýþÿÿþöûø÷ù÷òóøø÷÷öô÷þû÷÷ùúøöøøýýþÿÿøþÿÿýûø÷øøþ÷øø÷þû÷÷ùúøöøøýýþÿÿùþÿÿýûùøøþ÷øø÷þûøøùúù÷ùùýýþÿÿôþÿÿþüùøøùøøùù÷þüùøùúùøùùýýþÿÿøþÿÿþüúøùùþøùù÷ÿýúùùúùùúúýýþÿÿþþÿÿøýúùùúúùúúúÿýûúùú!úýýþÿÿþþÿÿýýûúúþùúúûÿþüûúú ûýýþÿÿþþÿÿøþûúúûúúûûûÿþýûúú ûýýþÿÿþþÿÿøþûúúûûúûûüþýüû#ûþÿüþýüû ûþýýüû"ûþÿþýýüû ûùÿþýüüûü üþÿúþýüüûüüûÿþýýü"üþÿüþýýü üÿûþýýüý ýþÿûþýýüýýÿþþý"ýþÿþþý ýÿþþýþ#þÿþþýþþÿ'þÿ þÿþ7ÿþ7ÿþèÿþ/ÿþ/ÿþ/ÿþÿþÿýÿþÿýÿþïýÿþþÿÿýÿÿùùÿÿûùþÿÿþýÿÿôýüüÿþûüþÿÿþÿÿõüÿÿûþþýÿþÿþþÿþøýÿüÿÿúûÿÿçþïÚÍÊÍÏÐÖêýÿþÿÿüùÿÿþüÿÿýÿÿûþÿþüÿÿüûöùÿÿúûÿÿüýÿÿýöûÿÿîøäѾ·°««¬¬«­±¶¾Ôíÿÿýýûÿ ÿøûüÿÿþÿþÿÿûýçÑûüüÿýýûÿÿá÷ÞÁ²³¾ËÛéíîîïàÕÉ¿³±ÊçûþÿýüýþýþÿÿÈþûüýüûýôÿÿûã˶ªÿþþÿþûûþÿøäÅ®´Ôïõûÿÿþüþÿÿýúôß¶ºÈíÿÿøýþöþþÿþûýúúýÿÿùîβ¯Æßÿÿ×ûúÿÿýÖ´µËâõÿýüúúûûüûýûùûÿøßÈ«Àáþÿÿüüýýþþÿÿþþÿÿýûþÿÿåß»³ÇáöÿüþÿÿüÿýðÒ¸´ÛÿÿþùüüýÿÿéüùõüüøøÿÿûϹ¹ßýÿüÿüýýþÿÿïþÿÿþûÿþðÕº¯Î÷ÿýóÿÿòüþÿïÈ©Ìòÿýøûÿýýøùööùýþýüüïù÷öÿཷÔôÿûüüýþþÿÿÅûúÿöÞ²ÀâÿÿöòÿÿûýúÿøÉ¯Éöÿôÿÿó÷ÿÿüýíöýôúùúÿñÿÿýýÿêÁ²×ÿþýûÿÿþÿÿØüÿýùÿåªÁêÿþüÿýöþÿúÿýеÄùûÿøîöÿÿãÀ‘xp»ÿþÿÿïüúöêäåøþè»¶çÿýûýÿÿþýÿÿ”ߺ´ïþÿøöùûýþÿúÿ嬺æÿýôðÿÿݘX4„ÿÿ÷ÑÔ¨›aBˆéûÿÿÙ°Åòþýüþÿþþÿþÿüÿò¼®Ûÿÿýûýû÷úÿøÿù¿­áÿúûøÿÿ»Y&9kh4“ÿÿ—&6'%HÁùù€˜ÿü̯×ûÿüþÿüþÿÿøÿüϱÐþþøôñ÷øóýÿøÿÞªÎÿþùôÿü+Oz^SA'”ÿøwB\F(µÿÿñ÷ùÿëµ»ðÿþþÿûþÿÿùÿí³Áõÿûøùõøùòþýÿù¿´íþíñÿüš''brU<(4T¼ÿúp^,Q¾ÿøûõ÷ü×®ÚûÿþþúÿþüÿùȬÛÿõÿþÿÿ€‚ûÿüÿÞ±Ìøùêóÿº7$mx? l»ëòøôöˆw[|aHØÿüòòüõ¸¼ñÿÿþûÿûûÿ䯹õÿáª™š™žºÿýŲÚ÷þôüèd"pu0/³õüûÿýïÿŽB5Rqi"€öøò÷òýɧêþÿÿüÿúüÿܱÌÿùÅ1"(6÷üÿÿóÛÍÐÙííëðìîïðîéßÒÎÙðÿýýþÿÿþ÷ýÿÿ÷âÏÍÕííîðÿúþ÷ëÞÔÑÑÓôÒÑÑÐÐÑÖàëöüýýþþÿÿþÿûùíãßÇÇ÷üúúýÿýôêïïóêëììëêèçíêëôÿÿûùýýþÿÿþÿýôéììëêÿúüôðó÷ùùýúûüüõúöõöùüþýýþÿÿþõüÿþùö÷öòùùøø÷÷ûÿÿüñìðøööðóòòóôõööñòõôóõùýýþþÿÿþõüÿýôîñö÷ôôõõö÷ýùõõ÷ùùøõõøûúø÷ö÷÷øøùùø÷öýýþÿÿþøû÷õøùùõööþ÷øø÷ÿþôòöùøóøøûùøø÷ööôø÷öö÷ø÷öýýþÿÿþýúùúúù÷øüûúù÷÷þø÷÷óóôö÷øø÷÷öøùùøøûúýýþÿÿþöûø÷ù÷òóøø÷÷öô÷þû÷÷ùúøöøøýýþÿÿøþÿÿýûø÷øøþ÷øø÷þû÷÷ùúøöøøýýþÿÿùþÿÿýûùøøþ÷øø÷þûøøùúù÷ùùýýþÿÿôþÿÿþüùøøùøøùù÷þüùøùúùøùùýýþÿÿøþÿÿþüúøùùþøùù÷ÿýúùùúùùúúýýþÿÿþþÿÿøýúùùúúùúúúÿýûúùú!úýýþÿÿþþÿÿýýûúúþùúúûÿþüûúú ûýýþÿÿþþÿÿøþûúúûúúûûûÿþýûúú ûýýþÿÿþþÿÿøþûúúûûúûûüþýüû#ûþÿüþýüû ûþýýüû"ûþÿþýýüû ûùÿþýüüûü üþÿúþýüüûüüûÿþýýü"üþÿüþýýü üÿûþýýüý ýþÿûþýýüýýÿþþý"ýþÿþþý ýÿþþýþ#þÿþþýþþÿ'þÿ þÿþ7ÿþ7ÿþèÿþ/ÿþ/ÿþ/ÿþÿþÿýÿþÿýÿþïýÿþþÿÿýÿÿùùÿÿûùþÿÿþýÿÿôýüüÿþûüþÿÿþÿÿõüÿÿûþþýÿþÿþþÿþøýÿüÿÿúûÿÿçþïÚÍÊÍÏÐÖêýÿþÿÿüùÿÿþüÿÿýÿÿûþÿþüÿÿüûöùÿÿúûÿÿüýÿÿýöûÿÿîøäѾ·°««¬¬«­±¶¾Ôíÿÿýýûÿ ÿøûüÿÿþÿþÿÿûýçÑûüüÿýýûÿÿá÷ÞÁ²³¾ËÛéíîîïàÕÉ¿³±ÊçûþÿýüýþýþÿÿÈþûüýüûýôÿÿûã˶ªÿþþÿþûûþÿøäÅ®´Ôïõûÿÿþüþÿÿýúôß¶ºÈíÿÿøýþöþþÿþûýúúýÿÿùîβ¯Æßÿÿ×ûúÿÿýÖ´µËâõÿýüúúûûüûýûùûÿøßÈ«Àáþÿÿüüýýþþÿÿþþÿÿýûþÿÿåß»³ÇáöÿüþÿÿüÿýðÒ¸´ÛÿÿþùüüýÿÿéüùõüüøøÿÿûϹ¹ßýÿüÿüýýþÿÿïþÿÿþûÿþðÕº¯Î÷ÿýóÿÿòüþÿïÈ©Ìòÿýøûÿýýøùööùýþýüüïù÷öÿཷÔôÿûüüýþþÿÿÅûúÿöÞ²ÀâÿÿöòÿÿûýúÿøÉ¯Éöÿôÿÿó÷ÿÿüýíöýôúùúÿñÿÿýýÿêÁ²×ÿþýûÿÿþÿÿØüÿýùÿåªÁêÿþüÿýöþÿúÿýеÄùûÿøîöÿÿãÀ‘xp»ÿþÿÿïüúöêäåøþè»¶çÿýûýÿÿþýÿÿ”ߺ´ïþÿøöùûýþÿúÿ嬺æÿýôðÿÿݘX4„ÿÿ÷ÑÔ¨›aBˆéûÿÿÙ°Åòþýüþÿþþÿþÿüÿò¼®Ûÿÿýûýû÷úÿøÿù¿­áÿúûøÿÿ»Y&9kh4“ÿÿ—&6'%HÁùù€˜ÿü̯×ûÿüþÿüþÿÿøÿüϱÐþþøôñ÷øóýÿøÿÞªÎÿþùôÿü+Oz^SA'”ÿøwB\F(µÿÿñ÷ùÿëµ»ðÿþþÿûþÿÿùÿí³Áõÿûøùõøùòþýÿù¿´íþíñÿüš''brU<(4T¼ÿúp^,Q¾ÿøûõ÷ü×®ÚûÿþþúÿþüÿùȬÛÿõÿþÿÿ€‚ûÿüÿÞ±Ìøùêóÿº7$mx? l»ëòøôöˆw[|aHØÿüòòüõ¸¼ñÿÿþûÿûûÿ䯹õÿáª™š™žºÿýŲÚ÷þôüèd"pu0/³õüûÿýïÿŽB5Rqi"€öøò÷òýɧêþÿÿüÿúüÿܱÌÿùÅ1"(6÷üÿÿóÛÍÐÙííëðìîïðîéßÒÎÙðÿýýþÿÿþ÷ýÿÿ÷âÏÍÕííîðÿúþ÷ëÞÔÑÑÓôÒÑÑÐÐÑÖàëöüýýþþÿÿþÿûùíãßÇÇ÷üúúýÿýôêïïóêëììëêèçíêëôÿÿûùýýþÿÿþÿýôéììëêÿúüôðó÷ùùýúûüüõúöõöùüþýýþÿÿþõüÿþùö÷öòùùøø÷÷ûÿÿüñìðøööðóòòóôõööñòõôóõùýýþþÿÿþõüÿýôîñö÷ôôõõö÷ýùõõ÷ùùøõõøûúø÷ö÷÷øøùùø÷öýýþÿÿþøû÷õøùùõööþ÷øø÷ÿþôòöùøóøøûùøø÷ööôø÷öö÷ø÷öýýþÿÿþýúùúúù÷øüûúù÷÷þø÷÷óóôö÷øø÷÷öøùùøøûúýýþÿÿþöûø÷ù÷òóøø÷÷öô÷þû÷÷ùúøöøøýýþÿÿøþÿÿýûø÷øøþ÷øø÷þû÷÷ùúøöøøýýþÿÿùþÿÿýûùøøþ÷øø÷þûøøùúù÷ùùýýþÿÿôþÿÿþüùøøùøøùù÷þüùøùúùøùùýýþÿÿøþÿÿþüúøùùþøùù÷ÿýúùùúùùúúýýþÿÿþþÿÿøýúùùúúùúúúÿýûúùú!úýýþÿÿþþÿÿýýûúúþùúúûÿþüûúú ûýýþÿÿþþÿÿøþûúúûúúûûûÿþýûúú ûýýþÿÿþþÿÿøþûúúûûúûûüþýüû#ûþÿüþýüû ûþýýüû"ûþÿþýýüû ûùÿþýüüûü üþÿúþýüüûüüûÿþýýü"üþÿüþýýü üÿûþýýüý ýþÿûþýýüýýÿþþý"ýþÿþþý ýÿþþýþ#þÿþþýþþÿ'þÿ þÿþ7ÿþ7ÿþèÿþ/ÿþ/ÿþ/ÿþÿþÿýÿþÿýÿþïýÿþþÿÿýÿÿùùÿÿûùþÿÿþýÿÿôýüüÿþûüþÿÿþÿÿõüÿÿûþþýÿþÿþþÿþøýÿüÿÿúûÿÿçþïÚÍÊÍÏÐÖêýÿþÿÿüùÿÿþüÿÿýÿÿûþÿþüÿÿüûöùÿÿúûÿÿüýÿÿýöûÿÿîøäѾ·°««¬¬«­±¶¾Ôíÿÿýýûÿ ÿøûüÿÿþÿþÿÿûýçÑûüüÿýýûÿÿá÷ÞÁ²³¾ËÛéíîîïàÕÉ¿³±ÊçûþÿýüýþýþÿÿÈþûüýüûýôÿÿûã˶ªÿþþÿþûûþÿøäÅ®´Ôïõûÿÿþüþÿÿýúôß¶ºÈíÿÿøýþöþþÿþûýúúýÿÿùîβ¯Æßÿÿ×ûúÿÿýÖ´µËâõÿýüúúûûüûýûùûÿøßÈ«Àáþÿÿüüýýþþÿÿþþÿÿýûþÿÿåß»³ÇáöÿüþÿÿüÿýðÒ¸´ÛÿÿþùüüýÿÿéüùõüüøøÿÿûϹ¹ßýÿüÿüýýþÿÿïþÿÿþûÿþðÕº¯Î÷ÿýóÿÿòüþÿïÈ©Ìòÿýøûÿýýøùööùýþýüüïù÷öÿཷÔôÿûüüýþþÿÿÅûúÿöÞ²ÀâÿÿöòÿÿûýúÿøÉ¯Éöÿôÿÿó÷ÿÿüýíöýôúùúÿñÿÿýýÿêÁ²×ÿþýûÿÿþÿÿØüÿýùÿåªÁêÿþüÿýöþÿúÿýеÄùûÿøîöÿÿãÀ‘xp»ÿþÿÿïüúöêäåøþè»¶çÿýûýÿÿþýÿÿ”ߺ´ïþÿøöùûýþÿúÿ嬺æÿýôðÿÿݘX4„ÿÿ÷ÑÔ¨›aBˆéûÿÿÙ°Åòþýüþÿþþÿþÿüÿò¼®Ûÿÿýûýû÷úÿøÿù¿­áÿúûøÿÿ»Y&9kh4“ÿÿ—&6'%HÁùù€˜ÿü̯×ûÿüþÿüþÿÿøÿüϱÐþþøôñ÷øóýÿøÿÞªÎÿþùôÿü+Oz^SA'”ÿøwB\F(µÿÿñ÷ùÿëµ»ðÿþþÿûþÿÿùÿí³Áõÿûøùõøùòþýÿù¿´íþíñÿüš''brU<(4T¼ÿúp^,Q¾ÿøûõ÷ü×®ÚûÿþþúÿþüÿùȬÛÿõÿþÿÿ€‚ûÿüÿÞ±Ìøùêóÿº7$mx? l»ëòøôöˆw[|aHØÿüòòüõ¸¼ñÿÿþûÿûûÿ䯹õÿáª™š™žºÿýŲÚ÷þôüèd"pu0/³õüûÿýïÿŽB5Rqi"€öøò÷òýɧêþÿÿüÿúüÿܱÌÿùÅ1"(6ÿðïðçíñåÎÄÖîþúüþþýüýþüýþýöçÕÇááâ ãäÃÄóÃËÑØäôþÿûýþþýýðþÿýûýÿûëÞÐÏÏÎÍÌËËÌìûèêíôÿÿîýüýÿÿþýþÿûûüýüùöôññòøùõþùõôòîðôüþÿÿîþÿÿøûýúõóô÷õõö÷÷øùùøöõ÷öøú÷ôøÿýþÿÿþþÿÿýþúùùõöòùùøø÷ööôööôøõôóôøøööùüþÿÿþþÿÿöþüùøöõôùùøøôóõû÷õö÷øùùüþÿÿþîÿúüüøóðôøóóôö÷øøùøøùøóõööôóõö÷üýÿÿþþÿ÷ý÷õ÷ùøôûúúù øùøöùúù÷ö÷øýþÿÿôþÿÿþüúø÷÷ùúùùøöùúùø÷÷øýþÿÿôþÿÿþýúø÷øùúù'ùúøùø÷øùýþÿÿôþÿÿþýûùøøùúù'ùúùùøùúýþÿÿöþÿÿþýûúùùú(úõùúûúùùúûýþÿÿøþÿÿþýüûúúûúõùúûûúúûüýþÿÿþþÿÿûþýüûúú'ûõùúûûúúûýýþÿÿþþÿÿüþýüûûþúû&ûýùúûûûüýýþÿÿþþÿÿøþýýüûûúüüûþúûûüÿþýüûüûüÿþýüû'üûüÿþýüþûü+üýÿþýüýüý ÿþýü,ýþ ÿþýüýþýþ ÿþýþüýýþýþ ÿþýÿþÿþ'ÿþÿþ'ÿþÿþÿþÿþÿþÿþÿþýÿþýÿþþýþþýÿþýÿþüÿýýÿÿýóÿþùøüÿüýÿÿýüÿÿýüþÿÿþýÿýýþÿÿñýûÿóåÙÑÎÏÒ×ãðùÿÿúùüþþüÿÿþüÿ ÿþÿÚþúüÿÿýÿÿôçÛÔÏÌÖØÝéõýÿþµ´°©¦§©©§±»ÂÑêýÿÿüþûþÿ ÿþûýÿýûÿÿÝöíÊÆ¾µ®©§¥¤ª¯µ¿Ïæ÷ÃÏÝãêïïìíÞÈ·¬±ÈßÿÿýüøÿÿþýÏÿ÷ôÿÿíÐÀ³»ÇÕâìñõïíãѽ³¶½íõûüýÿÿþûûÿþë͵«ÈåýÿýÿÿúÿÿþýóøþÿóÒ¹·Äãêóþÿÿöþÿüùöïá̾ÿÿëüúûüüùýþÿÿùåѪ¼ÜúÿûýÿÿþýìÿþéÅ­¸Ûöûýÿÿýúõòþýþÿÿåõîùöøúüûûüûûøöýÿÿûܼ²Òøÿþýÿÿþýîþÿݶ²Òôÿÿüûûúúûüüøøõùùþÿýùúÿÿíýþþûûýû÷øÿÿéÁ®ËøÿøÿÿþËýÿÓ¹¶Ûþÿûùÿþüúùùúûúùúýÿý÷ñ÷þüüùõüúüýùøø÷÷ýøÿøÄ©ÖÿûÿþÿÿÉþÿþúÿÿÞ¬¿æÿýøûø÷ÿøùýÿÿùôÿüøùùú÷óþýøøÿÿ÷ùúú÷õóõöøöúü̬ØÿÿþþÿÿØþûÿüÿÿÞ¾¶æÿùõøøúñÿøúÿñéÿÿôöþúûÿýôó÷øúüø÷÷©ûöùÿÿ÷õÿûýï½·ïÿÿþüýÿÿþÿûÿüÿõ¼®Üöÿþýûôöÿïÿÿ»{™ïÿõóýÿÿú÷ÿøùø÷ø÷ÿööþþôÕáÿõ÷ÿõüà±Îûÿÿûüÿÿýÿÿ€þײÈÿõô÷õúÿ÷ìÿó,CæÿøüþÓ•§öò÷ûùööõöûùõþâa_çÿóïóøî˯ìÿÿüüÿþüÿÿûÿîµ½ïúøûõíöýò÷ÿ‹9K5Îþñüãm2`÷óïú÷íöÿúÿþÿþJVÇÿúíöúìªÔöÿýýÿýüýÿûÿبÒÿóùöõúòíöü—0*lX ½ÿòÿìR5)ûÿíôöóÿýؽ²­©V)'B¾ûú÷ûòǶêÿýýÿýýþûÿõÁ¹ëýÿùíñúôòÿÜ6'rzO&¨ÿìäö BB$Æýûóøÿþ»G ":~_ )¬úðøóè£àÿýüÿýþÿøÿç³Ðÿøð÷ÿÿýÿÿúJEllcc3™ÿÍ?\åùª8ðïðçíñåÎÄÖîþúüþþýüýþüýþýöçÕÇááâ ãäÃÄóÃËÑØäôþÿûýþþýýðþÿýûýÿûëÞÐÏÏÎÍÌËËÌìûèêíôÿÿîýüýÿÿþýþÿûûüýüùöôññòøùõþùõôòîðôüþÿÿîþÿÿøûýúõóô÷õõö÷÷øùùøöõ÷öøú÷ôøÿýþÿÿþþÿÿýþúùùõöòùùøø÷ööôööôøõôóôøøööùüþÿÿþþÿÿöþüùøöõôùùøøôóõû÷õö÷øùùüþÿÿþîÿúüüøóðôøóóôö÷øøùøøùøóõööôóõö÷üýÿÿþþÿ÷ý÷õ÷ùøôûúúù øùøöùúù÷ö÷øýþÿÿôþÿÿþüúø÷÷ùúùùøöùúùø÷÷øýþÿÿôþÿÿþýúø÷øùúù'ùúøùø÷øùýþÿÿôþÿÿþýûùøøùúù'ùúùùøùúýþÿÿöþÿÿþýûúùùú(úõùúûúùùúûýþÿÿøþÿÿþýüûúúûúõùúûûúúûüýþÿÿþþÿÿûþýüûúú'ûõùúûûúúûýýþÿÿþþÿÿüþýüûûþúû&ûýùúûûûüýýþÿÿþþÿÿøþýýüûûúüüûþúûûüÿþýüûüûüÿþýüû'üûüÿþýüþûü+üýÿþýüýüý ÿþýü,ýþ ÿþýüýþýþ ÿþýþüýýþýþ ÿþýÿþÿþ'ÿþÿþ'ÿþÿþÿþÿþÿþÿþÿþýÿþýÿþþýþþýÿþýÿþüÿýýÿÿýóÿþùøüÿüýÿÿýüÿÿýüþÿÿþýÿýýþÿÿñýûÿóåÙÑÎÏÒ×ãðùÿÿúùüþþüÿÿþüÿ ÿþÿÚþúüÿÿýÿÿôçÛÔÏÌÖØÝéõýÿþµ´°©¦§©©§±»ÂÑêýÿÿüþûþÿ ÿþûýÿýûÿÿÝöíÊÆ¾µ®©§¥¤ª¯µ¿Ïæ÷ÃÏÝãêïïìíÞÈ·¬±ÈßÿÿýüøÿÿþýÏÿ÷ôÿÿíÐÀ³»ÇÕâìñõïíãѽ³¶½íõûüýÿÿþûûÿþë͵«ÈåýÿýÿÿúÿÿþýóøþÿóÒ¹·Äãêóþÿÿöþÿüùöïá̾ÿÿëüúûüüùýþÿÿùåѪ¼ÜúÿûýÿÿþýìÿþéÅ­¸Ûöûýÿÿýúõòþýþÿÿåõîùöøúüûûüûûøöýÿÿûܼ²Òøÿþýÿÿþýîþÿݶ²Òôÿÿüûûúúûüüøøõùùþÿýùúÿÿíýþþûûýû÷øÿÿéÁ®ËøÿøÿÿþËýÿÓ¹¶Ûþÿûùÿþüúùùúûúùúýÿý÷ñ÷þüüùõüúüýùøø÷÷ýøÿøÄ©ÖÿûÿþÿÿÉþÿþúÿÿÞ¬¿æÿýøûø÷ÿøùýÿÿùôÿüøùùú÷óþýøøÿÿ÷ùúú÷õóõöøöúü̬ØÿÿþþÿÿØþûÿüÿÿÞ¾¶æÿùõøøúñÿøúÿñéÿÿôöþúûÿýôó÷øúüø÷÷©ûöùÿÿ÷õÿûýï½·ïÿÿþüýÿÿþÿûÿüÿõ¼®Üöÿþýûôöÿïÿÿ»{™ïÿõóýÿÿú÷ÿøùø÷ø÷ÿööþþôÕáÿõ÷ÿõüà±Îûÿÿûüÿÿýÿÿ€þײÈÿõô÷õúÿ÷ìÿó,CæÿøüþÓ•§öò÷ûùööõöûùõþâa_çÿóïóøî˯ìÿÿüüÿþüÿÿûÿîµ½ïúøûõíöýò÷ÿ‹9K5Îþñüãm2`÷óïú÷íöÿúÿþÿþJVÇÿúíöúìªÔöÿýýÿýüýÿûÿبÒÿóùöõúòíöü—0*lX ½ÿòÿìR5)ûÿíôöóÿýؽ²­©V)'B¾ûú÷ûòǶêÿýýÿýýþûÿõÁ¹ëýÿùíñúôòÿÜ6'rzO&¨ÿìäö BB$Æýûóøÿþ»G ":~_ )¬úðøóè£àÿýüÿýþÿøÿç³Ðÿøð÷ÿÿýÿÿúJEllcc3™ÿÍ?\åùª8ðïðçíñåÎÄÖîþúüþþýüýþüýþýöçÕÇááâ ãäÃÄóÃËÑØäôþÿûýþþýýðþÿýûýÿûëÞÐÏÏÎÍÌËËÌìûèêíôÿÿîýüýÿÿþýþÿûûüýüùöôññòøùõþùõôòîðôüþÿÿîþÿÿøûýúõóô÷õõö÷÷øùùøöõ÷öøú÷ôøÿýþÿÿþþÿÿýþúùùõöòùùøø÷ööôööôøõôóôøøööùüþÿÿþþÿÿöþüùøöõôùùøøôóõû÷õö÷øùùüþÿÿþîÿúüüøóðôøóóôö÷øøùøøùøóõööôóõö÷üýÿÿþþÿ÷ý÷õ÷ùøôûúúù øùøöùúù÷ö÷øýþÿÿôþÿÿþüúø÷÷ùúùùøöùúùø÷÷øýþÿÿôþÿÿþýúø÷øùúù'ùúøùø÷øùýþÿÿôþÿÿþýûùøøùúù'ùúùùøùúýþÿÿöþÿÿþýûúùùú(úõùúûúùùúûýþÿÿøþÿÿþýüûúúûúõùúûûúúûüýþÿÿþþÿÿûþýüûúú'ûõùúûûúúûýýþÿÿþþÿÿüþýüûûþúû&ûýùúûûûüýýþÿÿþþÿÿøþýýüûûúüüûþúûûüÿþýüûüûüÿþýüû'üûüÿþýüþûü+üýÿþýüýüý ÿþýü,ýþ ÿþýüýþýþ ÿþýþüýýþýþ ÿþýÿþÿþ'ÿþÿþ'ÿþÿþÿþÿþÿþÿþÿþýÿþýÿþþýþþýÿþýÿþüÿýýÿÿýóÿþùøüÿüýÿÿýüÿÿýüþÿÿþýÿýýþÿÿñýûÿóåÙÑÎÏÒ×ãðùÿÿúùüþþüÿÿþüÿ ÿþÿÚþúüÿÿýÿÿôçÛÔÏÌÖØÝéõýÿþµ´°©¦§©©§±»ÂÑêýÿÿüþûþÿ ÿþûýÿýûÿÿÝöíÊÆ¾µ®©§¥¤ª¯µ¿Ïæ÷ÃÏÝãêïïìíÞÈ·¬±ÈßÿÿýüøÿÿþýÏÿ÷ôÿÿíÐÀ³»ÇÕâìñõïíãѽ³¶½íõûüýÿÿþûûÿþë͵«ÈåýÿýÿÿúÿÿþýóøþÿóÒ¹·Äãêóþÿÿöþÿüùöïá̾ÿÿëüúûüüùýþÿÿùåѪ¼ÜúÿûýÿÿþýìÿþéÅ­¸Ûöûýÿÿýúõòþýþÿÿåõîùöøúüûûüûûøöýÿÿûܼ²Òøÿþýÿÿþýîþÿݶ²Òôÿÿüûûúúûüüøøõùùþÿýùúÿÿíýþþûûýû÷øÿÿéÁ®ËøÿøÿÿþËýÿÓ¹¶Ûþÿûùÿþüúùùúûúùúýÿý÷ñ÷þüüùõüúüýùøø÷÷ýøÿøÄ©ÖÿûÿþÿÿÉþÿþúÿÿÞ¬¿æÿýøûø÷ÿøùýÿÿùôÿüøùùú÷óþýøøÿÿ÷ùúú÷õóõöøöúü̬ØÿÿþþÿÿØþûÿüÿÿÞ¾¶æÿùõøøúñÿøúÿñéÿÿôöþúûÿýôó÷øúüø÷÷©ûöùÿÿ÷õÿûýï½·ïÿÿþüýÿÿþÿûÿüÿõ¼®Üöÿþýûôöÿïÿÿ»{™ïÿõóýÿÿú÷ÿøùø÷ø÷ÿööþþôÕáÿõ÷ÿõüà±Îûÿÿûüÿÿýÿÿ€þײÈÿõô÷õúÿ÷ìÿó,CæÿøüþÓ•§öò÷ûùööõöûùõþâa_çÿóïóøî˯ìÿÿüüÿþüÿÿûÿîµ½ïúøûõíöýò÷ÿ‹9K5Îþñüãm2`÷óïú÷íöÿúÿþÿþJVÇÿúíöúìªÔöÿýýÿýüýÿûÿبÒÿóùöõúòíöü—0*lX ½ÿòÿìR5)ûÿíôöóÿýؽ²­©V)'B¾ûú÷ûòǶêÿýýÿýýþûÿõÁ¹ëýÿùíñúôòÿÜ6'rzO&¨ÿìäö BB$Æýûóøÿþ»G ":~_ )¬úðøóè£àÿýüÿýþÿøÿç³Ðÿøð÷ÿÿýÿÿúJEllcc3™ÿÍ?\åùª8ÿ÷ßãáÖËÐæùÿÿþîÿþýüýûîÜÍÏ×ßâààäéããöíéãÚÑÑßìþýýþþÿÿøÏÌÊÒáòüÿÿþÿþÿôùòÐÔÕÑÌÉÉÌÊË ËöÃÄÉÎÔÝíüüýýþþÿÿ÷îëêïõúúùþþüÿþþÿÿõþüîððîíîñôòòíùïòóõüÿüüýýþÿÿöúýÿüõïïñýþþÿþïüýþýùõðîø÷öõ÷øúüùùòþúø÷ôïîðúûüýþÿÿòöóôõõööüýþÿÿþõûþÿýùôòðùø÷÷ýöõö öòõøõô÷ø÷öøùúüýÿÿôùø÷ö÷øøùûüýÿÿþðÿþû÷õ÷ùñòôõö÷öõøøóùõô÷ù÷÷ùøùûýÿÿô÷ùúøõòöøúûýÿÿþÿøýùõô÷úøùùûø÷ööøøóú÷öøù÷öø÷ùûþÿÿôø÷÷øúúøõúûýÿÿíþýýþþûùøùûøùúúùùúûøøóù÷÷úú÷õö÷øûþÿÿùýûýÿÿþÿúûøùùöùù÷üùûýÿÿùýûýÿÿþÿúûøùùøùùøüùûýÿÿùýûýÿÿþ÷ýÿÿûøùúøùùûøùûýÿÿúýûýÿÿþøýÿÿûùúúùùúûùúüþÿÿûþýÿÿþøýÿÿûùúûúúûúüûüþÿÿûþýÿÿþøýÿÿûùûüúúûüúûýÿÿþþûûþýÿÿþ÷ýÿÿûúûüûúúûúüûüýÿÿþþüüýûýÿÿþ÷ýÿÿüúûüûúúüúüûüþÿÿþþüüýýþÿÿýþüû ûüýþþÿÿüýýþÿÿüþüüû ûüýþþÿÿüýýþÿÿüþýüûû üýþþÿÿüýýþÿÿýþýü#üýþþÿÿýþþÿÿûþýüüý ýûüýýþÿÿýþþÿÿþþýýþþýýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿþÿþÿþÿþÿþÿþhÿþþÿÿüþýþÿ7ÿþþÿÿþ9ÿþÿ þ/ÿøþýýÿÿþýþ þ-ÿøþýýÿÿþýþ þ+ÿþþýýþþýþ þ*ÿþýþþýþþýýþ*ÿ÷üþÿþýüýþýýþ ÿþÿþþÿÿýÿüûüþÿÿôüþÿÿþúøüýüþÿ ÿûúýÿÿýþÿÿ÷þÿüþÿÿüüÿÿóøðçàØÓÂËØãìõÿÿúýüüýþÿ ÿùþûþÿÿûÿ ÿþþýýÿþÿúîÞų«©©îª¬­­±½ÎÛøÿÿûüÿÿùþÿÿ÷â÷ÿÿþÿÿûÿ ÿÛþýüüÿÿþýÿÿìÕ¯³»È×äíðõïåÛϵ¬ÂÜøÿÿüýÿþþÿ÷¨Æìÿÿøøþÿ ÿÛþýüüÿöøÿùÕ¸²ÎÙêøþüùöþüüÿÿõâÔ¼´Áåýþûÿþþÿ÷ʵ³ÒôÿþÿþþÿçþýýûþüêÆ°¾Úùþÿÿýûýÿþüûüþÿÿ÷íд·ØøÿüþþÿøÜ´±ÒõÿÿþþÿÝþüúæÂ³ÊîÿûüýýûûýÿýþþüùøûýÿÿìŶËíÿýþþÿ÷øÿñ¿¯Ò÷ÿþþÿ÷Þ³±×ÿÿ÷úùùúëùøúýÿÿüùøøúüÿïʱÈïþýþþÿúÝÿ÷ϯÅöÿÿúÿÿþÿüÿüÿÿýþÿÿè·µæÿúõùüúûþÿÿ¾öÿð÷÷ôùùüý÷üüðνÄýÿúöþûÿÿûøûøñÐ³Îøÿøþÿøÿýÿþþÿûÿÿ껸Þÿ÷ðúöõøÿñýÿéòÿÿûúÿýêöñüÿú̱ÖÿÿùþþýÿúñùûÿﺷâÿùüÿôÿÿþÿüþüÿúưÎúÿóôþôÿõòÿû­f¯ñóöÿÿôïìøôøÿôÿý½³çÿûýþüÿþõøøþþݹÄ÷ÿûûùÿÿ€/þýûÿÿÞ°Ëñÿ÷øú÷÷ÿ÷ÿê}!XüõåÛÕÔæ÷èÿÿýîí÷ì·Æðþùýÿÿáÿúò÷þøÊ®Ûÿûøÿûÿÿüÿúÿ÷À³èýÿùúôïø÷ÿërF:dÕÉÅÏÛÜÖζõÿóãèøùÙ¯Óÿúúÿÿƒôÿöøòýî²Âúþöÿúýÿýÿüÿá±Êþôøûôñööúüv6]{osæÔÒÆ»ÂÏâÆªÊýôÛêÿù²¼öÿûÿÿ'ÅÿúúïúÿδáÿùÿýüþÿûÿøÄ¹çÿðñ÷ôöý÷ô©F¼öîÑßéòÿðãÅÉÍËéÿïåÿϳÚÿþüÿ›î÷úøøôé°Íÿüùÿüûÿõÿî±ÆùòøüýÿýüÿØ13yq”ìÿÁÄþýéñôÿÿÖ×ÐÒù÷ßÿí²Àþþùÿ÷ßãáÖËÐæùÿÿþîÿþýüýûîÜÍÏ×ßâààäéããöíéãÚÑÑßìþýýþþÿÿøÏÌÊÒáòüÿÿþÿþÿôùòÐÔÕÑÌÉÉÌÊË ËöÃÄÉÎÔÝíüüýýþþÿÿ÷îëêïõúúùþþüÿþþÿÿõþüîððîíîñôòòíùïòóõüÿüüýýþÿÿöúýÿüõïïñýþþÿþïüýþýùõðîø÷öõ÷øúüùùòþúø÷ôïîðúûüýþÿÿòöóôõõööüýþÿÿþõûþÿýùôòðùø÷÷ýöõö öòõøõô÷ø÷öøùúüýÿÿôùø÷ö÷øøùûüýÿÿþðÿþû÷õ÷ùñòôõö÷öõøøóùõô÷ù÷÷ùøùûýÿÿô÷ùúøõòöøúûýÿÿþÿøýùõô÷úøùùûø÷ööøøóú÷öøù÷öø÷ùûþÿÿôø÷÷øúúøõúûýÿÿíþýýþþûùøùûøùúúùùúûøøóù÷÷úú÷õö÷øûþÿÿùýûýÿÿþÿúûøùùöùù÷üùûýÿÿùýûýÿÿþÿúûøùùøùùøüùûýÿÿùýûýÿÿþ÷ýÿÿûøùúøùùûøùûýÿÿúýûýÿÿþøýÿÿûùúúùùúûùúüþÿÿûþýÿÿþøýÿÿûùúûúúûúüûüþÿÿûþýÿÿþøýÿÿûùûüúúûüúûýÿÿþþûûþýÿÿþ÷ýÿÿûúûüûúúûúüûüýÿÿþþüüýûýÿÿþ÷ýÿÿüúûüûúúüúüûüþÿÿþþüüýýþÿÿýþüû ûüýþþÿÿüýýþÿÿüþüüû ûüýþþÿÿüýýþÿÿüþýüûû üýþþÿÿüýýþÿÿýþýü#üýþþÿÿýþþÿÿûþýüüý ýûüýýþÿÿýþþÿÿþþýýþþýýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿþÿþÿþÿþÿþÿþhÿþþÿÿüþýþÿ7ÿþþÿÿþ9ÿþÿ þ/ÿøþýýÿÿþýþ þ-ÿøþýýÿÿþýþ þ+ÿþþýýþþýþ þ*ÿþýþþýþþýýþ*ÿ÷üþÿþýüýþýýþ ÿþÿþþÿÿýÿüûüþÿÿôüþÿÿþúøüýüþÿ ÿûúýÿÿýþÿÿ÷þÿüþÿÿüüÿÿóøðçàØÓÂËØãìõÿÿúýüüýþÿ ÿùþûþÿÿûÿ ÿþþýýÿþÿúîÞų«©©îª¬­­±½ÎÛøÿÿûüÿÿùþÿÿ÷â÷ÿÿþÿÿûÿ ÿÛþýüüÿÿþýÿÿìÕ¯³»È×äíðõïåÛϵ¬ÂÜøÿÿüýÿþþÿ÷¨Æìÿÿøøþÿ ÿÛþýüüÿöøÿùÕ¸²ÎÙêøþüùöþüüÿÿõâÔ¼´Áåýþûÿþþÿ÷ʵ³ÒôÿþÿþþÿçþýýûþüêÆ°¾Úùþÿÿýûýÿþüûüþÿÿ÷íд·ØøÿüþþÿøÜ´±ÒõÿÿþþÿÝþüúæÂ³ÊîÿûüýýûûýÿýþþüùøûýÿÿìŶËíÿýþþÿ÷øÿñ¿¯Ò÷ÿþþÿ÷Þ³±×ÿÿ÷úùùúëùøúýÿÿüùøøúüÿïʱÈïþýþþÿú€Íÿ÷ϯÅöÿÿúÿÿþÿüÿüÿÿýþÿÿæ¶³çÿü÷ûÿûúúûûÿóùîøüüÿþÿùøÿÿöθ¿ôþøùÿýþþûøûøñÐ³Îøÿøþÿøÿýÿþþÿûÿÿê¹¶Ýÿ÷óýøôøÿðûÿêõÿüýýøùÿÿøÿõýÿöȰÌùÿûÿÿûýúñùûÿﺷâÿùüÿôÿÿþÿüþüÿúÆ®Ìøÿóöÿõþòòÿÿ²o·ÿÿüûüõõöÿû÷ùðÿü½©áÿýÿÿúýþõøøþþݹÄ÷ÿûûùÿÿ€þýûÿÿÞ°Éïþ÷øýùùúöÿî&[üì͵¨¨¿ÔÙöüú÷øûæ®Áîÿûÿýþáÿúò÷þøÊ®Ûÿûøÿûÿÿüÿúÿ÷À³æûÿùúöñúõÿës>-RŒzhhkg]Tx½åïøÿÿíЩÒÿüüþþƒôÿöøòýî²Âúþöÿúýÿýÿüÿá±Êüòöüôóøøüÿw4O_EDrrgWW^frW‡àþôõüךּøÿýþü'ÅÿúúïúÿδáÿùÿýüþÿûÿøÄ¹çÿîï÷óøþùý±=rMw¥˜‹±ÏßèȲ}soƒÎÿûìüɲÜÿÿúû›î÷úøøôé°Íÿüùÿüûÿõÿî±Æùïöúýÿÿþÿå<4oPT“œdãÿÿîûÿÓcg”êÿñýæ°Âÿÿöþ÷ßãáÖËÐæùÿÿþîÿþýüýûîÜÍÏ×ßâààäéããöíéãÚÑÑßìþýýþþÿÿøÏÌÊÒáòüÿÿþÿþÿôùòÐÔÕÑÌÉÉÌÊË ËöÃÄÉÎÔÝíüüýýþþÿÿ÷îëêïõúúùþþüÿþþÿÿõþüîððîíîñôòòíùïòóõüÿüüýýþÿÿöúýÿüõïïñýþþÿþïüýþýùõðîø÷öõ÷øúüùùòþúø÷ôïîðúûüýþÿÿòöóôõõööüýþÿÿþõûþÿýùôòðùø÷÷ýöõö öòõøõô÷ø÷öøùúüýÿÿôùø÷ö÷øøùûüýÿÿþðÿþû÷õ÷ùñòôõö÷öõøøóùõô÷ù÷÷ùøùûýÿÿô÷ùúøõòöøúûýÿÿþÿøýùõô÷úøùùûø÷ööøøóú÷öøù÷öø÷ùûþÿÿôø÷÷øúúøõúûýÿÿíþýýþþûùøùûøùúúùùúûøøóù÷÷úú÷õö÷øûþÿÿùýûýÿÿþÿúûøùùöùù÷üùûýÿÿùýûýÿÿþÿúûøùùøùùøüùûýÿÿùýûýÿÿþ÷ýÿÿûøùúøùùûøùûýÿÿúýûýÿÿþøýÿÿûùúúùùúûùúüþÿÿûþýÿÿþøýÿÿûùúûúúûúüûüþÿÿûþýÿÿþøýÿÿûùûüúúûüúûýÿÿþþûûþýÿÿþ÷ýÿÿûúûüûúúûúüûüýÿÿþþüüýûýÿÿþ÷ýÿÿüúûüûúúüúüûüþÿÿþþüüýýþÿÿýþüû ûüýþþÿÿüýýþÿÿüþüüû ûüýþþÿÿüýýþÿÿüþýüûû üýþþÿÿüýýþÿÿýþýü#üýþþÿÿýþþÿÿûþýüüý ýûüýýþÿÿýþþÿÿþþýýþþýýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿýþþÿÿþý þýûüýýþÿÿþÿþÿþÿþÿþÿþhÿþþÿÿüþýþÿ7ÿþþÿÿþ9ÿþÿ þ/ÿøþýýÿÿþýþ þ-ÿøþýýÿÿþýþ þ+ÿþþýýþþýþ þ*ÿþýþþýþþýýþ*ÿ÷üþÿþýüýþýýþ ÿþÿþþÿÿýÿüûüþÿÿôüþÿÿþúøüýüþÿ ÿûúýÿÿýþÿÿ÷þÿüþÿÿüüÿÿóøðçàØÓÂËØãìõÿÿúýüüýþÿ ÿùþûþÿÿûÿ ÿþþýýÿþÿúîÞų«©©îª¬­­±½ÎÛøÿÿûüÿÿùþÿÿ÷â÷ÿÿþÿÿûÿ ÿÛþýüüÿÿþýÿÿìÕ¯³»È×äíðõïåÛϵ¬ÂÜøÿÿüýÿþþÿ÷¨Æìÿÿøøþÿ ÿÛþýüüÿöøÿùÕ¸²ÎÙêøþüùöþüüÿÿõâÔ¼´Áåýþûÿþþÿ÷ʵ³ÒôÿþÿþþÿçþýýûþüêÆ°¾Úùþÿÿýûýÿþüûüþÿÿ÷íд·ØøÿüþþÿøÜ´±ÒõÿÿþþÿÝþüúæÂ³ÊîÿûüýýûûýÿýþþüùøûýÿÿìŶËíÿýþþÿ÷øÿñ¿¯Ò÷ÿþþÿ÷Þ³±×ÿÿ÷úùùúëùøúýÿÿüùøøúýÿïʱÈïþýþþÿúÖÿ÷ϯÅöÿÿúÿÿþÿüÿüÿÿýþÿÿç¶´æÿûöúÿýøùûüÿùõïüÿÿÃøóïïøüñμÃ÷ÿùøÿüÿÿûøûøñÐ³Îøÿøþÿøÿýÿþþÿûÿÿ꺷Ýÿ÷ñü÷÷øÿîüÿîûÿþÿÿÁðý÷þÿõÅ«ÏûÿúÿÿüþúñùûÿﺷâÿùüÿôÿÿþÿüþüÿúƯÍùÿóõÿôüóòÿÿµqºüöíðóôÿÿâûýÿøÿö°­ãÿüþÿûþþõøøþþݹÄ÷ÿûûùÿÿÞþýûÿÿÞ°Êðÿ÷øûøøùôÿñ„'ZïÚ±•Š•¹×Ðôÿÿú€õã±Ãïÿúþþÿáÿúò÷þøÊ®Ûÿûøÿûÿÿüÿúÿ÷À³çüÿùúõðùóÿíw<'LhOGILLKi±ßë÷ÿÿüÓ«Óÿûûÿÿƒôÿöøòýî²Âúþöÿúýÿýÿüÿá±Êýó÷üôò÷÷ûÿ{7O[92jZXH7:BNYBwÐïìÿÿò®»÷ÿüÿý'ÅÿúúïúÿδáÿùÿýüþÿûÿøÄ¹çÿïð÷ô÷þøü³@qDd‰vlš¹ÌÕ±›a\Zmµô÷õþ˲Ûÿÿûü›î÷úøøôé°Íÿüùÿüûÿõÿî±Æùñ÷ûýÿþýÿå=9sOI}BjÙÿÿî÷û³hQQxÐóëÿè±Áÿÿøÿÿ ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3ÿýËÿƵìûöôõôòó÷ç pliggqi<B–áÿÿöððýòöõøïûì½¹ùÿûûÿüÿûÿÿÌÿÿýøüúýñúõôôÔòó÷îhdfgflhyi5J¡àÿÿîôõòçôôüñƸóÿüüÿýÿüÿúÅÿÿÈýþþî¼Æõõòñóòñòöíggkjddhan{^0.N¡áÿÿåôúòöúöѶèÿþýÿýÿþÿòºÿÿÒüþÿå³Íóõóñôôñò÷àadc`_`WcaWbpW(#^±öü÷îòððõÙ²Þÿÿùþÿÿþè²ÿÿÒýþÿß®ÏëçååççåæéÒX^XV^e]YXZ\]bkS8!^ºóèßçäíÙ¯×ÿÿùþÿÿþâ­ÿÿþÓýÿß«ÑåÝÛÛÝÝÛÛÞÕWa\X^ae_\_^\]b[gO•éãáàçØ®ÕÿÿüþÞ¯ÿÿÑýÿüÿá®ÕâçääçåââåÙ;BA??7?;;>BB><@>8îêááä×±×ÿÿúþÿþÞ³ÿÿÇýÿúÿã±ØäæääæåâáãØ   5˜æåÙäææ×´ÙÿýÿþÿþÿþÞ¸ÿÿõþüÿæ»ÉæääãââïáãÛ è<ÏôíÛáããê̱Üÿûþÿþÿýÿò³ÿÿÇüûûÿâêãäèãäèåÚ -…Æóïäââæêàéóêÿüþÿýÿýÿõ¼ÿÿûÉúÿû­áïáåêâåìæÐ "%&#!&}Áéìíèääææéä軼øÿþþÿüÿýÿùÊÿÿþÉùüÿÔ®ÚîääæãäèèÝ ")&( ,,$ qÊåíóÛ×ççßäìæí߸ÎþýÿþþüþüÿþÜÿÿÇþÿúøÿæ¶ÃéìèäçååíÐ *.19.0 eÓøìéïëãéíæåèåéòÉ·äÿüÿþýüþüÿÿëÿÿÇüÿýûÿóƬÛîïçêéæñØ#))# \¾òæäèâåéâäååëêßñæµ¾õÿþþÿüýþûÿÿøÿÿýûýÿÿÌüâ¯ÇäòëéêéìÙ!'_ÁîëíèâéíäêæèëåáèñíÈ´ÖþÿýÿÿûýþûýÿþÿÿÈýûÿÿûÿúÀµØòíãçêåâ R®éõðèáêôéâñêëêéëíñõ⯾ïÿýùÿÿûþþûüþÿÿÏþüÿÿþÿùì²¼àøñìïéé{L™ñÿôäåñôêâãæäéíìçèîî뿵ßþúþþùÿÿüÕûÿÿøË¶ÂæñèéíûùÿÿôäåíëëéçìôóìçîíéíôèÔµÌóÿûýÿÿþýüüÿ×øÌ´ËíöïêçðîäåîñîííìëëìêçðëèðüôÒ¯½íÿÿüüÿÿþþÿÖýÿîÄ­ÄæñîöòêìöóçèêíòóïììïòîóüîϹ¶àÿÿûýüÿýþþÿþþÿÿçýûüûÿì¾­½Ý÷ôõññôíêóíêêíðññïóöùéè¿çüÿúýÿûÿüþþÿÏþÿýýÿýüÿúÿÿòд¼ÛóúôéëôóíòñðîïóöøüíÕ¼µÆçÿÿúùÿÿûþÿþþ ÿÒüýÿþýÿüûþÿõÖ½¹·Öôúóò÷õóøúööøøóâϸ¸Õ÷ÿýûúþýýÿýÿÿþþÿÿàûÿÿþúùÿÿèÆº®¼ÜéìòöùöñïóðÙ¿ª´ÆßôÿÿøúÿÿôùÿüÿÿûýüüýÿÿçþàÍ·ªª³ÀÌÊÌÊÀ³¬±¹ÊáùÿÿúüÿÿçþýüþÿÿþýÿöèÜÑŽºµµ¶»ÂÏÝåÿÿûüúúûÿÿ÷þýýþÿÿþýÿÿõüðåßââåëôýÿÿýÿýþüÿÿþÿåþýøõõùú÷õõðôö÷ôóôöøûþÿÿþýüÿÿþþÿÿåþüüûûöòñðîðò÷÷õòððóöøûþþýýÿ ÿùþÿÿþûùøøõíøú÷÷úû÷ôô÷øöôôõöùüÿ!ÿßþÿÿýùöõõòñóö÷õôöôôõøüýùöõôô÷úûùõÿÿßþÿÿüøôóóúöôõóòó÷ö÷øõððõûõôôõ÷úûüÿÿþþÿÿøýùõôõøú÷÷þýÿÿýÿþþÿÿ÷ýûøöõöøúøøùüýÿÿþþÿÿýúù÷÷üøùúøøùùûýþÿþÿÿþøû÷ùüþÿÿþþýùùüø÷öùùû÷øûýÿÿûþýüùúúüø÷öúúûøùúüÿÿùþýüüùùúúùúýüþÿÿ÷þýüüøøùúûûúúüûúûþÿÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿÿ!ýþÿ ýþÿýþÿ#þÿ"þ<ÿþþÿŽÿÿýËÿƵìûöôõôòó÷ç pliggqi<B–áÿÿöððýòöõøïûì½¹ùÿûûÿüÿûÿÿÌÿÿýøüúýñúõôôÔòó÷îhdfgflhyi5J¡àÿÿîôõòçôôüñƸóÿüüÿýÿüÿúÅÿÿÈýþþî¼Æõõòñóòñòöíggkjddhan{^0.N¡áÿÿåôúòöúöѶèÿþýÿýÿþÿòºÿÿÒüþÿå³Íóõóñôôñò÷àadc`_`WcaWbpW(#^±öü÷îòððõÙ²Þÿÿùþÿÿþè²ÿÿÒýþÿß®ÏëçååççåæéÒX^XV^e]YXZ\]bkS8!^ºóèßçäíÙ¯×ÿÿùþÿÿþâ­ÿÿþÓýÿß«ÑåÝÛÛÝÝÛÛÞÕWa\X^ae_\_^\]b[gO•éãáàçØ®ÕÿÿüþÞ¯ÿÿÑýÿüÿá®ÕâçääçåââåÙ;BA??7?;;>BB><@>8îêááä×±×ÿÿúþÿþÞ³ÿÿÇýÿúÿã±ØäæääæåâáãØ   5˜æåÙäææ×´ÙÿýÿþÿþÿþÞ¸ÿÿõþüÿæ»ÉæääãââïáãÛ è<ÏôíÛáããê̱Üÿûþÿþÿýÿò³ÿÿÇüûûÿâêãäèãäèåÚ -…Æóïäââæêàéóêÿüþÿýÿýÿõ¼ÿÿûÉúÿû­áïáåêâåìæÐ "%&#!&}Áéìíèääææéä軼øÿþþÿüÿýÿùÊÿÿþÉùüÿÔ®ÚîääæãäèèÝ ")&( ,,$ qÊåíóÛ×ççßäìæí߸ÎþýÿþþüþüÿþÜÿÿÇþÿúøÿæ¶ÃéìèäçååíÐ *.19.0 eÓøìéïëãéíæåèåéòÉ·äÿüÿþýüþüÿÿëÿÿÇüÿýûÿóƬÛîïçêéæñØ#))# \¾òæäèâåéâäååëêßñæµ¾õÿþþÿüýþûÿÿøÿÿýûýÿÿÌüâ¯ÇäòëéêéìÙ!'_ÁîëíèâéíäêæèëåáèñíÈ´ÖþÿýÿÿûýþûýÿþÿÿÈýûÿÿûÿúÀµØòíãçêåâ R®éõðèáêôéâñêëêéëíñõ⯾ïÿýùÿÿûþþûüþÿÿÏþüÿÿþÿùì²¼àøñìïéé{L™ñÿôäåñôêâãæäéíìçèîî뿵ßþúþþùÿÿüÕûÿÿøË¶ÂæñèéíûùÿÿôäåíëëéçìôóìçîíéíôèÔµÌóÿûýÿÿþýüüÿ×øÌ´ËíöïêçðîäåîñîííìëëìêçðëèðüôÒ¯½íÿÿüüÿÿþþÿÖýÿîÄ­ÄæñîöòêìöóçèêíòóïììïòîóüîϹ¶àÿÿûýüÿýþþÿþþÿÿçýûüûÿì¾­½Ý÷ôõññôíêóíêêíðññïóöùéè¿çüÿúýÿûÿüþþÿÏþÿýýÿýüÿúÿÿòд¼ÛóúôéëôóíòñðîïóöøüíÕ¼µÆçÿÿúùÿÿûþÿþþ ÿÒüýÿþýÿüûþÿõÖ½¹·Öôúóò÷õóøúööøøóâϸ¸Õ÷ÿýûúþýýÿýÿÿþþÿÿàûÿÿþúùÿÿèÆº®¼ÜéìòöùöñïóðÙ¿ª´ÆßôÿÿøúÿÿôùÿüÿÿûýüüýÿÿçþàÍ·ªª³ÀÌÊÌÊÀ³¬±¹ÊáùÿÿúüÿÿçþýüþÿÿþýÿöèÜÑŽºµµ¶»ÂÏÝåÿÿûüúúûÿÿ÷þýýþÿÿþýÿÿõüðåßââåëôýÿÿýÿýþüÿÿþÿåþýøõõùú÷õõðôö÷ôóôöøûþÿÿþýüÿÿþþÿÿåþüüûûöòñðîðò÷÷õòððóöøûþþýýÿ ÿùþÿÿþûùøøõíøú÷÷úû÷ôô÷øöôôõöùüÿ!ÿßþÿÿýùöõõòñóö÷õôöôôõøüýùöõôô÷úûùõÿÿßþÿÿüøôóóúöôõóòó÷ö÷øõððõûõôôõ÷úûüÿÿþþÿÿøýùõôõøú÷÷þýÿÿýÿþþÿÿ÷ýûøöõöøúøøùüýÿÿþþÿÿýúù÷÷üøùúøøùùûýþÿþÿÿþøû÷ùüþÿÿþþýùùüø÷öùùû÷øûýÿÿûþýüùúúüø÷öúúûøùúüÿÿùþýüüùùúúùúýüþÿÿ÷þýüüøøùúûûúúüûúûþÿÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿÿ!ýþÿ ýþÿýþÿ#þÿ"þ<ÿþþÿŽÿÿýËÿƵìûöôõôòó÷ç pliggqi<B–áÿÿöððýòöõøïûì½¹ùÿûûÿüÿûÿÿÌÿÿýøüúýñúõôôÔòó÷îhdfgflhyi5J¡àÿÿîôõòçôôüñƸóÿüüÿýÿüÿúÅÿÿÈýþþî¼Æõõòñóòñòöíggkjddhan{^0.N¡áÿÿåôúòöúöѶèÿþýÿýÿþÿòºÿÿÒüþÿå³Íóõóñôôñò÷àadc`_`WcaWbpW(#^±öü÷îòððõÙ²Þÿÿùþÿÿþè²ÿÿÒýþÿß®ÏëçååççåæéÒX^XV^e]YXZ\]bkS8!^ºóèßçäíÙ¯×ÿÿùþÿÿþâ­ÿÿþÓýÿß«ÑåÝÛÛÝÝÛÛÞÕWa\X^ae_\_^\]b[gO•éãáàçØ®ÕÿÿüþÞ¯ÿÿÑýÿüÿá®ÕâçääçåââåÙ;BA??7?;;>BB><@>8îêááä×±×ÿÿúþÿþÞ³ÿÿÇýÿúÿã±ØäæääæåâáãØ   5˜æåÙäææ×´ÙÿýÿþÿþÿþÞ¸ÿÿõþüÿæ»ÉæääãââïáãÛ è<ÏôíÛáããê̱Üÿûþÿþÿýÿò³ÿÿÇüûûÿâêãäèãäèåÚ -…Æóïäââæêàéóêÿüþÿýÿýÿõ¼ÿÿûÉúÿû­áïáåêâåìæÐ "%&#!&}Áéìíèääææéä軼øÿþþÿüÿýÿùÊÿÿþÉùüÿÔ®ÚîääæãäèèÝ ")&( ,,$ qÊåíóÛ×ççßäìæí߸ÎþýÿþþüþüÿþÜÿÿÇþÿúøÿæ¶ÃéìèäçååíÐ *.19.0 eÓøìéïëãéíæåèåéòÉ·äÿüÿþýüþüÿÿëÿÿÇüÿýûÿóƬÛîïçêéæñØ#))# \¾òæäèâåéâäååëêßñæµ¾õÿþþÿüýþûÿÿøÿÿýûýÿÿÌüâ¯ÇäòëéêéìÙ!'_ÁîëíèâéíäêæèëåáèñíÈ´ÖþÿýÿÿûýþûýÿþÿÿÈýûÿÿûÿúÀµØòíãçêåâ R®éõðèáêôéâñêëêéëíñõ⯾ïÿýùÿÿûþþûüþÿÿÏþüÿÿþÿùì²¼àøñìïéé{L™ñÿôäåñôêâãæäéíìçèîî뿵ßþúþþùÿÿüÕûÿÿøË¶ÂæñèéíûùÿÿôäåíëëéçìôóìçîíéíôèÔµÌóÿûýÿÿþýüüÿ×øÌ´ËíöïêçðîäåîñîííìëëìêçðëèðüôÒ¯½íÿÿüüÿÿþþÿÖýÿîÄ­ÄæñîöòêìöóçèêíòóïììïòîóüîϹ¶àÿÿûýüÿýþþÿþþÿÿçýûüûÿì¾­½Ý÷ôõññôíêóíêêíðññïóöùéè¿çüÿúýÿûÿüþþÿÏþÿýýÿýüÿúÿÿòд¼ÛóúôéëôóíòñðîïóöøüíÕ¼µÆçÿÿúùÿÿûþÿþþ ÿÒüýÿþýÿüûþÿõÖ½¹·Öôúóò÷õóøúööøøóâϸ¸Õ÷ÿýûúþýýÿýÿÿþþÿÿàûÿÿþúùÿÿèÆº®¼ÜéìòöùöñïóðÙ¿ª´ÆßôÿÿøúÿÿôùÿüÿÿûýüüýÿÿçþàÍ·ªª³ÀÌÊÌÊÀ³¬±¹ÊáùÿÿúüÿÿçþýüþÿÿþýÿöèÜÑŽºµµ¶»ÂÏÝåÿÿûüúúûÿÿ÷þýýþÿÿþýÿÿõüðåßââåëôýÿÿýÿýþüÿÿþÿåþýøõõùú÷õõðôö÷ôóôöøûþÿÿþýüÿÿþþÿÿåþüüûûöòñðîðò÷÷õòððóöøûþþýýÿ ÿùþÿÿþûùøøõíøú÷÷úû÷ôô÷øöôôõöùüÿ!ÿßþÿÿýùöõõòñóö÷õôöôôõøüýùöõôô÷úûùõÿÿßþÿÿüøôóóúöôõóòó÷ö÷øõððõûõôôõ÷úûüÿÿþþÿÿøýùõôõøú÷÷þýÿÿýÿþþÿÿ÷ýûøöõöøúøøùüýÿÿþþÿÿýúù÷÷üøùúøøùùûýþÿþÿÿþøû÷ùüþÿÿþþýùùüø÷öùùû÷øûýÿÿûþýüùúúüø÷öúúûøùúüÿÿùþýüüùùúúùúýüþÿÿ÷þýüüøøùúûûúúüûúûþÿÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿüþýüû!ûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿ ÿûþýüûüüûûüýþþÿÿýþýÿÿ!ýþÿ ýþÿýþÿ#þÿ"þ<ÿþþÿŽÿÿù®éôòöñôô€Øöt9edlR>Çüÿ¤#Yjdtº÷íôïööóõë»·ùýÿûþúÿÿÖ¦ßóòõòòôúüž*Wpej½ñøôöðòñ÷÷xÇüÿ¤#Yjdtº÷íôïööóõë»·ùýÿûþúÿÿÖ¦ßóòõòòôúüž*Wpej½ñøôöðòñ÷÷xÇüÿ¤#Yjdtº÷íôïööóõë»·ùýÿûþúÿÿÖ¦ßóòõòòôúüž*Wpej½ñøôöðòñ÷÷x5xõÀ+Uz]8-nÕýÿý„8ŽggÇfd#§ÿí÷ðòôò÷óϬãÿþþÿýÿýâ¯Ö÷ïöïÿ­[ssi8(]r&SiltK&Jžñÿ†<…kkïjd*°ÿòøðõô÷øùà°ÚÿÿÛüÿúÒ´äûë÷öÿ±`p_nlOJhs]gl\B)bÖŸ .‹\\Ç_W#¬ÿîóïòíóñ÷è°Ñýÿÿþûÿúƹí÷æóòþ¯S^Tafap,\jUNZeaE)@9"?…``ÇdT ¥óÞåæåßäáêãªÄúÿþþûÿû¿¸éêßêäð¨ Te]][[kD!R`eh\_Xs`6<~FFÇJ?¨õÝáãâÞÞÜåß®Äùÿüÿúÿþ½¸çåáæÝë¨@K<>JKJ(EDAD?LE57¥Ýýò{~+*)('&&Â,­ÿääìßêáëãµ¼óÿþþüÿúÿö±ºóçåàò²0*Ûÿ¼'oÔùòéé…‚Ç!­õáÜßæçæïÒ­ÍüÿýÿüÿùÿúÑ©Þëìæö¯  [Èöðÿ¦ B­îçáÙçÿ “€‚„„|„žßøîíìèçîêÀ²âÿÿüÿüÿùþúã¯ÊÞìðø­.•çõÝÝÿ¾ åëêâóèåê|’çç¾èéêëèêììãáçæéëîÖ´Êùÿþüÿúÿüÿý÷þãöÝéæÅÒð÷êéçææÄÔêïåìçßêêôÊ’ºôëëéèçææêãìëåéìêìðêıáÿ÷ýüÿøÿþÿÿÉÛ¥¼ôîéêæõèÚïíÛðìåíçìçéèçõäèëäñçæèêêéèéëæëîèæééæîôÉ®×üýÿÿþýìÿûбÏðïèñãâééëîëêëìíí÷ëðëâçóôëîîííîñòìæäêîîïôõÕ´ÂíþûÿÿþÝýüþëÀ¯×úóçèíñìéêéííììëêééñåäïóìéðìëëììííìîíïòîêí÷Û·µàÿÿüÿÿþïüÿÿÞ­·áððñíêíîëéííîßçåìõðçíüììíïñðíëòñïìïòêÞ²»ÚüÿþýýÿÿþÿòûÙ±´ÓôöíåìðïòííÛîïðòñõðçéôñçðïïðññïííëëóýõÓ¯µÝýÿþÿÿþÿÿþÊÿþúÿÿÖ³·ÛðúôñëçìðïïîíìëëîïìðüüÛ´õòïìîïñòñöüöÞÄ·¶äýÿûüÿÿþËÿúøÿÿã¼²ÈãõýúñíòóóôôóòñïðùüèÇ´´ù÷öôóôõøøõçα­Ëíÿÿþúþÿ ÿêýþþøûÿÿâ·²ºÏåöýúñòõ÷ù÷÷ßüõëÖ¶¦¿ãñóö÷õòñðàγª¾áøþûúýÿþýüûÿÿÎüýÿÿþùüÿøÕ¶¬°ÈãððñóõóòïíáÔº§µÝùÿÀÄÉÌÈ¿µ­¨²ÆÜðüÿÿýþþ ÿýþÿþÿìòÙ¿®¨ª¾¿ÅÊʼº§®¾Øòÿÿᄎ¶²´¼ÅÊÞæñúýýþÿþþÿþÞøýÿÿ÷æÖÎý¹º»½ÃÉØáíúÿÿþùêæáÞàèóùüÿÿþÿþÿþþÿÿóûöíæßÛÝäï÷üþÿÿüþÿÿööõõôøööùýÿÿþÿÿþÿöü÷õöø÷öôòððòòô÷òöûýüüþÿõö÷÷öøôòôøüþýÿÿþÿúýûøõóòòýöøûûýù÷õõúö÷úýÿôôõõ÷øøö÷÷öõöúþþ ÿüüýþÿÿþùÙøöõõøüö÷÷õõ÷ø÷ÿúóñòøýÿö÷øùùøööõö÷õóô÷úþþ ÿýýþÿÿéýûùñô÷ùûùöõö÷öòòöøöôõ÷ùùþ÷öö÷öõõû÷ôôö÷öôýþþ ÿþþÿÿäûøöû÷ôôõõóðõúû÷÷øöòõøúùõõöù÷÷ùõøüÿÿþÿ ÿûû÷õõöö÷øú÷ùûýþÿ ÿúþú÷ööøøöøùüúûýÿ ÿþüýûùøøùøöøúûùøúüÿ ÿøþýûùøøùúúøù÷üúøùüþÿþÿÿ÷þüúøøùúûùùú÷ûúùúûýþþÿÿ÷þüúùùúûûùùú÷úýùúûûýýþÿÿüýúúûûþúùùú÷úýøúûûýüþÿÿùýûúûüûúúûüúûüûûþýÿÿüûú'ûøúûüüûûýÿÿüûþúû&ûøúûüüûüýÿÿüûüþûüüüûüþÿÿüû'üüûüýüüþþÿÿþýüüû'üøûüýýüüþÿÿýüþûü&üøûüýýüýþÿÿý.üýüüýþÿÿýüýþÿ3ýþÿ3ýþÿþýþýþÿ/þþýþþ ÿþÿþ ÿþ'ÿþ;ÿþ-ÿgÇad&­ÿôüòòöð÷ðÇ­ëÿüýÿþÿÿì²Ðùøüíþ° gsT>5xõÀ+Uz]8-nÕýÿý„8ŽggÇfd#§ÿí÷ðòôò÷óϬãÿþþÿýÿýâ¯Ö÷ïöïÿ­[ssi8(]r&SiltK&Jžñÿ†<…kkïjd*°ÿòøðõô÷øùà°ÚÿÿÛüÿúÒ´äûë÷öÿ±`p_nlOJhs]gl\B)bÖŸ .‹\\Ç_W#¬ÿîóïòíóñ÷è°Ñýÿÿþûÿúƹí÷æóòþ¯S^Tafap,\jUNZeaE)@9"?…``ÇdT ¥óÞåæåßäáêãªÄúÿþþûÿû¿¸éêßêäð¨ Te]][[kD!R`eh\_Xs`6<~FFÇJ?¨õÝáãâÞÞÜåß®Äùÿüÿúÿþ½¸çåáæÝë¨@K<>JKJ(EDAD?LE57¥Ýýò{~+*)('&&Â,­ÿääìßêáëãµ¼óÿþþüÿúÿö±ºóçåàò²0*Ûÿ¼'oÔùòéé…‚Ç!­õáÜßæçæïÒ­ÍüÿýÿüÿùÿúÑ©Þëìæö¯  [Èöðÿ¦ B­îçáÙçÿ “€‚„„|„žßøîíìèçîêÀ²âÿÿüÿüÿùþúã¯ÊÞìðø­.•çõÝÝÿ¾ åëêâóèåê|’çç¾èéêëèêììãáçæéëîÖ´Êùÿþüÿúÿüÿý÷þãöÝéæÅÒð÷êéçææÄÔêïåìçßêêôÊ’ºôëëéèçææêãìëåéìêìðêıáÿ÷ýüÿøÿþÿÿÉÛ¥¼ôîéêæõèÚïíÛðìåíçìçéèçõäèëäñçæèêêéèéëæëîèæééæîôÉ®×üýÿÿþýìÿûбÏðïèñãâééëîëêëìíí÷ëðëâçóôëîîííîñòìæäêîîïôõÕ´ÂíþûÿÿþÝýüþëÀ¯×úóçèíñìéêéííììëêééñåäïóìéðìëëììííìîíïòîêí÷Û·µàÿÿüÿÿþïüÿÿÞ­·áððñíêíîëéííîßçåìõðçíüììíïñðíëòñïìïòêÞ²»ÚüÿþýýÿÿþÿòûÙ±´ÓôöíåìðïòííÛîïðòñõðçéôñçðïïðññïííëëóýõÓ¯µÝýÿþÿÿþÿÿþÊÿþúÿÿÖ³·ÛðúôñëçìðïïîíìëëîïìðüüÛ´õòïìîïñòñöüöÞÄ·¶äýÿûüÿÿþËÿúøÿÿã¼²ÈãõýúñíòóóôôóòñïðùüèÇ´´ù÷öôóôõøøõçα­Ëíÿÿþúþÿ ÿêýþþøûÿÿâ·²ºÏåöýúñòõ÷ù÷÷ßüõëÖ¶¦¿ãñóö÷õòñðàγª¾áøþûúýÿþýüûÿÿÎüýÿÿþùüÿøÕ¶¬°ÈãððñóõóòïíáÔº§µÝùÿÀÄÉÌÈ¿µ­¨²ÆÜðüÿÿýþþ ÿýþÿþÿìòÙ¿®¨ª¾¿ÅÊʼº§®¾Øòÿÿᄎ¶²´¼ÅÊÞæñúýýþÿþþÿþÞøýÿÿ÷æÖÎý¹º»½ÃÉØáíúÿÿþùêæáÞàèóùüÿÿþÿþÿþþÿÿóûöíæßÛÝäï÷üþÿÿüþÿÿööõõôøööùýÿÿþÿÿþÿöü÷õöø÷öôòððòòô÷òöûýüüþÿõö÷÷öøôòôøüþýÿÿþÿúýûøõóòòýöøûûýù÷õõúö÷úýÿôôõõ÷øøö÷÷öõöúþþ ÿüüýþÿÿþùÙøöõõøüö÷÷õõ÷ø÷ÿúóñòøýÿö÷øùùøööõö÷õóô÷úþþ ÿýýþÿÿéýûùñô÷ùûùöõö÷öòòöøöôõ÷ùùþ÷öö÷öõõû÷ôôö÷öôýþþ ÿþþÿÿäûøöû÷ôôõõóðõúû÷÷øöòõøúùõõöù÷÷ùõøüÿÿþÿ ÿûû÷õõöö÷øú÷ùûýþÿ ÿúþú÷ööøøöøùüúûýÿ ÿþüýûùøøùøöøúûùøúüÿ ÿøþýûùøøùúúøù÷üúøùüþÿþÿÿ÷þüúøøùúûùùú÷ûúùúûýþþÿÿ÷þüúùùúûûùùú÷úýùúûûýýþÿÿüýúúûûþúùùú÷úýøúûûýüþÿÿùýûúûüûúúûüúûüûûþýÿÿüûú'ûøúûüüûûýÿÿüûþúû&ûøúûüüûüýÿÿüûüþûüüüûüþÿÿüû'üüûüýüüþþÿÿþýüüû'üøûüýýüüþÿÿýüþûü&üøûüýýüýþÿÿý.üýüüýþÿÿýüýþÿ3ýþÿ3ýþÿþýþýþÿ/þþýþþ ÿþÿþ ÿþ'ÿþ;ÿþ-ÿgÇad&­ÿôüòòöð÷ðÇ­ëÿüýÿþÿÿì²Ðùøüíþ° gsT>5xõÀ+Uz]8-nÕýÿý„8ŽggÇfd#§ÿí÷ðòôò÷óϬãÿþþÿýÿýâ¯Ö÷ïöïÿ­[ssi8(]r&SiltK&Jžñÿ†<…kkïjd*°ÿòøðõô÷øùà°ÚÿÿÛüÿúÒ´äûë÷öÿ±`p_nlOJhs]gl\B)bÖŸ .‹\\Ç_W#¬ÿîóïòíóñ÷è°Ñýÿÿþûÿúƹí÷æóòþ¯S^Tafap,\jUNZeaE)@9"?…``ÇdT ¥óÞåæåßäáêãªÄúÿþþûÿû¿¸éêßêäð¨ Te]][[kD!R`eh\_Xs`6<~FFÇJ?¨õÝáãâÞÞÜåß®Äùÿüÿúÿþ½¸çåáæÝë¨@K<>JKJ(EDAD?LE57¥Ýýò{~+*)('&&Â,­ÿääìßêáëãµ¼óÿþþüÿúÿö±ºóçåàò²0*Ûÿ¼'oÔùòéé…‚Ç!­õáÜßæçæïÒ­ÍüÿýÿüÿùÿúÑ©Þëìæö¯  [Èöðÿ¦ B­îçáÙçÿ “€‚„„|„žßøîíìèçîêÀ²âÿÿüÿüÿùþúã¯ÊÞìðø­.•çõÝÝÿ¾ åëêâóèåê|’çç¾èéêëèêììãáçæéëîÖ´Êùÿþüÿúÿüÿý÷þãöÝéæÅÒð÷êéçææÄÔêïåìçßêêôÊ’ºôëëéèçææêãìëåéìêìðêıáÿ÷ýüÿøÿþÿÿÉÛ¥¼ôîéêæõèÚïíÛðìåíçìçéèçõäèëäñçæèêêéèéëæëîèæééæîôÉ®×üýÿÿþýìÿûбÏðïèñãâééëîëêëìíí÷ëðëâçóôëîîííîñòìæäêîîïôõÕ´ÂíþûÿÿþÝýüþëÀ¯×úóçèíñìéêéííììëêééñåäïóìéðìëëììííìîíïòîêí÷Û·µàÿÿüÿÿþïüÿÿÞ­·áððñíêíîëéííîßçåìõðçíüììíïñðíëòñïìïòêÞ²»ÚüÿþýýÿÿþÿòûÙ±´ÓôöíåìðïòííÛîïðòñõðçéôñçðïïðññïííëëóýõÓ¯µÝýÿþÿÿþÿÿþÊÿþúÿÿÖ³·ÛðúôñëçìðïïîíìëëîïìðüüÛ´õòïìîïñòñöüöÞÄ·¶äýÿûüÿÿþËÿúøÿÿã¼²ÈãõýúñíòóóôôóòñïðùüèÇ´´ù÷öôóôõøøõçα­Ëíÿÿþúþÿ ÿêýþþøûÿÿâ·²ºÏåöýúñòõ÷ù÷÷ßüõëÖ¶¦¿ãñóö÷õòñðàγª¾áøþûúýÿþýüûÿÿÎüýÿÿþùüÿøÕ¶¬°ÈãððñóõóòïíáÔº§µÝùÿÀÄÉÌÈ¿µ­¨²ÆÜðüÿÿýþþ ÿýþÿþÿìòÙ¿®¨ª¾¿ÅÊʼº§®¾Øòÿÿᄎ¶²´¼ÅÊÞæñúýýþÿþþÿþÞøýÿÿ÷æÖÎý¹º»½ÃÉØáíúÿÿþùêæáÞàèóùüÿÿþÿþÿþþÿÿóûöíæßÛÝäï÷üþÿÿüþÿÿööõõôøööùýÿÿþÿÿþÿöü÷õöø÷öôòððòòô÷òöûýüüþÿõö÷÷öøôòôøüþýÿÿþÿúýûøõóòòýöøûûýù÷õõúö÷úýÿôôõõ÷øøö÷÷öõöúþþ ÿüüýþÿÿþùÙøöõõøüö÷÷õõ÷ø÷ÿúóñòøýÿö÷øùùøööõö÷õóô÷úþþ ÿýýþÿÿéýûùñô÷ùûùöõö÷öòòöøöôõ÷ùùþ÷öö÷öõõû÷ôôö÷öôýþþ ÿþþÿÿäûøöû÷ôôõõóðõúû÷÷øöòõøúùõõöù÷÷ùõøüÿÿþÿ ÿûû÷õõöö÷øú÷ùûýþÿ ÿúþú÷ööøøöøùüúûýÿ ÿþüýûùøøùøöøúûùøúüÿ ÿøþýûùøøùúúøù÷üúøùüþÿþÿÿ÷þüúøøùúûùùú÷ûúùúûýþþÿÿ÷þüúùùúûûùùú÷úýùúûûýýþÿÿüýúúûûþúùùú÷úýøúûûýüþÿÿùýûúûüûúúûüúûüûûþýÿÿüûú'ûøúûüüûûýÿÿüûþúû&ûøúûüüûüýÿÿüûüþûüüüûüþÿÿüû'üüûüýüüþþÿÿþýüüû'üøûüýýüüþÿÿýüþûü&üøûüýýüýþÿÿý.üýüüýþÿÿýüýþÿ3ýþÿ3ýþÿþýþýþÿ/þþýþþ ÿþÿþ ÿþ'ÿþ;ÿþ-ÿÿ€=úøñøöÒ­ßÿÿýüÿþüÿü±Âøûóõÿ¶L W÷ÿýìC2Pno"”þ–@!Mtj6tüÿñøùâªÖÿþÿþÿÿþÿûñöùܲØþÿýýÿÿüÿì±Ìú÷ïõÿ±H`üÿ½^&=aliq*\z"=xpem5sûýïöøå°Îÿþÿþÿþþÿþññùç¹ÌüÿþýÿÿüÿسÝþöóüÿº@cÙ‡,-Wjh[^z+>S_bm`U.vüþó÷ùï¼Äúþÿþÿþþúøíêóì¼ÁùþÿþÿÿüÿË´æùïïöÿ¾11G*8d_gc[Xg,&`if_a_c1sùùïòôò¹öþÿþÿþþîîçâé黺÷ÿÿþÿÿüþDzäëáâçë±B+,RjhWXfjea';eMTe]Xd&iîëäæéí½³óÿÿþþ€Ìêæâàä亷õÿÿýÿÿýÿÅ®âãàáåí£5NV:BH?<iëæââäí¼²óÿÿýÿÿþïãßâæä¼·ôÿÿüþÿþÿȯååãâçô¿     oíæääåòÀ³ôÿÿüÿÿþøäÞäêç½·ôþÿûýÿþÿγêæâÚÞï·  píäããäò½µöÿÿûÿÿþìêàÞêß°ÅüûýÿÿÄÒ¹ÕìäßÝóº_´]  læìàÙêè¸ÀøÿþÿüÿÿìëããìÚ²ÐýüþÿÿÄÛ±Òñáàçó¥(Xêâ*(/#(H'$.+!~êåçâìàºÈúÿýÿüÿþïêæêìϳáýýþÿÿþÅì¯Éòäáìó¿(QõÿàÆ[7=%‡Ø^06(ZôõæØòÙ©ÕûþýÿýÿþöêèðêÀ´ðÿþÿÿÄþýüþ¹¼èîååöª!Nàãèðçœ0;‰öàž5/u÷åæèòÅ®ãþþýÿþÿÿûééïßµ¼ùÿÿÂþüûÿͳÓ÷ëÝü´'UóùïßæäÏv€úöôÑ~"rñâéñê¼ÀðÿþýÿþþÿøéìæÎµÑÿþþÿÿÂþüüÿã¶ÀððáûË7Oßíêéíììð²G…ùêâìæ§EvîòïêÒºÐùÿþþÿþüÿîëñؽÁîÿýþÿÿÔþýüÿõȵÖîìïüÅ—±éòîæèààôç×ÈäâìíáæóãºÙòåôë·ºéþþÿòýûÿäìõϱÌÿÿýþÿÿÆþýýÿÿÛ´ÀêõáéøíîçäçéåïáëðéçáëáéîåèíãóñæìØ®Íõÿþþÿÿýúÿé÷زÆðÿÿÖþýûÿøÓ¶Ïòñåíëêòóêäñíéååæêìèëíêæäëóëêùâ°»îÿÿ÷üÛº»ßÿÿøÿÿéþýûÿÿëÅ´ÐøííêéìèèòçéëîïïðîñìéêîñëãïòçıÖÿÿ÷ð³«Ýÿÿýûÿÿèþýüÿÿýã²±Ûôïèéíîìíêêëììííïìíìêìñòîûä½¯Îøÿýÿÿø»®ÍýÿûüÿÿÕþýþþùýþÛµ¬Þðùñêîïìòñîííîïñìòòëéðö÷åÀ©Æöÿüüÿÿ÷¨ÖýÿùÿÿþÿÿÖþýÿÿùøÿþÚ±¬Ôùÿôïïîèêíîïïîííìëð÷øíß¶´Ëñÿüýÿÿ÷Ùùÿûûÿÿþÿÿíþýþÿÿûùÿüçµ³ÂÝòúúõïïñóòó÷öåË·²Ôûÿúûÿ ÿúúýÿýûÿÿüþýýÿÿÛöúÿÿòÇ©²ËãòõûúöõôôõöûöñçÓÀ·¸áöÿÿúÿÿöÿÿýûþÿÿþÿÿûþýüýþþÝýüýÿòßǯ±ÈÛêëïôõóòðëÞÏÁ´¶Ðîÿÿûýÿÿþÿ ÿþ ÿüüýýþþýäÿþôàDz§«»ÆÈÍÑʾ¬¬°½Ðèüÿüýþþÿ ÿþ ÿýþþýþþîýøðèâÈļ¶³µº¼ÊÔãôÿÿýþþÿÿþþÿÿþÿþýÿõúîåãàÜâëûýÿÿûþûþþÿÿþþÿÿþþÿÿþæýüüýýûöóøòóúúôôùùøöö÷úüþþÿÿþþÿÿþöýüýýúöòññ÷÷øöóòùó÷úýýþÿÿþþÿÿüýþþÿÿàþýüüýûöòñôùö÷öòðôôòþü÷óòó÷ûüüýþÿ ÿûûüýþÿÿÞþýüûûù÷ôóóõ÷ô÷÷õõø÷õóõ÷øø÷øùúúüýþÿ ÿûùúüþÿ ÿþôýûûöõôöúû÷ô÷÷ø÷õöóó÷ùøùûýþÿ ÿüöùüþþ ÿþûÿýùõöö ÷øùøõö÷úüýþÿÿù÷ùûýþþÿ ÿþûýûøö÷÷øþ÷øøùöú÷ùûýþÿÿùúùùûýþÿ ÿùþýúø÷÷øøù÷ûøúüþÿÿùûúøùüþÿ ÿúþûøööøøùøüùûþÿÿùüúøøûþÿ ÿùþû÷ö÷øùùøùúøùøøùûýþÿÿøûúùùúüþÿÿþúüúø÷øùùúþøùùúùüûüýÿÿúýûýÿÿüþüûúú ùúùúûÿ÷ùúûûúúüþÿÿøýüúúûüúùùúùúüùúúûûúÿþüûûúüýýþþÿÿþüûúûúûýýþÿÿüûúüýýþþÿÿþùýüûûúúûûúûýýþÿÿüûüýþÿþýýüûûúûüýýþÿÿüþýþþÿþüýüüûûüûüýýþÿÿþýüüýþÿþýþüûûüûüýþþÿÿýüþýþþÿþúýüüûûüüýþþÿÿýüýþÿþþýüüýþýýþÿÿýøüýýþÿþþÿÿþýüýþýýþÿÿýÿ'ýÿýÿ'ýÿþÿþýþÿþÿ'þÿþÿ'þÿþÿþÿþˆÿ€=úøñøöÒ­ßÿÿýüÿþüÿü±Âøûóõÿ¶L W÷ÿýìC2Pno"”þ–@!Mtj6tüÿñøùâªÖÿþÿþÿÿþÿûñöùܲØþÿýýÿÿüÿì±Ìú÷ïõÿ±H`üÿ½^&=aliq*\z"=xpem5sûýïöøå°Îÿþÿþÿþþÿþññùç¹ÌüÿþýÿÿüÿسÝþöóüÿº@cÙ‡,-Wjh[^z+>S_bm`U.vüþó÷ùï¼Äúþÿþÿþþúøíêóì¼ÁùþÿþÿÿüÿË´æùïïöÿ¾11G*8d_gc[Xg,&`if_a_c1sùùïòôò¹öþÿþÿþþîîçâé黺÷ÿÿþÿÿüþDzäëáâçë±B+,RjhWXfjea';eMTe]Xd&iîëäæéí½³óÿÿþþ€Ìêæâàä亷õÿÿýÿÿýÿÅ®âãàáåí£5NV:BH?<iëæââäí¼²óÿÿýÿÿþïãßâæä¼·ôÿÿüþÿþÿȯååãâçô¿     oíæääåòÀ³ôÿÿüÿÿþøäÞäêç½·ôþÿûýÿþÿγêæâÚÞï·  píäããäò½µöÿÿûÿÿþìêàÞêß°ÅüûýÿÿÄÒ¹ÕìäßÝóº_´]  læìàÙêè¸ÀøÿþÿüÿÿìëããìÚ²ÐýüþÿÿÄÛ±Òñáàçó¥(Xêâ*(/#(H'$.+!~êåçâìàºÈúÿýÿüÿþïêæêìϳáýýþÿÿþÅì¯Éòäáìó¿(QõÿàÆ[7=%‡Ø^06(ZôõæØòÙ©ÕûþýÿýÿþöêèðêÀ´ðÿþÿÿÄþýüþ¹¼èîååöª!Nàãèðçœ0;‰öàž5/u÷åæèòÅ®ãþþýÿþÿÿûééïßµ¼ùÿÿÂþüûÿͳÓ÷ëÝü´'UóùïßæäÏv€úöôÑ~"rñâéñê¼ÀðÿþýÿþþÿøéìæÎµÑÿþþÿÿÂþüüÿã¶ÀððáûË7Oßíêéíììð²G…ùêâìæ§EvîòïêÒºÐùÿþþÿþüÿîëñؽÁîÿýþÿÿÔþýüÿõȵÖîìïüÅ—±éòîæèààôç×ÈäâìíáæóãºÙòåôë·ºéþþÿòýûÿäìõϱÌÿÿýþÿÿÆþýýÿÿÛ´ÀêõáéøíîçäçéåïáëðéçáëáéîåèíãóñæìØ®Íõÿþþÿÿýúÿé÷زÆðÿÿÖþýûÿøÓ¶Ïòñåíëêòóêäñíéååæêìèëíêæäëóëêùâ°»îÿÿ÷üÛº»ßÿÿøÿÿéþýûÿÿëÅ´ÐøííêéìèèòçéëîïïðîñìéêîñëãïòçıÖÿÿ÷ð³«Ýÿÿýûÿÿèþýüÿÿýã²±Ûôïèéíîìíêêëììííïìíìêìñòîûä½¯Îøÿýÿÿø»®ÍýÿûüÿÿÕþýþþùýþÛµ¬Þðùñêîïìòñîííîïñìòòëéðö÷åÀ©Æöÿüüÿÿ÷¨ÖýÿùÿÿþÿÿÖþýÿÿùøÿþÚ±¬Ôùÿôïïîèêíîïïîííìëð÷øíß¶´Ëñÿüýÿÿ÷Ùùÿûûÿÿþÿÿíþýþÿÿûùÿüçµ³ÂÝòúúõïïñóòó÷öåË·²Ôûÿúûÿ ÿúúýÿýûÿÿüþýýÿÿÛöúÿÿòÇ©²ËãòõûúöõôôõöûöñçÓÀ·¸áöÿÿúÿÿöÿÿýûþÿÿþÿÿûþýüýþþÝýüýÿòßǯ±ÈÛêëïôõóòðëÞÏÁ´¶Ðîÿÿûýÿÿþÿ ÿþ ÿüüýýþþýäÿþôàDz§«»ÆÈÍÑʾ¬¬°½Ðèüÿüýþþÿ ÿþ ÿýþþýþþîýøðèâÈļ¶³µº¼ÊÔãôÿÿýþþÿÿþþÿÿþÿþýÿõúîåãàÜâëûýÿÿûþûþþÿÿþþÿÿþþÿÿþæýüüýýûöóøòóúúôôùùøöö÷úüþþÿÿþþÿÿþöýüýýúöòññ÷÷øöóòùó÷úýýþÿÿþþÿÿüýþþÿÿàþýüüýûöòñôùö÷öòðôôòþü÷óòó÷ûüüýþÿ ÿûûüýþÿÿÞþýüûûù÷ôóóõ÷ô÷÷õõø÷õóõ÷øø÷øùúúüýþÿ ÿûùúüþÿ ÿþôýûûöõôöúû÷ô÷÷ø÷õöóó÷ùøùûýþÿ ÿüöùüþþ ÿþûÿýùõöö ÷øùøõö÷úüýþÿÿù÷ùûýþþÿ ÿþûýûøö÷÷øþ÷øøùöú÷ùûýþÿÿùúùùûýþÿ ÿùþýúø÷÷øøù÷ûøúüþÿÿùûúøùüþÿ ÿúþûøööøøùøüùûþÿÿùüúøøûþÿ ÿùþû÷ö÷øùùøùúøùøøùûýþÿÿøûúùùúüþÿÿþúüúø÷øùùúþøùùúùüûüýÿÿúýûýÿÿüþüûúú ùúùúûÿ÷ùúûûúúüþÿÿøýüúúûüúùùúùúüùúúûûúÿþüûûúüýýþþÿÿþüûúûúûýýþÿÿüûúüýýþþÿÿþùýüûûúúûûúûýýþÿÿüûüýþÿþýýüûûúûüýýþÿÿüþýþþÿþüýüüûûüûüýýþÿÿþýüüýþÿþýþüûûüûüýþþÿÿýüþýþþÿþúýüüûûüüýþþÿÿýüýþÿþþýüüýþýýþÿÿýøüýýþÿþþÿÿþýüýþýýþÿÿýÿ'ýÿýÿ'ýÿþÿþýþÿþÿ'þÿþÿ'þÿþÿþÿþˆÿ€=úøñøöÒ­ßÿÿýüÿþüÿü±Âøûóõÿ¶L W÷ÿýìC2Pno"”þ–@!Mtj6tüÿñøùâªÖÿþÿþÿÿþÿûñöùܲØþÿýýÿÿüÿì±Ìú÷ïõÿ±H`üÿ½^&=aliq*\z"=xpem5sûýïöøå°Îÿþÿþÿþþÿþññùç¹ÌüÿþýÿÿüÿسÝþöóüÿº@cÙ‡,-Wjh[^z+>S_bm`U.vüþó÷ùï¼Äúþÿþÿþþúøíêóì¼ÁùþÿþÿÿüÿË´æùïïöÿ¾11G*8d_gc[Xg,&`if_a_c1sùùïòôò¹öþÿþÿþþîîçâé黺÷ÿÿþÿÿüþDzäëáâçë±B+,RjhWXfjea';eMTe]Xd&iîëäæéí½³óÿÿþþ€Ìêæâàä亷õÿÿýÿÿýÿÅ®âãàáåí£5NV:BH?<iëæââäí¼²óÿÿýÿÿþïãßâæä¼·ôÿÿüþÿþÿȯååãâçô¿     oíæääåòÀ³ôÿÿüÿÿþøäÞäêç½·ôþÿûýÿþÿγêæâÚÞï·  píäããäò½µöÿÿûÿÿþìêàÞêß°ÅüûýÿÿÄÒ¹ÕìäßÝóº_´]  læìàÙêè¸ÀøÿþÿüÿÿìëããìÚ²ÐýüþÿÿÄÛ±Òñáàçó¥(Xêâ*(/#(H'$.+!~êåçâìàºÈúÿýÿüÿþïêæêìϳáýýþÿÿþÅì¯Éòäáìó¿(QõÿàÆ[7=%‡Ø^06(ZôõæØòÙ©ÕûþýÿýÿþöêèðêÀ´ðÿþÿÿÄþýüþ¹¼èîååöª!Nàãèðçœ0;‰öàž5/u÷åæèòÅ®ãþþýÿþÿÿûééïßµ¼ùÿÿÂþüûÿͳÓ÷ëÝü´'UóùïßæäÏv€úöôÑ~"rñâéñê¼ÀðÿþýÿþþÿøéìæÎµÑÿþþÿÿÂþüüÿã¶ÀððáûË7Oßíêéíììð²G…ùêâìæ§EvîòïêÒºÐùÿþþÿþüÿîëñؽÁîÿýþÿÿÔþýüÿõȵÖîìïüÅ—±éòîæèààôç×ÈäâìíáæóãºÙòåôë·ºéþþÿòýûÿäìõϱÌÿÿýþÿÿÆþýýÿÿÛ´ÀêõáéøíîçäçéåïáëðéçáëáéîåèíãóñæìØ®Íõÿþþÿÿýúÿé÷زÆðÿÿÖþýûÿøÓ¶Ïòñåíëêòóêäñíéååæêìèëíêæäëóëêùâ°»îÿÿ÷üÛº»ßÿÿøÿÿéþýûÿÿëÅ´ÐøííêéìèèòçéëîïïðîñìéêîñëãïòçıÖÿÿ÷ð³«Ýÿÿýûÿÿèþýüÿÿýã²±Ûôïèéíîìíêêëììííïìíìêìñòîûä½¯Îøÿýÿÿø»®ÍýÿûüÿÿÕþýþþùýþÛµ¬Þðùñêîïìòñîííîïñìòòëéðö÷åÀ©Æöÿüüÿÿ÷¨ÖýÿùÿÿþÿÿÖþýÿÿùøÿþÚ±¬Ôùÿôïïîèêíîïïîííìëð÷øíß¶´Ëñÿüýÿÿ÷Ùùÿûûÿÿþÿÿíþýþÿÿûùÿüçµ³ÂÝòúúõïïñóòó÷öåË·²Ôûÿúûÿ ÿúúýÿýûÿÿüþýýÿÿÛöúÿÿòÇ©²ËãòõûúöõôôõöûöñçÓÀ·¸áöÿÿúÿÿöÿÿýûþÿÿþÿÿûþýüýþþÝýüýÿòßǯ±ÈÛêëïôõóòðëÞÏÁ´¶Ðîÿÿûýÿÿþÿ ÿþ ÿüüýýþþýäÿþôàDz§«»ÆÈÍÑʾ¬¬°½Ðèüÿüýþþÿ ÿþ ÿýþþýþþîýøðèâÈļ¶³µº¼ÊÔãôÿÿýþþÿÿþþÿÿþÿþýÿõúîåãàÜâëûýÿÿûþûþþÿÿþþÿÿþþÿÿþæýüüýýûöóøòóúúôôùùøöö÷úüþþÿÿþþÿÿþöýüýýúöòññ÷÷øöóòùó÷úýýþÿÿþþÿÿüýþþÿÿàþýüüýûöòñôùö÷öòðôôòþü÷óòó÷ûüüýþÿ ÿûûüýþÿÿÞþýüûûù÷ôóóõ÷ô÷÷õõø÷õóõ÷øø÷øùúúüýþÿ ÿûùúüþÿ ÿþôýûûöõôöúû÷ô÷÷ø÷õöóó÷ùøùûýþÿ ÿüöùüþþ ÿþûÿýùõöö ÷øùøõö÷úüýþÿÿù÷ùûýþþÿ ÿþûýûøö÷÷øþ÷øøùöú÷ùûýþÿÿùúùùûýþÿ ÿùþýúø÷÷øøù÷ûøúüþÿÿùûúøùüþÿ ÿúþûøööøøùøüùûþÿÿùüúøøûþÿ ÿùþû÷ö÷øùùøùúøùøøùûýþÿÿøûúùùúüþÿÿþúüúø÷øùùúþøùùúùüûüýÿÿúýûýÿÿüþüûúú ùúùúûÿ÷ùúûûúúüþÿÿøýüúúûüúùùúùúüùúúûûúÿþüûûúüýýþþÿÿþüûúûúûýýþÿÿüûúüýýþþÿÿþùýüûûúúûûúûýýþÿÿüûüýþÿþýýüûûúûüýýþÿÿüþýþþÿþüýüüûûüûüýýþÿÿþýüüýþÿþýþüûûüûüýþþÿÿýüþýþþÿþúýüüûûüüýþþÿÿýüýþÿþþýüüýþýýþÿÿýøüýýþÿþþÿÿþýüýþýýþÿÿýÿ'ýÿýÿ'ýÿþÿþýþÿþÿ'þÿþÿ'þÿþÿþÿþˆÿÿ€Rüõ¹½ðôöûÿŽ+X|/:ºÿý÷ôóôöýˆor-QvJ@¸ÿñëòþâ´Ðúùÿöÿüüþ̱Ýþû¼"&+//E5ÿî´Åö÷øüïW*oR+‘ÿóóôôóòñó—i÷ÿt+ekòøôõýå¹Éùúÿùÿüÿõ¾¶ìýúÚvT]cn[@>ÿã°Ñú÷÷üË7@u/Tæÿñòôõõôòòãßÿÿ»+?n2[Ýþôòþó¾¼öûÿûþýÿè±Äþ÷óôõòþéõð•%ÿ׮ܸïòø,S\(‹úìññðïïððòöþéóîV)bE8ÅÿòìøóŰóþÿýýþÿà®Ðÿïêò÷þý÷ûÿô•üЭáïãêôz*ZG2«ìéèçãâáâäæããêîðy2^S&³øèâíìʨðþþýýÿþÜ®ÐóçåäàÝÖÞÝ×ûëøÐ­âæÝåðwE*-¼ìçÞààŠßÞÝÛäÞâÙìŠ;C¬íßÜçè˨íþÿýþþýÝ®ÊåãäÞØáèÞæßàëùÒ¬ßäáæîn¶õÞßàâääâàߨåèçú ªíäáæäÊ«ìþÿûÿþýã­ÊèãßßéãäÝߨèøûÕªÝäæéí†÷ ñãàáâãää¹ÞÝßîàd¸ïæäìîɯêýÿúÿþýç¯ÏòåØßçáÖàãçú³þÞ¶Ïêàæî¨! ^æòáíåâÚàÞåÞåÙýÖ3€‹E×èééãìÀ½îÿþúÿüÿë·Ãìàçïúýÿûÿÿ©7ÿã²Çìáàï×?(¸ÿëÕÜïÜâæÛèà÷÷† iåìáÜìãºÄòÿÿýÿüÿô»½ëãíÑ’‡Ž‹{Gÿí´¾ìæÝìðu\×ìíàäæçßìÞÞý¿0"ªêãäÝõÖ±Ïúÿÿµüÿüĵäé÷²"  üúÁ²ãíáçï¾4 1WàìêáÖëíäøøÃ:11`äêÚëæóÏ®ÜþýýÿÿüÿþÖ­Óïÿ«ÙøÿÕ­ÎìëçíôŠ:?·òöòêÞÿß‹1 *. 4´÷îåçç€Çƶéÿûûÿýûÿúê°ÁìþÁ^Tevmdvœûÿè·¹ßñìçõão2.ÿã°Ñú÷÷üË7@u/Tæÿñòôõõôòòãßÿÿ»+?n2[Ýþôòþó¾¼öûÿûþýÿè±Äþ÷óôõòþéõð•%ÿ׮ܸïòø,S\(‹úìññðïïððòöþéóîV)bE8ÅÿòìøóŰóþÿýýþÿà®Ðÿïêò÷þý÷ûÿô•üЭáïãêôz*ZG2«ìéèçãâáâäæããêîðy2^S&³øèâíìʨðþþýýÿþÜ®ÐóçåäàÝÖÞÝ×ûëøÐ­âæÝåðwE*-¼ìçÞààŠßÞÝÛäÞâÙìŠ;C¬íßÜçè˨íþÿýþþýÝ®ÊåãäÞØáèÞæßàëùÒ¬ßäáæîn¶õÞßàâääâàߨåèçú ªíäáæäÊ«ìþÿûÿþýã­ÊèãßßéãäÝߨèøûÕªÝäæéí†÷ ñãàáâãää¹ÞÝßîàd¸ïæäìîɯêýÿúÿþýç¯ÏòåØßçáÖàãçú³þÞ¶Ïêàæî¨! ^æòáíåâÚàÞåÞåÙýÖ3€‹E×èééãìÀ½îÿþúÿüÿë·Ãìàçïúýÿûÿÿ©7ÿã²Çìáàï×?(¸ÿëÕÜïÜâæÛèà÷÷† iåìáÜìãºÄòÿÿýÿüÿô»½ëãíÑ’‡Ž‹{Gÿí´¾ìæÝìðu\×ìíàäæçßìÞÞý¿0"ªêãäÝõÖ±Ïúÿÿµüÿüĵäé÷²"  üúÁ²ãíáçï¾4 1WàìêáÖëíäøøÃ:11`äêÚëæóÏ®ÜþýýÿÿüÿþÖ­Óïÿ«ÙøÿÕ­ÎìëçíôŠ:?·òöòêÞÿß‹1 *. 4´÷îåçç€Çƶéÿûûÿýûÿúê°ÁìþÁ^Tevmdvœûÿè·¹ßñìçõão2.ÿã°Ñú÷÷üË7@u/Tæÿñòôõõôòòãßÿÿ»+?n2[Ýþôòþó¾¼öûÿûþýÿè±Äþ÷óôõòþéõð•%ÿ׮ܸïòø,S\(‹úìññðïïððòöþéóîV)bE8ÅÿòìøóŰóþÿýýþÿà®Ðÿïêò÷þý÷ûÿô•üЭáïãêôz*ZG2«ìéèçãâáâäæããêîðy2^S&³øèâíìʨðþþýýÿþÜ®ÐóçåäàÝÖÞÝ×ûëøÐ­âæÝåðwE*-¼ìçÞààŠßÞÝÛäÞâÙìŠ;C¬íßÜçè˨íþÿýþþýÝ®ÊåãäÞØáèÞæßàëùÒ¬ßäáæîn¶õÞßàâääâàߨåèçú ªíäáæäÊ«ìþÿûÿþýã­ÊèãßßéãäÝߨèøûÕªÝäæéí†÷ ñãàáâãää¹ÞÝßîàd¸ïæäìîɯêýÿúÿþýç¯ÏòåØßçáÖàãçú³þÞ¶Ïêàæî¨! ^æòáíåâÚàÞåÞåÙýÖ3€‹E×èééãìÀ½îÿþúÿüÿë·Ãìàçïúýÿûÿÿ©7ÿã²Çìáàï×?(¸ÿëÕÜïÜâæÛèà÷÷† iåìáÜìãºÄòÿÿýÿüÿô»½ëãíÑ’‡Ž‹{Gÿí´¾ìæÝìðu\×ìíàäæçßìÞÞý¿0"ªêãäÝõÖ±Ïúÿÿµüÿüĵäé÷²"  üúÁ²ãíáçï¾4 1WàìêáÖëíäøøÃ:11`äêÚëæóÏ®ÜþýýÿÿüÿþÖ­Óïÿ«ÙøÿÕ­ÎìëçíôŠ:?·òöòêÞÿß‹1 *. 4´÷îåçç€Çƶéÿûûÿýûÿúê°ÁìþÁ^Tevmdvœûÿè·¹ßñìçõão2.=/^msm@CD‰ôúøöñíÿõÿýÿþýþÿùǺéûñÿâj;54:0Ffhda^0„ÿÿÁlŸÿëO,LàÙM+(dØÿÿ€$h ™ÿÿâûùòìϹíÿüþÿýüýí¼ÆôüóþÛP1JJQR]bZWZZ,rôÿÿï2fÿÿ5??><%%NÜÿðÿ÷9ÿÿïëõéùô×±äÿýýÿýýÿè´ËôôìþãU?b\^Yc^[^`\.oðöîÿp[âþ‹C+ =Ë÷ëØíßjtñôÙåîäÝó騩Ýÿþüþýÿÿê±ÌêæáõÙK+FHSJHEJMKB!mæïÜöŒPÒÿó  ²ÿßÜíïÔ»ãþä×ßÙáâäÝ×§Ùÿÿüýþûÿè­ÍçãáíÐ@   fããÞõŽEÆö¾5nãîÜÛæÓŠ¡ñâááÝêããåÙ¬Úÿÿûüÿøûæ¬ÐèæäùØEËníáãõhKÓñ+& ^êøÛéé>­ûëáàäÝìßÛ°Üýÿûûÿþþç­ÐçãÝðÏ>ä   xãôþô=\ðû"­ŸtöÿÿñS(·óïÚëåÖã×®äÿÿÄè¶ÆìäàêÕwDCEB!zìëÞx‘õÜ!¡úó—h‡Š„4"©ÿïÚæçóʳêÿþÿÿ–þÿ÷»¹êæãäì×ÍÏÚÓ™,0* ‘þØH8ßÿ±* ðåèî•, (!›æÚéîà·¿ôÿþÿýÿþúÿÅ­äëåßèêèèôöÜO-2$+Žÿ¿8¿ÿÂ<“ïìâéðä‹€Õ36 ‚òèëõá«ÎýÿýÿüþÿùÿÔ¬ÕîçèèáÞäßßò·& 78¯ÿæ¾á£P8ìïæàæçèï¼”£Jèðßéì×±ßÿÿüÿüþÿýÿé¶½éëèääæëáÛïïŒ <¯ÿâèäXãæïãäîæêçßåÿäA2¬îùßâíÚ²ÄñÿÿûÿýþûÿÿüÊ­Øíîæëìæèëæñ⊠5Æÿæí×W <êëáîëáîéçòåòåU=Êÿçâí÷ïϲÞÿýÿúþÿþûÿÿŠâ³Âäçãæéãçëàãæõ†5Øûåñð³uàíèåîêçìâìèéóå©¿ÿßéùéèåÁ»îÿûþúÿÿþÿþüÿò´ØöõåèîäåëòêãÿÖ™Øóæéêëõôééëììêééêèäéæáôüèòää÷ðÄ·ÓÿýýþÆýÿýÿþæÃ°âîðííçèõéæèñ÷ùõóêéæèêëéåðîíìêêëíêìîêèëëãéæõõʰÎùþýýþßÿüþÿø×¸Éäùõëíñìîìëìëææèéìïïíìíñëêêëìíîîìïìëðïëîê÷÷Ó¯ÀîÿýýþÿÊüÿÿñЫÅíûìæíëçéëëéçêïïíêèêëíîññðñòñíëéïðïïîîòûõϬ¿éüþýýþÅÿþÿÿüùÿÿð°¼ãõïëîíðóôðîîðìîïñòïìêðïîïððîíîñòêäìõôìÊ«¹çüüÿýþþÿïýþÿþöûÿÿùɤ¹èùôòððÚïîîíììîïîíîòöóñïîîðñòëèëñøÿõß·®ÅëýÿÿûþþÿÇþûþÿýûýÿÿ÷ѱºÔé÷ôóñîïòóñöïéìôùöòúùù÷ôóòòøùøú÷â¿§°ÍõÿþÿÿöþþÿÜþýþÿýúýöÿýÚºµÇÚñõø÷öö÷öõòòùþõÞÉÙáêòõõóêõìÖì­ÉæþÿüûûþÿþþÿÊûþüúÿÿõüÿìį¨ÄÔäìîñôôîóôë×Á²¬¨¯¹ÃÊÍÌËÀ·¬©³Êãóýûûüþÿýüÿ ÿþÔùøùüûòãÖ¶±®²½ÈÎÏÊÅ»°¬¶ÉØÖÑÈ¿º·¹º¿ÅÑàîüÿÿýüýþþþýÿ ÿþüÿþþÿÿâþúîâÑļ¹¶³¶¼ÅÍØçøÿÿýôêäààßéïøÿÿûþûýþÿÿþ ÿþúÿýûûýÿÿõõíçâÞÚêïöûÿÿôöòõôóöõöö÷øùùüþÿÿþþÿ ÿþÿïþüúùöö÷øø÷ööîðóö÷÷öïõöö÷úùóòòóô÷úüûýÿÿþþÿ ÿþþýÿÿñüù÷ù÷õóòóõ÷ûú÷ööûõôööõõöòþýû÷õôóòùûýþþÿÿþöýüûù÷õôóøùùû÷öõûòóõö÷÷öôõôõöøù÷øùüþÿÿþÿíüøööõõîïóõöõòðóõ÷øùùûúùøöôôúõöóôõööøõôöö÷úþÿÿþúýûø÷÷øøú÷öôõöøø÷÷øø÷õôôõøøúùþø÷÷ûøûýþÿ ÿþÿþþøø÷ ø÷öø÷øùúûýþÿÿþÿýþüööøùø÷÷öøùùøùûþÿ ÿüþûùööøùúù÷öùúù÷÷úýÿ ÿûþüù÷ùùøúûúù÷÷ùûù÷÷ùüÿ ÿûýúø÷ùùúùø÷÷øùúùøøúüÿÿþþÿÿûüúøø÷÷úûùøùüúûüÿÿ÷þÿÿþûùùú÷÷ú ûúùùøùúûüýÿ ÿúþûùúûúúûûüýýþÿÿûþýüûúú/ûûüýýþÿÿûþýüûúú/ûûüýýþÿÿüþýüûûüýþþÿÿüþýüûû0üýþþÿÿüþüüûû0üýþþÿÿüþýüûû0üýþþÿÿýþýü3üýþþÿÿýþýüüýÿþ3ýÿþ1ý ÿþýþÿ/þÿþeÿþ<ÿþÿ€‹1ÖÿëùÿÄK)4)%/D{wB•ùöôøí¸ÁùþþÿýýüÿÿͲáúóôøÇ¿»¿¹˜Wmne\,‰ÿÉ@[õÿ¢73Éÿ÷¿>=/^msm@CD‰ôúøöñíÿõÿýÿþýþÿùǺéûñÿâj;54:0Ffhda^0„ÿÿÁlŸÿëO,LàÙM+(dØÿÿ€$h ™ÿÿâûùòìϹíÿüþÿýüýí¼ÆôüóþÛP1JJQR]bZWZZ,rôÿÿï2fÿÿ5??><%%NÜÿðÿ÷9ÿÿïëõéùô×±äÿýýÿýýÿè´ËôôìþãU?b\^Yc^[^`\.oðöîÿp[âþ‹C+ =Ë÷ëØíßjtñôÙåîäÝó騩Ýÿþüþýÿÿê±ÌêæáõÙK+FHSJHEJMKB!mæïÜöŒPÒÿó  ²ÿßÜíïÔ»ãþä×ßÙáâäÝ×§Ùÿÿüýþûÿè­ÍçãáíÐ@   fããÞõŽEÆö¾5nãîÜÛæÓŠ¡ñâááÝêããåÙ¬Úÿÿûüÿøûæ¬ÐèæäùØEËníáãõhKÓñ+& ^êøÛéé>­ûëáàäÝìßÛ°Üýÿûûÿþþç­ÐçãÝðÏ>ä   xãôþô=\ðû"­ŸtöÿÿñS(·óïÚëåÖã×®äÿÿÄè¶ÆìäàêÕwDCEB!zìëÞx‘õÜ!¡úó—h‡Š„4"©ÿïÚæçóʳêÿþÿÿ–þÿ÷»¹êæãäì×ÍÏÚÓ™,0* ‘þØH8ßÿ±* ðåèî•, (!›æÚéîà·¿ôÿþÿýÿþúÿÅ­äëåßèêèèôöÜO-2$+Žÿ¿8¿ÿÂ<“ïìâéðä‹€Õ36 ‚òèëõá«ÎýÿýÿüþÿùÿÔ¬ÕîçèèáÞäßßò·& 78¯ÿæ¾á£P8ìïæàæçèï¼”£Jèðßéì×±ßÿÿüÿüþÿýÿé¶½éëèääæëáÛïïŒ <¯ÿâèäXãæïãäîæêçßåÿäA2¬îùßâíÚ²ÄñÿÿûÿýþûÿÿüÊ­Øíîæëìæèëæñ⊠5Æÿæí×W <êëáîëáîéçòåòåU=Êÿçâí÷ïϲÞÿýÿúþÿþûÿÿŠâ³Âäçãæéãçëàãæõ†5Øûåñð³uàíèåîêçìâìèéóå©¿ÿßéùéèåÁ»îÿûþúÿÿþÿþüÿò´ØöõåèîäåëòêãÿÖ™Øóæéêëõôééëììêééêèäéæáôüèòää÷ðÄ·ÓÿýýþÆýÿýÿþæÃ°âîðííçèõéæèñ÷ùõóêéæèêëéåðîíìêêëíêìîêèëëãéæõõʰÎùþýýþßÿüþÿø×¸Éäùõëíñìîìëìëææèéìïïíìíñëêêëìíîîìïìëðïëîê÷÷Ó¯ÀîÿýýþÿÊüÿÿñЫÅíûìæíëçéëëéçêïïíêèêëíîññðñòñíëéïðïïîîòûõϬ¿éüþýýþÅÿþÿÿüùÿÿð°¼ãõïëîíðóôðîîðìîïñòïìêðïîïððîíîñòêäìõôìÊ«¹çüüÿýþþÿïýþÿþöûÿÿùɤ¹èùôòððÚïîîíììîïîíîòöóñïîîðñòëèëñøÿõß·®ÅëýÿÿûþþÿÇþûþÿýûýÿÿ÷ѱºÔé÷ôóñîïòóñöïéìôùöòúùù÷ôóòòøùøú÷â¿§°ÍõÿþÿÿöþþÿÜþýþÿýúýöÿýÚºµÇÚñõø÷öö÷öõòòùþõÞÉÙáêòõõóêõìÖì­ÉæþÿüûûþÿþþÿÊûþüúÿÿõüÿìį¨ÄÔäìîñôôîóôë×Á²¬¨¯¹ÃÊÍÌËÀ·¬©³Êãóýûûüþÿýüÿ ÿþÔùøùüûòãÖ¶±®²½ÈÎÏÊÅ»°¬¶ÉØÖÑÈ¿º·¹º¿ÅÑàîüÿÿýüýþþþýÿ ÿþüÿþþÿÿâþúîâÑļ¹¶³¶¼ÅÍØçøÿÿýôêäààßéïøÿÿûþûýþÿÿþ ÿþúÿýûûýÿÿõõíçâÞÚêïöûÿÿôöòõôóöõöö÷øùùüþÿÿþþÿ ÿþÿïþüúùöö÷øø÷ööîðóö÷÷öïõöö÷úùóòòóô÷úüûýÿÿþþÿ ÿþþýÿÿñüù÷ù÷õóòóõ÷ûú÷ööûõôööõõöòþýû÷õôóòùûýþþÿÿþöýüûù÷õôóøùùû÷öõûòóõö÷÷öôõôõöøù÷øùüþÿÿþÿíüøööõõîïóõöõòðóõ÷øùùûúùøöôôúõöóôõööøõôöö÷úþÿÿþúýûø÷÷øøú÷öôõöøø÷÷øø÷õôôõøøúùþø÷÷ûøûýþÿ ÿþÿþþøø÷ ø÷öø÷øùúûýþÿÿþÿýþüööøùø÷÷öøùùøùûþÿ ÿüþûùööøùúù÷öùúù÷÷úýÿ ÿûþüù÷ùùøúûúù÷÷ùûù÷÷ùüÿ ÿûýúø÷ùùúùø÷÷øùúùøøúüÿÿþþÿÿûüúøø÷÷úûùøùüúûüÿÿ÷þÿÿþûùùú÷÷ú ûúùùøùúûüýÿ ÿúþûùúûúúûûüýýþÿÿûþýüûúú/ûûüýýþÿÿûþýüûúú/ûûüýýþÿÿüþýüûûüýþþÿÿüþýüûû0üýþþÿÿüþüüûû0üýþþÿÿüþýüûû0üýþþÿÿýþýü3üýþþÿÿýþýüüýÿþ3ýÿþ1ý ÿþýþÿ/þÿþeÿþ<ÿþÿ€‹1ÖÿëùÿÄK)4)%/D{wB•ùöôøí¸ÁùþþÿýýüÿÿͲáúóôøÇ¿»¿¹˜Wmne\,‰ÿÉ@[õÿ¢73Éÿ÷¿>=/^msm@CD‰ôúøöñíÿõÿýÿþýþÿùǺéûñÿâj;54:0Ffhda^0„ÿÿÁlŸÿëO,LàÙM+(dØÿÿ€$h ™ÿÿâûùòìϹíÿüþÿýüýí¼ÆôüóþÛP1JJQR]bZWZZ,rôÿÿï2fÿÿ5??><%%NÜÿðÿ÷9ÿÿïëõéùô×±äÿýýÿýýÿè´ËôôìþãU?b\^Yc^[^`\.oðöîÿp[âþ‹C+ =Ë÷ëØíßjtñôÙåîäÝó騩Ýÿþüþýÿÿê±ÌêæáõÙK+FHSJHEJMKB!mæïÜöŒPÒÿó  ²ÿßÜíïÔ»ãþä×ßÙáâäÝ×§Ùÿÿüýþûÿè­ÍçãáíÐ@   fããÞõŽEÆö¾5nãîÜÛæÓŠ¡ñâááÝêããåÙ¬Úÿÿûüÿøûæ¬ÐèæäùØEËníáãõhKÓñ+& ^êøÛéé>­ûëáàäÝìßÛ°Üýÿûûÿþþç­ÐçãÝðÏ>ä   xãôþô=\ðû"­ŸtöÿÿñS(·óïÚëåÖã×®äÿÿÄè¶ÆìäàêÕwDCEB!zìëÞx‘õÜ!¡úó—h‡Š„4"©ÿïÚæçóʳêÿþÿÿ–þÿ÷»¹êæãäì×ÍÏÚÓ™,0* ‘þØH8ßÿ±* ðåèî•, (!›æÚéîà·¿ôÿþÿýÿþúÿÅ­äëåßèêèèôöÜO-2$+Žÿ¿8¿ÿÂ<“ïìâéðä‹€Õ36 ‚òèëõá«ÎýÿýÿüþÿùÿÔ¬ÕîçèèáÞäßßò·& 78¯ÿæ¾á£P8ìïæàæçèï¼”£Jèðßéì×±ßÿÿüÿüþÿýÿé¶½éëèääæëáÛïïŒ <¯ÿâèäXãæïãäîæêçßåÿäA2¬îùßâíÚ²ÄñÿÿûÿýþûÿÿüÊ­Øíîæëìæèëæñ⊠5Æÿæí×W <êëáîëáîéçòåòåU=Êÿçâí÷ïϲÞÿýÿúþÿþûÿÿŠâ³Âäçãæéãçëàãæõ†5Øûåñð³uàíèåîêçìâìèéóå©¿ÿßéùéèåÁ»îÿûþúÿÿþÿþüÿò´ØöõåèîäåëòêãÿÖ™Øóæéêëõôééëììêééêèäéæáôüèòää÷ðÄ·ÓÿýýþÆýÿýÿþæÃ°âîðííçèõéæèñ÷ùõóêéæèêëéåðîíìêêëíêìîêèëëãéæõõʰÎùþýýþßÿüþÿø×¸Éäùõëíñìîìëìëææèéìïïíìíñëêêëìíîîìïìëðïëîê÷÷Ó¯ÀîÿýýþÿÊüÿÿñЫÅíûìæíëçéëëéçêïïíêèêëíîññðñòñíëéïðïïîîòûõϬ¿éüþýýþÅÿþÿÿüùÿÿð°¼ãõïëîíðóôðîîðìîïñòïìêðïîïððîíîñòêäìõôìÊ«¹çüüÿýþþÿïýþÿþöûÿÿùɤ¹èùôòððÚïîîíììîïîíîòöóñïîîðñòëèëñøÿõß·®ÅëýÿÿûþþÿÇþûþÿýûýÿÿ÷ѱºÔé÷ôóñîïòóñöïéìôùöòúùù÷ôóòòøùøú÷â¿§°ÍõÿþÿÿöþþÿÜþýþÿýúýöÿýÚºµÇÚñõø÷öö÷öõòòùþõÞÉÙáêòõõóêõìÖì­ÉæþÿüûûþÿþþÿÊûþüúÿÿõüÿìį¨ÄÔäìîñôôîóôë×Á²¬¨¯¹ÃÊÍÌËÀ·¬©³Êãóýûûüþÿýüÿ ÿþÔùøùüûòãÖ¶±®²½ÈÎÏÊÅ»°¬¶ÉØÖÑÈ¿º·¹º¿ÅÑàîüÿÿýüýþþþýÿ ÿþüÿþþÿÿâþúîâÑļ¹¶³¶¼ÅÍØçøÿÿýôêäààßéïøÿÿûþûýþÿÿþ ÿþúÿýûûýÿÿõõíçâÞÚêïöûÿÿôöòõôóöõöö÷øùùüþÿÿþþÿ ÿþÿïþüúùöö÷øø÷ööîðóö÷÷öïõöö÷úùóòòóô÷úüûýÿÿþþÿ ÿþþýÿÿñüù÷ù÷õóòóõ÷ûú÷ööûõôööõõöòþýû÷õôóòùûýþþÿÿþöýüûù÷õôóøùùû÷öõûòóõö÷÷öôõôõöøù÷øùüþÿÿþÿíüøööõõîïóõöõòðóõ÷øùùûúùøöôôúõöóôõööøõôöö÷úþÿÿþúýûø÷÷øøú÷öôõöøø÷÷øø÷õôôõøøúùþø÷÷ûøûýþÿ ÿþÿþþøø÷ ø÷öø÷øùúûýþÿÿþÿýþüööøùø÷÷öøùùøùûþÿ ÿüþûùööøùúù÷öùúù÷÷úýÿ ÿûþüù÷ùùøúûúù÷÷ùûù÷÷ùüÿ ÿûýúø÷ùùúùø÷÷øùúùøøúüÿÿþþÿÿûüúøø÷÷úûùøùüúûüÿÿ÷þÿÿþûùùú÷÷ú ûúùùøùúûüýÿ ÿúþûùúûúúûûüýýþÿÿûþýüûúú/ûûüýýþÿÿûþýüûúú/ûûüýýþÿÿüþýüûûüýþþÿÿüþýüûû0üýþþÿÿüþüüûû0üýþþÿÿüþýüûû0üýþþÿÿýþýü3üýþþÿÿýþýüüýÿþ3ýÿþ1ý ÿþýþÿ/þÿþeÿþ<ÿþÿÿî.ïû÷ðïó÷¾·ñÿúÿüüÿÿÂѳ×úöûùºÅºÄÂ^/M£î­tÊÖßÿÿæêêäíįÆÖÿçöò¹´üÿüý' Òøôóòõúȹëÿûÿýüÿÿ€¹ÌºßúïøÏ@B9?;+Kbz¶â†AŒäÎÙõëëöéÿú³á¿ÿïñöÉ´ïÿþü` µüó÷òôüÒ¹áÿýÿþüÿÿúÂÀëøïÿÓ;FJM^kXzÖÉc3|ýØÄÜïþòèÿÿÚÕÉìùëöÞ´Ýÿÿû” ™ýîóìí÷Ú·Øÿþÿþýþÿò¸ÆññíÿÙ"Yhdh^XU¡ò§M †ÿâ»Áêÿêëñ÷íÎåÑÿçñè³Ñÿÿûž}ïâçåæíܲÒÿÿ€Îüþýÿì±ÆðêåñÎ=JGGJPUœå”AƒÿâºÀßéëß×ÝÏÙè¶ÿåæå±Íÿÿû‘ yéÞßáàæÜ°Ðÿýÿüþýÿê±ÆêäàòÍ  à€‹÷æÙÂÆÍÔÞ×ÖÕÂß´ðâàß°Îÿþü~ŠíåÝãàåÛ°Òÿûÿüýýÿë´ÆäãÜõÊ    uß… íÚêоÃÂâöòçµÑÙáßáà°Ïÿÿýi ”îëàèâæÝ°Óÿùÿýýüÿí¹ÆáåÞ𸠀£XßÀ3‰þÊêÿÙÊÚ¹õþ¾Í¹ÿçÛäâ±Ðÿÿþ6 ÍèàãâëæÑ±ØÿüþÿùÿýòºíéäîÄR?CE?=»ða”ÿÖËÜåàÏ´Ïç»Ú»õçãñرÓÿþý(âòâäãÞìÊ·âÿûþýüþþûÅ´æêÛçíÌÚÖØâ^ ?zØÀ^–ÿóÛßøëºÐØÜߪäÿãâñÒ³Úÿÿþqôêßåêî_ïÿûýûÿûþÿϯØëíáèãòãêüÞ;7Hˆ×Ö¡øÿëÆÙô÷Ûÿô·±ññãåîÅ·éÿþÿ²òãêãÜíæ°Êüþüþûÿüþÿß±Åéíáåãíâçèÿ4TÕÒ̺ÇÃÉÆÀÐåÙ¸óæßëëä¶¿øÿüÿjßëçïåßêÓ®×ÿþþÿûþÿüÿñ¿¸âääêçëæåÖéër :BsÖãëìØÑÙõ¬ÀËùââæÝîÑ­ÍÿÿúÿÕóçéäèõìÀ»çÿþÿÿýüÿüüþÕ¶ÑìêçäæåìæÔñÔjTèϱ¯½½®´ÀóäôÐäåÚåÁ¶áÿþúÿòéééàìïϵÔ÷ÿþÿþþüÿýùÿê½¼äîëëÌæìëæàùáqeøùõôîÝèÿú÷×ÙùèâôÕ¶Ëøÿýþÿìèòèê÷å¾±æÿýýþüÿýýùøÿ÷Å®Ôìì€áëæçáðêæõôÂq¡ßåÜÙáÞãëðÆãùìêúñǰÞÿýýÿÿêåêèðìɱàöûùÿÿúþþÿÿüþÿíÆ¸×ïñèäéñâéëéîøû÷ôîçãëöðáíïöîãïį̀ÞýýÿÿýÿëëêôøÒ²Åïÿÿûÿÿûþÿÿþúûÿúä²ÄäñæìñãìïíèèííçåîòîêîññëìêéöøØ¬ÆéýüÿÿþÿíúöðÚ°½óûÿÿûÿÿýÿþÿÿûúÿÿýÔ±½íüñììïóðìíðïéëïòñðïðïðïîùûص²êúýûÿÿ€†êøîÔ±²àýûÿþùýÿþÿüýþþüüþÿþͨÀéîéñèìíìïôôïêåäèïñîéåðõðÕ­³âÿÿþüÿÿþÿùêǵ¼ÞÿýûþüúþÿþÿýýþÿÿýúüþûΣ·çùöíîìéèìîîððñòñðó÷ðøï̲¹Üýÿÿþþÿýýÿß̰¿ìÿÿþþÿÿûþÿÿýÿÿÍýÿùÿøÔ´¾ÙäüüùóïîñóìïòñïññòúáĵÂåþþûüýÿÿüýÿ¯ºÎêÿÿôøÿ ÿÖþÿÿýÿÿøþÿÞ±«½àèò÷öôôøòòñôûÿõçϵ­ÅçþÿþüûüþÿÿîÁ×ÿÿ÷ÿÿýûûýÿþþÿÿûÿÿàüøýÿÿùùÿñ˽¡¸ÔéððïòïðìèåÞɱ©¾ÚòÿÿúüÿýüýÿÿöþüüÿÿþüüýÿÿßüÿÿûüÿýñÍ¿®§­»ÇÎÍÊĹ®©´Âßïþÿýýþÿþþÿþùÿþýüüýÿÿßþÿÿüýÿý÷þóãÕËļ·¼º»ÀÉÖè÷úÿÿþûüýýþþÿþþüüþýÿÿþþÿÿóúôìâÜÔ×âïûÿþÿÿüþûüÿÿþÿþüýþþÿÿþþÿÿèüýÿóöøúûúùøõôõùüûúøüûûüÿÿþÿûúûüþÿÿþþÿÿþýÿÿøþýööêõôôõõûùõðîðõøøúýÿÿþýýþþÿûö÷ùýÿÿàýþÿüöõø÷øø÷÷öö÷óùýü÷öõóøùüþýûþÿþþÿõü÷úþÿÿàþýüú÷ö÷óóôôõõôóîóõôõøùø÷ö÷úûûÿÿþþÿùöõõ÷ûþÿÿýýúøøçõôôõ÷øø÷óôóñóùú÷ùôó÷úùúýþþÿöùø÷ö÷úýÿþÿÿþ ÿõúööùûúùö÷øùùø÷õúøõóôöúýþþÿÿù÷úøúüþþÿÿþÿþþÿÿôýú÷÷ùúùøö÷øùù øõúù÷öö÷øùýþÿÿùôøùúûûýþÿÿþþÿÿþýüúùùøø÷þøùùøùøø÷÷öýýþÿÿúùùüýÿÿþþÿÿõþýüûû÷ùúúø÷÷øùøù÷úùø÷÷üüþÿÿúùøøúüþÿÿþÿÿöþüúúöøûúø÷÷øùúùøùúûýýþÿÿúùúûþÿÿþÿÿëþüûù÷ùûúù÷÷øùùøøùùúûúúùøöùúûüúûüýþÿÿùúöøûþÿÿþÿÿþÿÿûýûúùúúþùøø÷úùùøùùúûú úþùúúùûùúûýþÿÿùúôûøûþÿÿþÿÿþþÿÿüþüûúúù÷úùùøøùúûúúûúøùøùúûýþÿÿ ûüýþÿþýýüû û÷ùúûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿü üýþÿþûýüûûüüûùüýþþÿÿüüýþÿþûýüûûü!üúýþþÿÿüüýþÿþûýüûûü üýþÿüýþÿþûýüûûüüýþÿüýþÿþûýüûûüüýþÿ ýþÿþ#ýþÿýþÿþ!ýþÿýþÿþý þÿ þÿ'þÿ þ ÿ%þ ÿþþÿ ÿþþÿÿþ‡ÿî.ïû÷ðïó÷¾·ñÿúÿüüÿÿÂѳ×úöûúºÅºÄÂS7fh9e-O_Œíÿíñûÿù‹ooªùòüö¸¯öþüÿ' ÒøôóòõúȹëÿûÿýüÿÿÖ̺ßúïøÏ@B9?<$OtXFyNM{Z–ìúóöõÿÅxuäù÷úȯéþþ€` µüó÷òôüÒ¹áÿýÿþüÿÿúÂÀëøïÿÓ;FJM\k[I_fF)€®LT²ïÿîçòæ²MlÎÿñûݯØýÿý” ™ýîóìí÷Ú·Øÿþÿþýþÿò¸ÆññíÿÙ"Yhdh\VOasKC4¤ÝqBj´ðñóæõâ8r±ÿîöè®Ìþÿýž}ïâçåæíܲÒÿÿ‘üþýÿì±ÆðêåñÎ=JGGJJGW`8?$–üµgHh¯ùôàôÖGpÿíëå¬Èþÿý‘ yéÞßáàæÜ°Ðÿýÿüþýÿê±ÆêäàòÍ  <[! ‹ÿñ¶T6mÀïéìÖ=mƒôêåà«Éÿÿß~ŠíåÝãàåÛ°Òÿûÿüýýÿë´ÆäãÜõÊ  å6^" üóï“CFcÑöçÊ8h ìææà«Êÿÿãi ”îëàèâæÝ°Óÿùÿýýüÿí¹ÆáåÞð¸ ã_\˜ÿÚýì>?‡ãÕ‡TUÂøâêâ¬Ëÿÿ€‚6 ÍèàãâëæÑ±ØÿüþÿùÿýòºíéäîÄR?CE@%Lu›ÿâä÷Þ•PHްYcjÙèâñرÓÿþý(âòâäãÞìÊ·âÿûþýüþþûÅ´æêÛçíÌÚÖØâR$''kg¨ÿáÐàùÕŽWluwU´ïßâñÒ³Úÿÿþqôêßåêî_ïÿûýûÿûþÿϯØëíáèãòãêýÉ:75of}Õðúîüùà]wdXŒêíÝåîÅ·éÿþÿ²òãêãÜíæ°Êüþüþûÿüþÿß±ÅéíáåãíâçèöŒ+(:dZh~¶È¾i\UTzòñàðëä¶¿øÿüÿjßëçïåßêÓ®×ÿþþÿûþÿüÿñ¿¸âääêçëæåÖëëw 01V^^cZX]qW^…ëñææîíÑ­ÍÿÿúÿÕóçéäèõìÀ»çÿþÿÿýüÿüüþÕ¶ÑìêçäæåìæáõÕlC¬~A+8CCSŽÍØÿÙßãëåÁ¶áÿþúÿòéééàìïϵÔ÷ÿþÿþþüÿýùÿê½¼äîëëÌæìëðæùàseöòåÛÒ¿ÈéçüçÞõçãôÕ¶Ëøÿýþÿìèòèê÷å¾±æÿýýþüÿýýùøÿ÷Å®Ôìì€áëæçáðëçôï¾jžðõïíòëëïîÛôíÞïÿáǰÞÿýýÿÿêåêèðìɱàöûùÿÿúþþÿÿüþÿíÆ¸×ïñèäéñâéëéîøü÷ôîäàèòëÝìîõîãïìͨÞýýÿÿýÿëëêôøÒ²Åïÿÿûÿÿûþÿÿþúûÿúä²ÄäñæìñãìïíèèííçåîòìèêííëìêéöøØ¬ÆéýüÿÿþÿíúöðÚ°½óûÿÿûÿÿýÿþÿÿûúÿÿýÔ±½íüñììïóðìíðïéíïòòîíìëðïîùûص²êúýûÿÿ€†êøîÔ±²àýûÿþùýÿþÿüýþþüüþÿþͨÀéîéñèìíìïôôïìçäèïïìçåðõðÕ­³âÿÿþüÿÿþÿùêǵ¼ÞÿýûþüúþÿþÿýýþÿÿýúüþûΣ·çùöíîìéèìîîòòôòñðñôðøï̲¹Üýÿÿþþÿýýÿß̰¿ìÿÿþþÿÿûþÿÿýÿÿÍýÿùÿøÔ´¾ÙäüüùóïîñóñóôóïññðúáĵÂåþþûüýÿÿüýÿ¯ºÎêÿÿôøÿ ÿÖþÿÿýÿÿøþÿÞ±«½àèò÷öôôøööõöýÿõçϵ­ÅçþÿþüûüþÿÿîÁ×ÿÿ÷ÿÿýûûýÿþþÿÿûÿÿàüøýÿÿùùÿñ˽¡¸Ôéððïñóõñêçàɱ©¾ÚòÿÿúüÿýüýÿÿöþüüÿÿþüüýÿÿßüÿÿûüÿýñÍ¿®§­»ÇÍÍÊù®©´Âßïþÿýýþÿþþÿþùÿþýüüýÿÿßþÿÿüýÿý÷þóãÕËļ·¼º»ÀÉÖè÷úÿÿþûüýýþþÿþþüüþýÿÿþþÿÿóúôìâÜÔ×âïûÿþÿÿüþûüÿÿþÿþüýþþÿÿþþÿÿèüýÿóöøúûúùøõôõùüûúøüûûüÿÿþÿûúûüþÿÿþþÿÿþýÿÿøþýööêõôôõõûùõðîðõøøúýÿÿþýýþþÿûö÷ùýÿÿàýþÿüöõø÷øø÷÷öö÷óùýü÷öõóøùüþýûþÿþþÿõü÷úþÿÿàþýüú÷ö÷óóôôõõôóîóõôõøùø÷ö÷úûûÿÿþþÿùöõõ÷ûþÿÿýýúøøçõôôõ÷øø÷óôóñóùú÷ùôó÷úùúýþþÿöùø÷ö÷úýÿþÿÿþ ÿõúööùûúùö÷øùùø÷õúøõóôöúýþþÿÿù÷úøúüþþÿÿþÿþþÿÿôýú÷÷ùúùøö÷øùù øõúù÷öö÷øùýþÿÿùôøùúûûýþÿÿþþÿÿþýüúùùøø÷þøùùøùøø÷÷öýýþÿÿúùùüýÿÿþþÿÿõþýüûû÷ùúúø÷÷øùøù÷úùø÷÷üüþÿÿúùøøúüþÿÿþÿÿöþüúúöøûúø÷÷øùúùøùúûýýþÿÿúùúûþÿÿþÿÿëþüûù÷ùûúù÷÷øùùøøùùúûúúùøöùúûüúûüýþÿÿùúöøûþÿÿþÿÿþÿÿûýûúùúúþùøø÷úùùøùùúûú úþùúúùûùúûýþÿÿùúôûøûþÿÿþÿÿþþÿÿüþüûúúù÷úùùøøùúûúúûúøùøùúûýþÿÿ ûüýþÿþýýüû û÷ùúûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿü üýþÿþûýüûûüüûùüýþþÿÿüüýþÿþûýüûûü!üúýþþÿÿüüýþÿþûýüûûü üýþÿüýþÿþûýüûûüüýþÿüýþÿþûýüûûüüýþÿ ýþÿþ#ýþÿýþÿþ!ýþÿýþÿþý þÿ þÿ'þÿ þ ÿ%þ ÿþþÿ ÿþþÿÿþ‡ÿî.ïû÷ðïó÷¾·ñÿúÿüüÿÿÂѳ×úöûúºÅºÄÁeEdX!\E";JpÔùôüÿôò…EDýóøõ½¶þÿüü' Òøôóòõúȹëÿûÿýüÿÿ€¹ÌºßúïøÏ@B9?;3[oE-V0 CkHIK1žèåâñÒ³Úÿÿþqôêßåêî_ïÿûýûÿûþÿϯØëíáèãòãêýÃ5 3="aÅðÿÿ€ÔíÆ0TD2bÌâàåîÅ·éÿþÿ²òãêãÜíæ°Êüþüþûÿüþÿß±Åéíáåãíâçèú… ) /.@^—«¢tM+8?]ÒÞÛóëä¶¿øÿüÿjßëçïåßêÓ®×ÿþþÿûþÿüÿñ¿¸âääêçëæåÖùæb7")69;.,:T3IvÚçêñõíÑ­ÍÿÿúÿÕóçéäèõìÀ»çÿþÿÿýüÿüüþÕ¶ÑìêçäæåìæïôÆ] IŽe*&A}ÀÐýßîòòåÁ¶áÿþúÿòéééàìïϵÔ÷ÿþÿþþüÿýùÿê½¼äîëëÌæìëïáôÜpcêíáй¥¹èãõââÿïçöÕ¶Ëøÿýþÿìèòèê÷å¾±æÿýýþüÿýýùøÿ÷Å®Ôììòëæçáâæëùî²Y‰ëÿÿ€Ñöèì÷ñÙóöåë÷ÝǰÞÿýýÿÿêåêèðìɱàöûùÿÿúþþÿÿüþÿíÆ¸×ïñèäéñâéëéîùü÷ôîåàéóìÞìîõîãðìͨÞýýÿÿýÿëëêôøÒ²Åïÿÿûÿÿûþÿÿþúûÿúä²ÄäñæìñãìïíèèííçåîòíéëîîëìêéöøØ¬ÆéýüÿÿþÿíúöðÚ°½óûÿÿûÿÿýÿþÿÿûúÿÿýÔ±½íüñììïóðìíðïéìïòñïîíìðïîùûص²êúýûÿÿ€†êøîÔ±²àýûÿþùýÿþÿüýþþüüþÿþͨÀéîéñèìíìïôôïëæäèïðíèåðõðÕ­³âÿÿþüÿÿþÿùêǵ¼ÞÿýûþüúþÿþÿýýþÿÿýúüþûΣ·çùöíîìéèìîîññòòñðòõðøï̲¹Üýÿÿþþÿýýÿß̰¿ìÿÿþþÿÿûþÿÿýÿÿèýÿùÿøÔ´¾ÙäüüùóïîñóðòóòïññçúáĵÂåþþûüýÿÿüýÿ¯ºÎêÿÿôøÿ ÿÖþÿÿýÿÿøþÿÞ±«½àèò÷öôôøõõôöüÿõçϵ­ÅçþÿþüûüþÿÿîÁ×ÿÿ÷ÿÿýûûýÿþþÿÿûÿÿàüøýÿÿùùÿñ˽¡¸Ôéððïñòôïéæßɱ©¾ÚòÿÿúüÿýüýÿÿöþüüÿÿþüüýÿÿßüÿÿûüÿýñÍ¿®§­»ÇÍÍÊĹ®©´Âßïþÿýýþÿþþÿþùÿþýüüýÿÿßþÿÿüýÿý÷þóãÕËļ·¼º»ÀÉÖè÷úÿÿþûüýýþþÿþþüüþýÿÿþþÿÿóúôìâÜÔ×âïûÿþÿÿüþûüÿÿþÿþüýþþÿÿþþÿÿèüýÿóöøúûúùøõôõùüûúøüûûüÿÿþÿûúûüþÿÿþþÿÿþýÿÿøþýööêõôôõõûùõðîðõøøúýÿÿþýýþþÿûö÷ùýÿÿàýþÿüöõø÷øø÷÷öö÷óùýü÷öõóøùüþýûþÿþþÿõü÷úþÿÿàþýüú÷ö÷óóôôõõôóîóõôõøùø÷ö÷úûûÿÿþþÿùöõõ÷ûþÿÿýýúøøçõôôõ÷øø÷óôóñóùú÷ùôó÷úùúýþþÿöùø÷ö÷úýÿþÿÿþ ÿõúööùûúùö÷øùùø÷õúøõóôöúýþþÿÿù÷úøúüþþÿÿþÿþþÿÿôýú÷÷ùúùøö÷øùù øõúù÷öö÷øùýþÿÿùôøùúûûýþÿÿþþÿÿþýüúùùøø÷þøùùøùøø÷÷öýýþÿÿúùùüýÿÿþþÿÿõþýüûû÷ùúúø÷÷øùøù÷úùø÷÷üüþÿÿúùøøúüþÿÿþÿÿöþüúúöøûúø÷÷øùúùøùúûýýþÿÿúùúûþÿÿþÿÿëþüûù÷ùûúù÷÷øùùøøùùúûúúùøöùúûüúûüýþÿÿùúöøûþÿÿþÿÿþÿÿûýûúùúúþùøø÷úùùøùùúûú úþùúúùûùúûýþÿÿùúôûøûþÿÿþÿÿþþÿÿüþüûúúù÷úùùøøùúûúúûúøùøùúûýþÿÿ ûüýþÿþýýüû û÷ùúûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿûûüýþÿþýýüû ûúùûüýþÿÿü üýþÿþûýüûûüüûùüýþþÿÿüüýþÿþûýüûûü!üúýþþÿÿüüýþÿþûýüûûü üýþÿüýþÿþûýüûûüüýþÿüýþÿþûýüûûüüýþÿ ýþÿþ#ýþÿýþÿþ!ýþÿýþÿþý þÿ þÿ'þÿ þ ÿ%þ ÿþþÿ ÿþþÿÿþ‡ÿÿþÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3@ÿRÿþûÿþýýÿÿþþÿ1ÿþÿþüÿÿýüýÿ!ÿ@ÿRÿþûÿþýýÿÿþþÿ1ÿþÿþüÿÿýüýÿ!ÿ@ÿRÿþûÿþýýÿÿþþÿ1ÿþÿþüÿÿýüýÿ!ÿ@ÿYý <û•©q9ø ×Ðܺk8÷陕ÀÚ»j 5ôè‘——µÝ°^ 4ôé‘’‘Œ’´Ô»V3ò呎ŒŠŽ’«Ú°=1ðä‘ŒŠŠŒŽ‘—ŽÂÛ 4/î┎’’‹™‰‡—ÂÔ”%-ì埙››œ—”‘ž›‹” ÍÐ+êÞž–››š“œ£ ››–“®ÇÎ})êÝ«¥¨¦§£¨ ž¦§ ¥°¤¨ Ùíf)êðÙÚÜ×ÚÙáØÕÚßßÛÙÕáãЉ$)ëùøÿÿýÿÿüüÿÿýûüÿÿúÂ\*íøöøöô÷ôêòôîî÷üû³] ,ïíêççèâçâÞÝìÿý¹l-ðèÛÑÙáÔÝÐÞöüÐv0óèÝÍÇÇÃÈñø×1ôçËÎËÍéÿÙ‰$4÷ñÜÉÚýâ+5øÚñÿáŸ78û×îª8:ü#Àÿ@ÿDÿþ<ÿþ8ÿ@ÿDÿþ<ÿþ8ÿ@ÿDÿþ<ÿþ8ÿ@ÿKù6984(ø42-/1 -í3¶ìííð¶*=Ôñøðè² ,í_˳–¥À´"IÒµ›µâ$ü íwÕ¡ž³°"Aͧ—“•ð-ù‰¦°¶°ípÀ”—›¬±'CÏ ’ž…è/ù>××»¼¸ívÅ“‹±©#DÏ™‰‘zß)ùHÄŸˆšítÆ’Œ‹¨® BÊšŒŠŒÜ+ùLÅžŒíl»‹ŠŠ¤«"FΙˆ‹‰ß.ùHáˆým••ò«¯%FÑžŽ–Œä/ùG䈎ísÊ›–š¯¯$BПŒ—‹ã,ùJÈªŽ–žíqΤž¡µ¯ AÓ¬™£šç,ùIιž¤©írçÓÑÑܼ@äÙÒ×Íú,ùIÜßÐÒÓíuÿþýùÿË=íüÿÿùÿ)ùKíÿüþÿíuÿþø÷ÿÎ8æøúøûÿ%ùLèöèæçírúòãñþ½?åôêîæû4ùKçèÔÝÕíqîìÞÞæ¸@åèÙÜÜù2ùGÞÛÀÍÕíwâÔÊÑê¹<ãâÓÏËó.ùHßåÂÂÊíxäÕËÎâ½BêÜÆÏÄø1ùKåÿûøûísçØÍÔçºAäÚÉÍÊÿ+ù!º¾¿ÃítòèÒÕá¿ Héç×ÎÚø'úýL×ÿÿòþÐ/Iêÿýÿ÷Ê-ù*915?1ù82528%dÀÿ@ÿjÿþ<ÿþÿ@ÿjÿþ<ÿþÿ@ÿjÿþ<ÿþÿ@ÿÀ ý ü N*üR;û'}^¯¯û²©ú)÷Ðxú!âÝqûjÿÚD¾¾ûÃÇÓ5ù6ÎÑÍ›>øAÔÄѶJû[ãÉW‘‘’û“Ï4î6Ú‹†ÊÏx-щÀÉŽøeçÅ]’‘ŽŽû’ŒÏ8â3׎|ˆœË¹#G½¦†šÅßRi߯fŽŽŒŒû‘Ò<æ3Ôš‘“ŠšÇ¿Å㕊ˆ”¨Î‘$YÜÏK‘‘þ’‘‘ú–™Ô;ä3Ξ‘’•‡Š‘ÝÜŒ‘Ÿ‰”ŸÈ¿[sÝÇQ•–——–û•œÑ5Ú3Ø©•Ž¡£”мӠ—›—“‹Ÿ¬Óäͺb¡£¤¥¥¤¤£¡«×4æ3Ò§§¥¦ŸžšÆÝµœœ¥§ž£¨”©ÓèØPÔÔþÕÔÔúÓØÚê6â3ïÑ×ÔÐÎ×ÏäíØÒÔÔØÙÑÊ×ÓÞóÑeþýýüûûü÷ö5ï3öþÿþÿüÿüüþûÿÿþüÿÿíûþÿÿéYîíêéèèééêìí2æ3öûèá÷êñüûúðçíóñçøü÷éXÕÕû×Ùì7æ-ñäÝÛÐÛóíäòÕÛáÕÔêýÉkLüèVÍÍÏýç7æ5äâÓÆØÿÝp\æçÉÆÜôá‹,jÿçfËËüÓå4í3íÈÇîï¹W!ÙÔÈéñÆUûbúáb÷÷ûûÿî;ï4ðööÙ~8ãïùç†/ûbÿæWÃÃÀý‘ú4ü÷¬Bú3îÿ±LûhÿïXü#û•f û‚vûH» ;þÀÿ@ÿ?ÿþÿþ#ÿþÿþ%ÿ@ÿ?ÿþÿþ#ÿþÿþ%ÿ@ÿ?ÿþÿþ#ÿþÿþ%ÿ@ÿÙüMvDüX üW %û»ÿ›ú a»ö`ú [»øg%û1ÀñŒù*—ÒÅçVù,„ÄÔÍx%û)²ê›îlÄÍ™wÕeaÉÔ›’¿o%æ)´é– IµÍ©Œ‰Ñ]$šÍ²‹‹¹u%æ+°ð…ˆ»µ¤ŠŠŒ×ůǪ‹‚Š–Àu%æ*¶á[©Ùª—–š‡Ïß¡…Ž›œœÃu%æ,µÙÞÓÅ Š’™›•—”ÏÉ” “žÏu%æ ¸âßµ•”¯ª£œ£¤×Ë™Ÿž¨žœ¦Æu%æ+ÕûçÒÓÊËØÐÐáÜÇïãÕ×ÑÕÎØÞêu%ê(Òÿúýÿúÿþýÿÿýôÿþÿýýÿüÿÿþu%æÓýµŒÔÿûíéôæñôòýûìäïæïôúu%æ%Úÿ‡<¸øïÙÜÙáÏùåèúáÐßÝÞïk%æ1Æÿ•jåîßÉÐÕîv\ÏÿáÃÄ×åt%û#Êÿ”î-©ïêÉÍôG4–åôÔÐæw%û$×÷•ï _ÙöâûgeÃìóé%ûÑÿŸú2ŒïÿWú%Žçÿt&ül³gûV†.ûRŽ3'ý£Àÿ@ÿGÿûþÿýüÿÿþýÿÿýüûÿÿüÿþýÿ(ÿêþüÿÿüýøÿÿüÿÿþþüÿÿýþüüÿ ÿ@ÿGÿûþÿýüÿÿþýÿÿýüûÿÿüÿþýÿ(ÿêþüÿÿüýøÿÿüÿÿþþüÿÿýþüüÿ ÿ@ÿGÿûþÿýüÿÿþýÿÿýüûÿÿüÿþýÿ(ÿêþüÿÿüýøÿÿüÿÿþþüÿÿýþüüÿ ÿ@ÿÔþ8ø5zÀáÛ_û%',íL’áÔ²³ÐbW_ž«ÙÝ^*ìtÉÍŸ‘ ÃVqñȸÏÔM*ë•⺆‹¥¼ÍËUkå|¦Î[)éŽá¨u–Ó¶’fFb×}…¾Ý[þ ÷]ׯvŸÒ—CöaÞ¡Ÿ‡ˆ®×4ö®³³±±¥sø)±ºi¦Ü|õVô¶º¾Ž‡Æ•ö3ÊáÆ¿ËÃÎâùxÈ†ŽØˆõlÍ3¯Æ|‘ÏSö%®ááÒÈÇ˦ø²È‡¼³)õ>`Ä¡†Ù{÷"$%%$F•Òù4®Ë| øªÂŽ»™ ý“ùcÈ›©ÇH ùxʨ½)þ ùfܤÂÊ" ù^ש±Õ4#ùgñÐåÊ ùSîÓÔÝ)#ùlüÿÿÚ9 ùbüýþá##ùDéÿùñ` øœÿúüÊþeøËøâÿª ù5çûáþø  sÞùžÿÚííV ù„ùåçùVöª§¤ž£×ÿøFäðÄøÒ9 øhççÑú¾ ýCåÿÿþô÷…ÿׯúÅ>÷}êîÀåìTö4ÏÚÔÍÎÔÇšé¿úÂÅÞÝ—M)X£éÝ»Ôö‹ö<6-)%*$ ê7ÂýÜÇÙã㤓œÀÞöÔÀéô£*ìCÈôãÑÜÛÜíðêîÞÛÎîò›!,î”ìúæçêÞÞãÔáêüãe.ñ*šÝûòôôòÿÿÎp3ö=eŠ“vX(åÀÿ¸ÿþ€ÿMÿþ#ÿùýþÿÿþþÿÿþÿþÿüþýþÿÿ¸ÿþ€ÿMÿþ#ÿùýþÿÿþþÿÿþÿþÿüþýþÿÿ¸ÿþ€ÿMÿþ#ÿùýþÿÿþþÿÿþÿþÿüþýþÿÿ@ÿ5þ<üjÝ ýD8!ù £ðЦû>±›. û¦ÇDø£îŽ™Êú ¦èû ûžøË^ø‘Ù—}µËCú|ßÉÙôe¥¤´µ›²Ü~îQΕ‚š—Ê9J1P–ÆkóaÈÉÆÊº©Š|µòrìÓ£Œ“‚™Õ['ÅäK—ÏwòbDZÏÒáÚÄ‹ä’×Gl€®ÀŸ“•š¾]cÏĨÉV\Æ¿ÏNÔÝ£+ð Ǹ¹¾›Œ‘™•ŸÇmñ/ÄhŬÕJNÈźUûŸô¨ðŸ¿¡¡’œ  ™£Î}óŸ…ª¹»å÷ÔÈfü©µñ—Þ¡£  ¤¥¡ž¨Íxôh‹ŸÙíÿîpýB'ñžäÊÍÍÐÅÈËÍÏÓátôH›mÿÿùí"þü«ÿúÿÿýþýþþýûxó^  lðòüôíÒ*ü–Šþªÿÿý÷ùôø÷ôúûrò—‘êòì~›ýüÇ#ü«ÿñšììéïýåäììåîòhéÂmíø¦ÿÿ±! œÿø‚ç*MTGTšèÔâÓÑîåWFÀÛ*ê–ñ›÷÷ËŸ‘¥Øèþê„ íÞèÆÉÏÒêT!Øÿm~›óŸýÿûÿþéÅÄøøfî]èÞÉÔÝì9xX4tÙ󔺯´ÅÍËÝû´/ø ôÞÀÛã4ûWÎìÿö¡ÿóˆø!¯ÿÝäÔ#û±ÿÿØ ü§üt ù)²öÿËûiŰS üj]"ú}»‰ý4ýHÀÿ ÿþÿkÿ6ü ÿÿûãÔÜçÿÿ1ï!98ñÚÞáßßÚÛÓúÿÿ+ì.(Gk¡ÿØàèÕáññâÉÅÿ+õEoèÿϺÿÿúÁ¹Öÿÿ(ô H”çÐó×ÿúäÐÎßÿ)ô§ÿ5Ú²ÿûÿ©ÿ›)ó8¿ùc$kôÃËþûÉì¤ÿ'ñ aã·0ÿõĶÿûÿÂä÷'ðŒÿ›ÿÿÍ»ÿÿûÿºÿÃ(ùŠÿùÿçÑäÿÿûÿÎÿÁ(ù kø”ÿõ×ÊÒÿÿÆßÍ(÷XòºôÿÛÂËÿÿÆÐÿ(÷GÑüDõÿñö¡ÿÿ®íÅÿ*ù=“ÿ“ZBÿ÷ÐÑØÿÿá×ÿ'ö%`Àø­wøñïÿÿÕÅÿ(êÿ .oÍÿÙÿÿÿÿâäÿî¤Å)ëÿ€8mÄòëæÿôîäß·Îðô,þ$ò$Nÿç×ÝÚÛÍÏÀÖÿ3ÿúôëíÿúÿÿsý£WYÿþ ÿþþÿÿþþÿ(ÿþÿþþÿÿ ÿþÿ&þ^ þÿ/ýbþ-3ð.Y6#!"2:®.î PC?=7432/+,í. %XHONBA>=4! /ø 3] Cø:L",ÿ,ø !55ú6&1=ˆ(ó.('+,û/#18)ó/, ,+=qû3,$ÿ(ó /* D85+ûq!6(ñ4) !.ÿX8$Zûÿ $(ð1'!%ÞM )ÿûÿ '÷2 óþ1$^ÿÄ -'÷ 4" ôf.0DvW!"\'÷3& õ‚CKGˆÿ-)-ÿ'è"5&ÿÿe4X<1dÿ*ù0C2 ø8;=6AÂ(êÿ &FV2hÿõ*]>#5Ÿ)ýÿ=ð#>/5BRTPA2O.'n-ñ L5" *5?=s/ñ ÿ\"!!#@Uÿ0û4 <ýÄWYÿþ ÿþþÿÿþþÿ(ÿþÿþþÿÿ ÿþÿ&ýŽþÿ/ýFý^"4ý*;ý þÿ=þ+ý;ü;ü;ü ;þþþ0þýP5þ ý95þ ý5þý5þþ'5ý%þÿ3ü =ý <ü;û% ;ú :ûo. —Yÿþ ÿþþÿÿþþÿ(ÿþÿþþÿÿ@ÿ&ý þ/ûáxü 3ð;¶Ûã–+D^w„}p`? þ2í1žÎ«®È©»ÀÉÐÎÐ˱{5 ý¥ ì±ÈŒ®³”‘š‡z~{{€¹²< ýÚ?õ{ʪ’°bŽs øYŽ Büæô<ͤ•®¤™É©Œ+úF“¶‘2üÙÐîvtw{xļ•öèÅ–4û3¶”mü¬Ó!ìÔɼÀ¬™Ž©»›¹Þ—€ÆŽ'ûŠ ˆ üjÍ=ë Ó©’œž¤¤²»ÂÀÔc@»Ñq ûCÀ‰5üGÒUê׬ §¨±¸¬´Õ»áhuʸYûÊ…büDèhéÚÍÎË¿ÎÒÔÀ¾ïÝÿe!|Ķ^ û ½žjüFí`ü éüÿÿëâÄøÿÿNˆ×ºi*ϰYühè=ðìÿÿýüöüÿâ¾ÚÿüSô/™ÝÜRPÙ¨4ü§ððÜïïòîÿôððЬñÿXõ9¹ÿ³1 ½¡Ûþâ=YPHRÒÿÕþá›Þÿ_ A ´¥šÂÍoý÷ öDçéÐñ¾©íQø8¯°µÉŸ*ýþRêŠñÛÜñØÎ–T*?ùǫ< ý»ë»ÿÐçÿÝåↂˆ—¬åØ”; þDî<ËÿêíÑ®Éèíóðíݪ‚,.ð=Ñÿÿ 4bx‡…~`.0û+‘Ôk<ý'WÀÿ ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ4 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ4 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ4 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿþ8ø5zÀáÛ_û%',íL’áÔ²³ÐbW_ž«ÙÝ^*ìtÉÍŸ‘ ÃVqñȸÏÔM*ë•⺆‹¥¼ÍËUkå|¦Î[)éŽá¨u–Ó¶’fFb×}…¾Ý[þ ÷]ׯvŸÒ—CöaÞ¡Ÿ‡ˆ®×4õ®³³±±¥sø)±ºi¦Ü|õVô¶º¾Ž‡Æ•õ3ÊáÆ¿ËÃÎâkùxÈ†ŽØˆõlÍ3¯Æ|‘ÏSô%®ááÒÈÇ˦Ïwø²È‡¼³)õ>`Ä¡†Ù{ô"$%%$F•Ò¨ÉVù4®Ë| øªÂŽ»™ ú“ŬÕùcÈ›©ÇH ùxʨ½)û ª¹»ùfܤÂÊ" ù^ש±Õ4üŸÙùgñÐåÊ ùSîÓÔÝ)ýmÿùlüÿÿÚ9 ùbüýþá#ülðòùDéÿùñ` øœÿúüÊûeêòìøËøâÿª ù5çûáþõ  sÞíøùžÿÚííV ù„ùåçùVôª§¤ž£×ÿê–øFäðÄøÒ9 øhççÑú¾ ýCåÿÿýô›÷…ÿׯúÅ>÷}êîÀåìTõ4ÏÚÔÍÎÔÇšé¿úÂÅÞÝ—M)X£éÝ»Ôö‹ö<6-)%*$ ê7ÂýÜÇÙã㤓œÀÞöÔÀéô£*ìCÈôãÑÜÛÜíðêîÞÛÎîò›!,î”ìúæçêÞÞãÔáêüãe.ñ*šÝûòôôòÿÿÎp3ö=eŠ“vX(è ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3ýD8û¦ÇDûžøË^ôe¥¤´µ›²Ü~óaÈÉÆÊº©Š|µòr òbDZÏÒáÚÄ‹ä’ ò\Æ¿ÏNÔÝ£+ ùJNÈźUûŸô¨ úå÷ÔÈfü©µ ûíÿîpýB'ûÿùí"þúüôíÒ*ü–Šù~›ýüÇ#ü«ÿó¦ÿÿ±! œÿø‚ñ›÷÷ËŸ‘¥Øèþê„ óŸýÿûÿþéÅÄøøf󔺯´ÅÍËÝû´/ö¡ÿóˆü§ütüj]Ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþúýþÿÿþÿÿþÿúþüÿþýþþÿýüþÿÿýþþÿÿþÿþüþýÿÿöüÿþýüüýþþÿÿþÿþþÿÿüþýþÿÿýýþÿÿþýýüÿÿ÷ýÿÿýýÿÿûüüýþ÷ÿýúúýÿþüÿÿþÿòýÿÿþýþÿþûùþÿþÿÿúýþýüüýýþþÿ ÿþþÿÿßýÿþûÿÿúÿýüÿÿþýÿüýýüúûþÿÿüûýþüþÿýþþõýüüùüþÿýýþÿÿîýÿþûÿÿñôðïôÿÿüí÷ûÿÿùþýýÿþýþþÿðýüüþþýüýþÿþüúúûÿÿÜûÿÿüÿüæÑÜÝÙéÿúáô÷ýÿýúùúøþþùøüûõÿÿüüÿÿüÿÏþúÿÿþÿùÞ×îíÖÚö÷ÜôòîéçëôüîýÿòñúõæúòììóúûûðéãéôþÿýÿÿÏýÿúÿüýÿáÖÿÿÛ×ÿûÐùèÚàÏÉé騸ôÍåÿåÛìïÚÔÕàú÷ÏÓáÜÞõþ÷ÿÿÏýÿûÿýýÿàÐã×ÛéýïÔäþÿùÞ×ôùÓïíËÚöáÚý÷ééÝÝ÷õÔàðâÛöüêÿÿÏþÿûÿÿþýß×ÛÌÞôÿôÙÛÿøàÙãùøÛßä×ÝäÜéüåÝåÒÑõüÜîÿìÛ÷úÜÿÿþüÿÿÕûáÛôäÙàÿøÑìÿéÙîÿÿþéÍÖíéÑÒûðØäÿéÛïìÛïÿñÙðñÑÿÿþýÿÿÕûèÖÿùÝÌêîÑêóÚÐæîñÿîÈÒøðÌÑÿôÓ×íàÚïñÚçýðÚèèÒÿÿþÿÕûòáÿÿùßäîëíêØÕßÛàúôÜåý÷àåÿÿáÕÙÖàøÿçëý÷êïîåÿÿöþÿÿüýÿþûøÿÿìøöüþÿýûÿÿü÷ÿýøùÿýùýÿÿû÷øùÿÿûþùûÿÿúþÿÿûüÿÿõöÿúÿÿõÿúþÿþþÿëýþÿÿýöÿÿøýÿûÿþþÿþÿÿüÿÿþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿÿýþúýþÿÿþÿÿþÿúþüÿþýþþÿýüþÿÿýþþÿÿþÿþüþýÿÿöüÿþýüüýþþÿÿþÿþþÿÿüþýþÿÿýýþÿÿþýýüÿÿ÷ýÿÿýýÿÿûüüýþ÷ÿýúúýÿþüÿÿþÿòýÿÿþýþÿþûùþÿþÿÿúýþýüüýýþþÿ ÿþþÿÿßýÿþûÿÿúÿýüÿÿþýÿüýýüúûþÿÿüûýþüþÿýþþõýüüùüþÿýýþÿÿîýÿþûÿÿñôðïôÿÿüí÷ûÿÿùþýýÿþýþþÿðýüüþþýüýþÿþüúúûÿÿÜûÿÿüÿüæÑÜÝÙéÿúáô÷ýÿýúùúøþþùøüûõÿÿüüÿÿüÿÏþúÿÿþÿùÞ×îíÖÚö÷ÜôòîéçëôüîýÿòñúõæúòììóúûûðéãéôþÿýÿÿÏýÿúÿüýÿáÖÿÿÛ×ÿûÐùèÚàÏÉé騸ôÍåÿåÛìïÚÔÕàú÷ÏÓáÜÞõþ÷ÿÿÏýÿûÿýýÿàÐã×ÛéýïÔäþÿùÞ×ôùÓïíËÚöáÚý÷ééÝÝ÷õÔàðâÛöüêÿÿÏþÿûÿÿþýß×ÛÌÞôÿôÙÛÿøàÙãùøÛßä×ÝäÜéüåÝåÒÑõüÜîÿìÛ÷úÜÿÿþüÿÿÕûáÛôäÙàÿøÑìÿéÙîÿÿþéÍÖíéÑÒûðØäÿéÛïìÛïÿñÙðñÑÿÿþýÿÿÕûèÖÿùÝÌêîÑêóÚÐæîñÿîÈÒøðÌÑÿôÓ×íàÚïñÚçýðÚèèÒÿÿþÿÕûòáÿÿùßäîëíêØÕßÛàúôÜåý÷àåÿÿáÕÙÖàøÿçëý÷êïîåÿÿöþÿÿüýÿþûøÿÿìøöüþÿýûÿÿü÷ÿýøùÿýùýÿÿû÷øùÿÿûþùûÿÿúþÿÿûüÿÿõöÿúÿÿõÿúþÿþþÿëýþÿÿýöÿÿøýÿûÿþþÿþÿÿüÿÿþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿÿýþúýþÿÿþÿÿþÿúþüÿþýþþÿýüþÿÿýþþÿÿþÿþüþýÿÿöüÿþýüüýþþÿÿþÿþþÿÿüþýþÿÿýýþÿÿþýýüÿÿ÷ýÿÿýýÿÿûüüýþ÷ÿýúúýÿþüÿÿþÿòýÿÿþýþÿþûùþÿþÿÿúýþýüüýýþþÿ ÿþþÿÿßýÿþûÿÿúÿýüÿÿþýÿüýýüúûþÿÿüûýþüþÿýþþõýüüùüþÿýýþÿÿîýÿþûÿÿñôðïôÿÿüí÷ûÿÿùþýýÿþýþþÿðýüüþþýüýþÿþüúúûÿÿÜûÿÿüÿüæÑÜÝÙéÿúáô÷ýÿýúùúøþþùøüûõÿÿüüÿÿüÿÏþúÿÿþÿùÞ×îíÖÚö÷ÜôòîéçëôüîýÿòñúõæúòììóúûûðéãéôþÿýÿÿÏýÿúÿüýÿáÖÿÿÛ×ÿûÐùèÚàÏÉé騸ôÍåÿåÛìïÚÔÕàú÷ÏÓáÜÞõþ÷ÿÿÏýÿûÿýýÿàÐã×ÛéýïÔäþÿùÞ×ôùÓïíËÚöáÚý÷ééÝÝ÷õÔàðâÛöüêÿÿÏþÿûÿÿþýß×ÛÌÞôÿôÙÛÿøàÙãùøÛßä×ÝäÜéüåÝåÒÑõüÜîÿìÛ÷úÜÿÿþüÿÿÕûáÛôäÙàÿøÑìÿéÙîÿÿþéÍÖíéÑÒûðØäÿéÛïìÛïÿñÙðñÑÿÿþýÿÿÕûèÖÿùÝÌêîÑêóÚÐæîñÿîÈÒøðÌÑÿôÓ×íàÚïñÚçýðÚèèÒÿÿþÿÕûòáÿÿùßäîëíêØÕßÛàúôÜåý÷àåÿÿáÕÙÖàøÿçëý÷êïîåÿÿöþÿÿüýÿþûøÿÿìøöüþÿýûÿÿü÷ÿýøùÿýùýÿÿû÷øùÿÿûþùûÿÿúþÿÿûüÿÿõöÿúÿÿõÿúþÿþþÿëýþÿÿýöÿÿøýÿûÿþþÿþÿÿüÿÿþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿÿüþýÿÿøüûúýÿþþÿÿåþÿÿýÿÿüüþþýþüþÿÿûûÿÿýýÿÿþþÿÿþþÿÿûþýýþÿÿøþÿÿýüýüÿÿûýûýüýýþÿþÿþþÿÿþþÿ ÿüüýýþþ ÿýþÿþÿþúÿþÿíþýÿþÿÿþûþýùúÿÿýüýþýýúüûÿÿþÿ ÿïþýÿÿýþÿÿþÿøúÿûüþÿÿêþÿþýüþûþÿüûýýþÿýúûþþüÿÿûþÿÿþÿÿüþýüýýþþÿÿùûÿÿüúþýýûùÿÿ÷ýýüðþûÿÿüûýúÿýýÿÿýüþþøýüüýýþþýýþýþþÿÿÍúìñþüûþþÿÿüÿðèÿÿûýþÿþþÿÿþûÿÿüÿþñæèòýÿýýÿýúúýýûüÿüþÿÿþÿûíÖÙôÿÿáûüö÷þäÛûûúýÿþúùüÿþõöøúÿúßÓÞíúýüüöþùûÿÿýüÿüÿÿ€îüúþÿÿûùúþÿÿþêÉÊëþÿüóéäðÿèÜõæõùúöñìîñûîëîöÿôÎÛìûÿÿýùóïêîûüòïöøûýùòíïóöóðôýÿÿþÖææÖøÿëÙçß×õëÇÑÜÞæÿëËÎÓçéáÞÕÖøõ¿ÜéöûýÿðÕÛÖáôêØßãÒòÿÍÔÛ×ÒØàÚ×üÿýÿßòìÔõÿàÄóùóþçÑòøßÞþêÓéñÿøìêÝÑìøÖæóýÿÿòá×ôìðíÓÔðîÓêÿÕÞîêÑàïäÖøþúýÆâßÃäÿî×ÙãèÿëÚÿüåÙýéÔùÿÿáÙàÚÖõþÓòÿÿ€øí×ÛÿýÿöÓäÿÿÔâýÞçÿýÐèÿòÖöÿþþÎçêÌ×úÿùëÙÒùéØÿûæÖþèÑúûîÒãùëÙöÿÑñÿ÷ïýòÙÛÿýýìÌÝÿþÒßõÜçÿþËåÿõÓñÿÿþùþÿèÑãëã÷ßÓ÷êÖþüäØýêÔúüðÝãëÞÔðöÏëþêÙóúâØêèêìÞÛëìÕçòÛæüóÎáüóÓìýÿüÿúÿüâçâØÛáéÿôåýûðçþðâüÿþðØÍÔãùøßóÿïÞõÿòáÌÕÞòöâÙÙéúûéòýõäïþûåôýÿýúôúÿýÿø÷ëúÿÿþöýÿýùÿùõýýÿÿøôûÿÿëþÿúöþÿþ÷÷þûÿÿúõôûÿÿùÿÿøúÿþÿøÿþÿÿùþ÷üÿÿøÿÿÔýüÿÿúþþÿýþÿýøýÿÿþþÿþüÿüøýÿÿùüÿüÿþüýýÿüýýûýýÿÿøöþþÿúÿýþþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿüþýÿÿøüûúýÿþþÿÿåþÿÿýÿÿüüþþýþüþÿÿûûÿÿýýÿÿþþÿÿþþÿÿûþýýþÿÿøþÿÿýüýüÿÿûýûýüýýþÿþÿþþÿÿþþÿ ÿüüýýþþ ÿýþÿþÿþúÿþÿíþýÿþÿÿþûþýùúÿÿýüýþýýúüûÿÿþÿ ÿïþýÿÿýþÿÿþÿøúÿûüþÿÿêþÿþýüþûþÿüûýýþÿýúûþþüÿÿûþÿÿþÿÿüþýüýýþþÿÿùûÿÿüúþýýûùÿÿ÷ýýüðþûÿÿüûýúÿýýÿÿýüþþøýüüýýþþýýþýþþÿÿÍúìñþüûþþÿÿüÿðèÿÿûýþÿþþÿÿþûÿÿüÿþñæèòýÿýýÿýúúýýûüÿüþÿÿþÿûíÖÙôÿÿáûüö÷þäÛûûúýÿþúùüÿþõöøúÿúßÓÞíúýüüöþùûÿÿýüÿüÿÿ€îüúþÿÿûùúþÿÿþêÉÊëþÿüóéäðÿèÜõæõùúöñìîñûîëîöÿôÎÛìûÿÿýùóïêîûüòïöøûýùòíïóöóðôýÿÿþÖææÖøÿëÙçß×õëÇÑÜÞæÿëËÎÓçéáÞÕÖøõ¿ÜéöûýÿðÕÛÖáôêØßãÒòÿÍÔÛ×ÒØàÚ×üÿýÿßòìÔõÿàÄóùóþçÑòøßÞþêÓéñÿøìêÝÑìøÖæóýÿÿòá×ôìðíÓÔðîÓêÿÕÞîêÑàïäÖøþúýÆâßÃäÿî×ÙãèÿëÚÿüåÙýéÔùÿÿáÙàÚÖõþÓòÿÿ€øí×ÛÿýÿöÓäÿÿÔâýÞçÿýÐèÿòÖöÿþþÎçêÌ×úÿùëÙÒùéØÿûæÖþèÑúûîÒãùëÙöÿÑñÿ÷ïýòÙÛÿýýìÌÝÿþÒßõÜçÿþËåÿõÓñÿÿþùþÿèÑãëã÷ßÓ÷êÖþüäØýêÔúüðÝãëÞÔðöÏëþêÙóúâØêèêìÞÛëìÕçòÛæüóÎáüóÓìýÿüÿúÿüâçâØÛáéÿôåýûðçþðâüÿþðØÍÔãùøßóÿïÞõÿòáÌÕÞòöâÙÙéúûéòýõäïþûåôýÿýúôúÿýÿø÷ëúÿÿþöýÿýùÿùõýýÿÿøôûÿÿëþÿúöþÿþ÷÷þûÿÿúõôûÿÿùÿÿøúÿþÿøÿþÿÿùþ÷üÿÿøÿÿÔýüÿÿúþþÿýþÿýøýÿÿþþÿþüÿüøýÿÿùüÿüÿþüýýÿüýýûýýÿÿøöþþÿúÿýþþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿüþýÿÿøüûúýÿþþÿÿåþÿÿýÿÿüüþþýþüþÿÿûûÿÿýýÿÿþþÿÿþþÿÿûþýýþÿÿøþÿÿýüýüÿÿûýûýüýýþÿþÿþþÿÿþþÿ ÿüüýýþþ ÿýþÿþÿþúÿþÿíþýÿþÿÿþûþýùúÿÿýüýþýýúüûÿÿþÿ ÿïþýÿÿýþÿÿþÿøúÿûüþÿÿêþÿþýüþûþÿüûýýþÿýúûþþüÿÿûþÿÿþÿÿüþýüýýþþÿÿùûÿÿüúþýýûùÿÿ÷ýýüðþûÿÿüûýúÿýýÿÿýüþþøýüüýýþþýýþýþþÿÿÍúìñþüûþþÿÿüÿðèÿÿûýþÿþþÿÿþûÿÿüÿþñæèòýÿýýÿýúúýýûüÿüþÿÿþÿûíÖÙôÿÿáûüö÷þäÛûûúýÿþúùüÿþõöøúÿúßÓÞíúýüüöþùûÿÿýüÿüÿÿ€îüúþÿÿûùúþÿÿþêÉÊëþÿüóéäðÿèÜõæõùúöñìîñûîëîöÿôÎÛìûÿÿýùóïêîûüòïöøûýùòíïóöóðôýÿÿþÖææÖøÿëÙçß×õëÇÑÜÞæÿëËÎÓçéáÞÕÖøõ¿ÜéöûýÿðÕÛÖáôêØßãÒòÿÍÔÛ×ÒØàÚ×üÿýÿßòìÔõÿàÄóùóþçÑòøßÞþêÓéñÿøìêÝÑìøÖæóýÿÿòá×ôìðíÓÔðîÓêÿÕÞîêÑàïäÖøþúýÆâßÃäÿî×ÙãèÿëÚÿüåÙýéÔùÿÿáÙàÚÖõþÓòÿÿ€øí×ÛÿýÿöÓäÿÿÔâýÞçÿýÐèÿòÖöÿþþÎçêÌ×úÿùëÙÒùéØÿûæÖþèÑúûîÒãùëÙöÿÑñÿ÷ïýòÙÛÿýýìÌÝÿþÒßõÜçÿþËåÿõÓñÿÿþùþÿèÑãëã÷ßÓ÷êÖþüäØýêÔúüðÝãëÞÔðöÏëþêÙóúâØêèêìÞÛëìÕçòÛæüóÎáüóÓìýÿüÿúÿüâçâØÛáéÿôåýûðçþðâüÿþðØÍÔãùøßóÿïÞõÿòáÌÕÞòöâÙÙéúûéòýõäïþûåôýÿýúôúÿýÿø÷ëúÿÿþöýÿýùÿùõýýÿÿøôûÿÿëþÿúöþÿþ÷÷þûÿÿúõôûÿÿùÿÿøúÿþÿøÿþÿÿùþ÷üÿÿøÿÿÔýüÿÿúþþÿýþÿýøýÿÿþþÿþüÿüøýÿÿùüÿüÿþüýýÿüýýûýýÿÿøöþþÿúÿýþþÿþýþÿþÿþýþÿþÿþ/ÿþ7ÿþ7ÿþÿÿ ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3þÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3 ÿ3އGC#![ gelber hintergrundÿ     Á%d [ d¸xd[ dÌs`Jÿ5ÿüãÿ€ÿÿ+ÿüöëÕÿÿþ€(ÿþüÿ ÿ'ÿ& ÿüúÿüÿÿ ÿÿþûÿÿûü÷ÿª ÿÿÿÿÿÿÿþÿÿþþÿÿÿþÿ ÿÿ ÿþÿ ÿÿÿþÿÿûüöÿÿÿÿýøúÿÿþÿ ÿ ÿ ÿþÿ ÿ ÿ ÿþÿ ÿ ÿ ÿþÿ ÿ ÿÿþÿÿþøÿÿ ÿ ÿþÿÿúüÿíÿÿ ÿþÿ ÿþûÿ ÿùþÿÿõÿÿ ÿÿúüÿî¿ÿ ÿÿûûôÿÿÿÿ ÿÿ ÿÿÿ ÿ)ÿ+ÿ/ÿ2 ÿ)Kþ€ÿÿþ€5òÿªÕÑÏ××ÌÆ¿€ÿ€ÿÿþ€+ê€ÌêÞãÜÜÛÝÛØÕÿÌÝä×Ýã¿€(ÿêäÝÛÚÛÚÚÛÜÛÝ×ÚÖØÜÞÛØ¿ÿ&ÿéÞßÝÛÜÛÛÚÚÛÛåÝÛÙÚÛÝÚÜÌÿ%ÿøéÝÜÚÛÚÜÛÛò×ÞÜÜÛÜÛÜÜØ×Ìÿöÿª¿ÿÌÌÿÿ€ÿýßÝÜÜÚîÜÚÚÝÞÜÚÛÛÜÛÜÙØØæªóªÛëãÛÜÜÙÏÌÌ€ëÿßÞÝÚÚÛÜÛÛÚÙÛÛÞÜÛÚÛÜÛÛùÜÝÛÛÕÿñªÌÜØÝÞÜÛÜÚ×ÒÛÿÿäÜþÛÜÜÚïÛÜàÙÛÛÝÜÛÛÜÛÚÙØÿåÿª×áÚÚÛÝÛÜÛÛÚ׿ªÿÑÜÝÛÛÜÛÚÚÕí×èßáÙÛÜÛÜÛÛÚÜÚÜÖÿÿ çÿ¿ÖÜÜÝÝÛÛÚÜÛÜÙÙÑÿÿ×ÚÝÜÛÜÜõÚÖÒß̪ÿÌÜÞÛÛöÜÛÙÚÚÛÙêÿ èÿÕÜÙÝÜÛÜÛÛÜÜÛÚרÿÛÛÝÛÝÛÛÚéáÌ€ÿÿØÜàÜÜÝÛÛÚÜÝÛäÿÿ áÿ¿ÛÛÜÝÚÛÚÛÚÚ×ÙÛÝÿÕßÚÛÜÛÜÜÞàã€ÌÕÝÜÜÛÜÛÜÛÚÜÛÿ ëÿÕßÞÚÜÜÝÚÙÛÙÚÜÜÿßÝÜÛÛúÞÚÙÕÿñ€ÿêÛÛÜÜÛÜÚÚÙèÿÿææßÙÜÞØÒÙÜÚÛÛ¿ÙÚÜÜÛÜÛÛÜßÌúÿÕØÙÜÛÛúÜÝàݪÿÌôÛÌÕÛÚÛÚÿÑÜÛÛûÝÛéÌýÌÕÛÛøÚÛÚÜÙßÿÿë¿èØÛÜÜÛ¿ÙÞÛÜÛÜÛÛØßÌòÿÕàÜÜÛÛÚÛÛÙÛªîÿª¿ÿÌÕÌæÜàÜÝÜÿßÜÛÛÚû×Ù¶ÿò€ÆßÝÚÚÛÛÜÜÛæÿëªÛëãÛÜéåæßÝÝÞÜÿÑ×ÛÛÜÜúÛÙ×Õÿñÿ¿ßÞÜÝÛÜÛÜßÞÕÿ áªÌÞÞÝÞÜàÞÝÛÞÝÝÛÿÕÖØÛÜÛÛÜÜÚÑÑÌÿÿüÌÄ×ÜÜøÚÛÛÙÛÛÿ úÿª×רÛÛþÝÛÛöÝÚÜØÿÛÛÚÚïÛÚÛÚÙÚÙÕß¶¿ÕÙÛßÜÛÛûÜØÛÿ êÿ¿ÖÙÚÛÚÜÛÜÛÙÛÖ×ÑÿÛàÜÜýÛÜÙÙìØÛ×ÛÏÕ×ÙÛÝÜÛÛÜÛÛÌ¿ÿ ÏÿÕÜÚÙÛÛÚÛÜÚØÞãÛªÿÿëÞÛÛÜÛÜÛÛÜÛÛÝÛÚØÛÜÛÛÜÝÜÛÝÕÛÿðÿ¿ÛÜÝÛÜÜÚÛÛÚ×ÛÿÿóäàÜÜÚÛÛÜÛÛÜÝÜÜÛûÝÚÕÿòÿÕßÞÚÜâÜÚßáÛÿòÿßÞÝÜÚÛÜÛÜÚÛÜÛÛôÚÛÜÛÚÛÛÚßÌÿÿöæßÙçÙßæÿÿÿüÞßÝÛÛÚÛøÜÛÝÝáÕÿÿ ÿøãÝâÞÜÛÜÛÛþÜÛÛùØÔÜÈÕÿ(ø€ÌêßàÛÜÝÝþÜÛÛøÚÙ×Îã¿ÿ*íÿªÛØÕÝàÞàÝÜÜÞßÛÕÕÿ.ðÿªÕÑÝäÜèçãÛÆÌÿÿ2ü€ÿÿÌÌü¿ªÿ(LûU@@U8ø+.0663ûU@@U-ô3+!)('(($'+336ý3+ú$(($(''ó&#$"(-)'('$')ù ,+(&(''û&'*#((ù)('),3'û ,'&''÷(&'&'('&''(ü'(3øU@@33@Uò ++(''&''&&%%''(ú'(''3õ$;+$#.3033ü ,+''÷('&'('+(''&û')$+ó.'+*'('+(-$í3(+(&&''('&%*,.)&(''ù&''(-'û$('&&'û(,( î.+((&''()(%"(. -&''&'ý)+ù #&&%&&'ã*-&.@(%&'&&'(() 33,%$&'&&û%&&+ü+#&%%þ&'')ø('$$%&&'ý%ø#$#%&'&&$ý(@$'è%&%&')(++(+&%''&'(''ò++(%'%&&%%#$õ+0)+''&%&'))ñ'0&('&&''%&+ó@+$$&'&''%&.3ç0&#!'&&))('@&%%&&'&%'+3ü+'&''&ü'*"ðU@33$"#''('@.'&&ü(,3ý3+((ù'&'(&0÷.'()'&@&&'ý+3ø+)&%&''&&þ$ïU@@3+33.,''%0(&&'(ý&$ü(%&&ý$î$'+$.,,2-+(%%.(''ü&"+ô '&&%&&'$!+ì,'+*''),**(%$+)'&&'ú(%$.3ó3' #%&&%'&$$û(''&&ø())(%#'ü$*%&&ê'*-&+ $ +&$$%''%&&''$ú &'%&&(û$"ø$)''&%%&&í)'$ $ +(&&''&&''+"ú+#%&&%%'ý$'&'ø()($%'(''û(&+$ó$+*''%''(%($ü3(*&&%&ó'('&'&'(''&%&&þ+ô+ )+')'+(-$ö ,'&%&%&&''þ&''ú&$$% 3ø0313033ó !%%$&%&&'&&''÷&'%$&"+þU@@þU ê$%&'&%%&&'&'&''&#$++ó %$&'&&'&&$""ý$.ð$' ")&'&'(! $++1ô+.3(##$+$35ýU@33þ@*J÷  4ì8RaaM.   *ú =v¾ÿÿòçB3MaaM. (û #aÃÿÿûMa®ÿÿúìB&û )vöÿÿüÝ•çÿÿü•3 %ü )vÿ ÿþìÿÿüaõ ü ){ÿ ÿþìÿÿü©3ò#B\kqqfR3 ü )vÿ ÿýì¹ÿÿükú3qÈÿÿúö¤W# ûaöÿÿü³q€ÿÿûÍB ûaÝÿÿöÒa) 8¹ÿÿøöša8)Wñÿÿü€ ü)€ÿÿøÍf8aÿÿ÷¾W)3•ÿÿüÍ= üqÿ ÿùç©#ÿÿôöW B•ûÿÿüa ûG³ÿ ÿû =Íÿÿü©. ú 3\šÿÿü•# ú RŸöÿÿüRÿÿüŠú =³ÿÿüÍ8 ö 3Rfqv…®ÿÿüfÿÿü{ü…ÿÿüûMö #M¹ÿÿüqÿÿývü{ÿÿýRü8©ÿÿüfÿÿü{ü€ÿÿüñGö3fâÿÿüRÿÿüŠ#ü .¤ÿÿü³3 õ#B\kqv•Òÿÿû 8ÃÿÿûÃ=ûRìÿÿüv ú3vÈÿ ÿû€ÿÿû8 û B¤ÿÿû×G ûaçÿÿøâ©GÝÿÿö®f=)#)=f³ÿÿü…# ü)€ÿÿ÷¾a8#€ÿÿúפ¤×ÿÿû×M üqÿÿõÈ\#BÈÿÿü{#ûG¹ÿÿûÒa# ûaûÿÿû®=ú RŸöÿÿúö¤W# ü )vÿÿûÒRô 3RfkfR3 û )vöÿÿû¾W ü ü û #\¾ÿ ÿû•G (ú ={Òÿ ÿúÃk.*ù#B{¾ÿÿùì¤k= .ð8Maqqk\G. 1û ü(tÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿýøêÿÿ ÿüøÕ¿ÿÿ ÿþóÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿÿÿytÿøÿªÿÛÿ¿ÿôÿª¿ÛØÜÙÕÝÛÿ ñÿ¿ßØÕÖØÛÚÙÚÎÿÿ ïÿÕëàÝÛÞÝÜÜÚØÝãÿÿ÷ªÛáàÞÝÝÛÜÜÛûÝßæÿ÷Ñ×ÛÜÚÙÙÚÜÜùÚÛÜÛëÿøßÛÞÜÛÛÚÜÜøÛÚÚÜÛëÿÝÜõÚÝÚÙÛÝÝßæÿÚðÛÚÛÛÞÜØÚÚÝÛÜãÿÿÛñÜÚÖÎ¿ÈØÖÛÙÝ×Ûÿ úÚÛÜÛÒ¿¿øãÒÜæÛÿÿ ÛòÜÛÒ¿¿ªÕæØÕÛÿÿ ðÜÛÜÚÜÛæãÛÞÛÖßÛÿ ÜÝóÛÕÓÛÞßÝÙÚÎÿÿ öÞÝÝÛÛßרÚÜÜúÚÝÕÌÿîØÜÛÝßÛÜÚÚÜÝÜÛàÞãÿîÑäÝÞÞÜÚÜÝÝÜÜÚÛÚØÿùªÛÕâàÞÛÛþÝÛÛûÙÞêÿ ÿñÝÛßÝÞÜÝÛÝÜÙÙãÿ ðÿÌãÛÙÝÚÚÜÝÚÞëÿÿ ÿõÌãÒØ×ÜæÑÌ€÷ÿ¿Ûƿ̪ÿüÿ€€yü3$+öU@$'#& "$ó@ '+)'$&&%$$ ñ+')($&(('('(+3 ð$-'&&%&''('()(3 ö.(,(%&&'&''ü(*' ï(*&&$$%%&'&&'(*' (û%''%''û()(3 '($õ!#'('&')+3 ð()'()$+$'))&)($ ñ&''(&+-.3$+ ù&''$&+û'+$ %õ)$$!$ $ %ò&($$#$'$&&%$$ ô$%%'$#$'(('((ý+3 ï')$%#$#%'('((*)9 ú()&$%%÷'('&'*,' ý$+$$&÷%&'&()'+ ñ+"$&'%%&%&(*/9 ò39$&"%%&&%)'@õU3' #&.3û$ 3”tø#ô#BqŠ{M# ø)B\€ÈÿÿûÒk# ù B€Ãûÿÿûç\û#W©ÿÿü¤3 ü8a³ÿ ÿüÝB ý¤Ýÿ ÿüÝB  ÿü¤3 ÿüן¹ÿÿûâ\ÿóâk=G…âÿÿ¾a# ÿô®=.WqfG ÿô®=3B=# ÿôâk3.Gv€R# ÿûוÈÿÿûÒk# ÿûç\ý©âÿ ÿüŸ. ü8a¾ÿ ÿüÒB û#\³ÿÿüÈ= ú MÍÿÿüŠ. ø .GfšöÿÿûŸB ò .W…¤•f8 ÷#.)û x-&  Hintergrundÿ     y & yDׯ×Ò×Þ×ê& ytCŠŠ”l¬ª¶›Á]ÎôY€ý™€9øª”™“ŸU7ý’”••ü–•™6õŽ””–••–‘ŽU4þŽ••ú–•“ŽU2ñŽ•–•–••––”•“ŽU0üŽ•–••ö”••–”•“ŽU.üŽ•–••ö”••–”•“ŽU,üŽ•–••ö”••–”•“ŽU*üŽ•–••÷”••–””•™)üŽ•–• •ý”•––ý—ª(üŽ•–• •ü–•”••þ™(üŽ•–• •–ý—ª(üŽ•–• •ø”••’‘•™)üŽ•–••–ú•“—™ª*üŽ•–• •”ý™ª,üŽ•–••û’••™.úŽ•–•–••ú’“—™ª/üŽ•”••ú’“—™ª1þŽ––•ú’“—™ª3ö’––””“—™ª5øªŒ’–“™ª8ûª’’ª"Y€ý™€9øª”™“ŸU7ý’”••ü–•™6õŽ””–••–‘ŽU4þŽ••ú–•“ŽU2ñŽ•–•–••––”•“ŽU0üŽ•–••ö”••–”•“ŽU.üŽ•–••ö”••–”•“ŽU,üŽ•–••ö”••–”•“ŽU*üŽ•–••÷”••–””•™)üŽ•–• •ý”•––ý—ª(üŽ•–• •ü–•”••þ™(üŽ•–• •–ý—ª(üŽ•–• •ø”••’‘•™)üŽ•–••–ú•“—™ª*üŽ•–• •”ý™ª,üŽ•–••û’••™.úŽ•–•–••ú’“—™ª/üŽ•”••ú’“—™ª1þŽ––•ú’“—™ª3ö’––””“—™ª5øªŒ’–“™ª8ûª’’ª"Y€ý™€9øª”™“ŸU7ý’”••ü–•™6õŽ””–••–‘ŽU4þŽ••ú–•“ŽU2ñŽ•–•–••––”•“ŽU0üŽ•–••ö”••–”•“ŽU.üŽ•–••ö”••–”•“ŽU,üŽ•–••ö”••–”•“ŽU*üŽ•–••÷”••–””•™)üŽ•–• •ý”•––ý—ª(üŽ•–• •ü–•”••þ™(üŽ•–• •–ý—ª(üŽ•–• •ø”••’‘•™)üŽ•–••–ú•“—™ª*üŽ•–• •”ý™ª,üŽ•–••û’••™.úŽ•–•–••ú’“—™ª/üŽ•”••ú’“—™ª1þŽ––•ú’“—™ª3ö’––””“—™ª5øªŒ’–“™ª8ûª’’ª"Yû9ø--7÷2{‡^86õ C¬ÕÁ˜U 4ó F·òõà©f: 2ñ F¸õþúçÅ›d: 0ï F¸õÿÿüöåÅ›d: .û F¸õÿÿõüöåÅ›d: ,û F¸õÿÿõüöåÅ›d: *û F¸õÿÿöüöåÅ›d9)û F¸õÿÿ÷üöåÄ–N(û F¸õÿ ÿøþúíÇt$(û F¸õÿÿ÷ýöåÅ–N(û F¸õÿÿ÷úèÆœe:)û F¸õÿÿöýöáªg; *û F¸õÿÿöýöåÆšV ,û F¸õÿÿöýöåÆœe:.ð F¸õþýöåÆœe; /ò F¸óöåÆœe; 1ô D¯ÜÅœe; 3ö3’d; 5ø13 8û" ù€ªŽŽ’Uú€ªŸªU.ó™›•––•›™™›••ý›™,òª••––•–••ªª••––ü“’™+ü’•–••ù–•’’•–••–ý•ªý€ªŽŽúŽ–••–••û–ªª–••’ûª”–”••üŽ•–••ú“™™•–••ý–ªþ’––üŽ•–••ú“™™•–••ý“™üŽ–”••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ––••üŽ•–••ú“™™•–••û”•”™ü’˜–••úŽ–••–••ø”ªª–••–••ý–€ýª—••ü’•–••’ý•–••ü”™€ù€–•”’“몕“••”•“•ªª•“••”–—¢ÿú€™Ÿ™™확’””’•™™•’”’“’ª-ùª’™™’ªùª’™™’ª$ ù€ªŽŽ’Uú€ªŸªU.ó™›•––•›™™›••ý›™,òª••––•–••ªª••––ü“’™+ü’•–••ù–•’’•–••–ý•ªý€ªŽŽúŽ–••–••û–ªª–••’ûª”–”••üŽ•–••ú“™™•–••ý–ªþ’––üŽ•–••ú“™™•–••ý“™üŽ–”••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ––••üŽ•–••ú“™™•–••û”•”™ü’˜–••úŽ–••–••ø”ªª–••–••ý–€ýª—••ü’•–••’ý•–••ü”™€ù€–•”’“몕“••”•“•ªª•“••”–—¢ÿú€™Ÿ™™확’””’•™™•’”’“’ª-ùª’™™’ªùª’™™’ª$ ù€ªŽŽ’Uú€ªŸªU.ó™›•––•›™™›••ý›™,òª••––•–••ªª••––ü“’™+ü’•–••ù–•’’•–••–ý•ªý€ªŽŽúŽ–••–••û–ªª–••’ûª”–”••üŽ•–••ú“™™•–••ý–ªþ’––üŽ•–••ú“™™•–••ý“™üŽ–”••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ•–••üŽ•–••ú“™™•–••ý“™üŽ––••üŽ•–••ú“™™•–••û”•”™ü’˜–••úŽ–••–••ø”ªª–••–••ý–€ýª—••ü’•–••’ý•–••ü”™€ù€–•”’“몕“••”•“•ªª•“••”–—¢ÿú€™Ÿ™™확’””’•™™•’”’“’ª-ùª’™™’ªùª’™™’ª$ ù ú.î5DD55A5,ìR–³´–RR–¯–U+ë5–ÝòóÝ–55–Ýðà§Uý  ë D´óþÿó´D D´óþúà—6û3CFFë F¸õÿÿö¹G F¸õÿÿó´D û3…±¸¸ë F¸õÿÿö¹G F¸õÿÿö¹G û D±ìõõë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G û F¸õÿÿë F¸õÿÿö¹G F¸õÿÿö¹G ø D³ñýÿÿë F¸õÿÿö¹G F¸õÿÿôµE ø4Ñìõöë D´óþÿóµE D´óþýç8øF¨·¹ë5–ÞóôÞ—65–ÞóðÇkù)>FGëS—´µ—SS—´³Š; ú í6EE66ED4-ù ù $¼€þŽŽý’Uú€ªŸªUú€ª’€ÿúª–“’™••û–•›™杖™—–™ª”—–‘™€’ü•–•––•þªî’––••“‘ŽU’–—–•–™™ûŽ•–”• •ü–•’üŽ–”••ë–•“Œ”•””•”‘ŽUŽ•–•–• •ý–ªôŽ•–•”••––—–••÷–•–•“ŽU™• •ý“™óŽ•–•–•”•––•–••–ù”•“™•–• •ý“™üŽ•–••þ”••ù”••––—––þ“• •ý“™üŽ•–• •û”•––••þ“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••þ”••þ“• •ý“™üŽ•–••û”•”–••–ù”•”––“• •ý“™üŽ•–••þ”••ø”••””—–• •ý“™üŽ•–••–ü”•”••–•™•ý–ªþŽ••”ûž”––••”û™ªŽ••þ–••ü–“’õŽ–”•”’••™’••þ”••þ™ûŽ“•–••ú“”’™ª“””—™ªª•’•”™™ª’ü•”•““ú”’—™ªù€’•’Žªþ™’’þ™ûª––’™™ý’ª€€ü€¿€€¼€þŽŽý’Uú€ªŸªUú€ª’€ÿúª–“’™••û–•›™杖™—–™ª”—–‘™€’ü•–•––•þªî’––••“‘ŽU’–—–•–™™ûŽ•–”• •ü–•’üŽ–”••ë–•“Œ”•””•”‘ŽUŽ•–•–• •ý–ªôŽ•–•”••––—–••÷–•–•“ŽU™• •ý“™óŽ•–•–•”•––•–••–ù”•“™•–• •ý“™üŽ•–••þ”••ù”••––—––þ“• •ý“™üŽ•–• •û”•––••þ“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••þ”••þ“• •ý“™üŽ•–••û”•”–••–ù”•”––“• •ý“™üŽ•–••þ”••ø”••””—–• •ý“™üŽ•–••–ü”•”••–•™•ý–ªþŽ••”ûž”––••”û™ªŽ••þ–••ü–“’õŽ–”•”’••™’••þ”••þ™ûŽ“•–••ú“”’™ª“””—™ªª•’•”™™ª’ü•”•““ú”’—™ªù€’•’Žªþ™’’þ™ûª––’™™ý’ª€€ü€¿€€¼€þŽŽý’Uú€ªŸªUú€ª’€ÿúª–“’™••û–•›™杖™—–™ª”—–‘™€’ü•–•––•þªî’––••“‘ŽU’–—–•–™™ûŽ•–”• •ü–•’üŽ–”••ë–•“Œ”•””•”‘ŽUŽ•–•–• •ý–ªôŽ•–•”••––—–••÷–•–•“ŽU™• •ý“™óŽ•–•–•”•––•–••–ù”•“™•–• •ý“™üŽ•–••þ”••ù”••––—––þ“• •ý“™üŽ•–• •û”•––••þ“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••ú”••–“• •ý“™üŽ•–••þ”••þ“• •ý“™üŽ•–••û”•”–••–ù”•”––“• •ý“™üŽ•–••þ”••ø”••””—–• •ý“™üŽ•–••–ü”•”••–•™•ý–ªþŽ••”ûž”––••”û™ªŽ••þ–••ü–“’õŽ–”•”’••™’••þ”••þ™ûŽ“•–••ú“”’™ª“””—™ªª•’•”™™ª’ü•”•““ú”’—™ªù€’•’Žªþ™’’þ™ûª––’™™ý’ª€€ü€¿€€¼û  ýúúú!FFûD5ï2@318%ú/cK¸¸ú´–Rî3…«“S 3‚œxDú A™5õõúóÝ–5å D±èÞ©f:J²áПV  F¬ªDÿÿûó´D å F¸õùçÅ›fQyËö÷áªf:  F¯¯Fÿÿûö¹G å F¸õþüöåɽÌëüÿúçÅ›d:M±¯Fÿÿûö¹G û F¸õÿÿúüøöøüÿÿôüöåÅ›fQy±Gÿÿûö¹G û F¸õÿ ÿöüöåɽÌâ¶Gÿÿûö¹G û F¸õÿ ÿøüøöøó¸Gÿÿûö¹G û F¸õÿ ÿøüøöøó¸Gÿÿûö¹G û F¸õÿ ÿ÷úèʾÌâ¶Gÿÿûö¹G û F¸õÿÿúýù÷ùüÿÿõýöáªiRz±Gÿÿûö¹G å F¸õÿÿúèʾÌìüÿÿúèÆšVN²¯Fÿÿûö¹G å F¸õüöáªiRzÌøüöáªg: F¯¯Fÿÿúýï²D å FµìåÆšVL¶îçÆšV  F­«DööùôåÈ4í ?›¹›e:5“ǧg:ú Bš5¹¹ùµšd8î)\X9 MqO ú/cLGGúE6 ù ú#ú"  ýüüü€™€€&ú™’“–ª€ú™’“–ª þªùª•–•’’“”•”ª€Ž‘–•’’ þ’ù’•”–•Žî™›”••––’™›”•–•“Ž þªꎖ•–•™€Ž‘“•–•–”Ž•‘–••ü–•™ þ™þŽ••ú™€’•”••û–•––••ü–“™ þ™õŽ••”•”Ž••–••ú–•–•–••ý“™ þ™öŽ•–•–””––••ý“™ þ™þŽ••ü–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™þŽ••þ”••ý“™ þ™÷Ž•–•”•–”••û”•”–••ý“™ þ™þŽ••ú“—™—–••þ–••þ–••ý“™ þ™þŽ••™û”’””••þ”••ý“™ þªýŽ–••陀Ÿ“•”•––•–——•”•–”•“™ þ’ù’•–•“Žª”•û—™ªª””•ý—Ž þªùª•”•’’•””’’™••””’’$ú™’––ªªû•––ªªû•––ª%ü€¿€ü€¿€ü€¿€Ž™€€&ú™’“–ª€ú™’“–ª þªùª•–•’’“”•”ª€Ž‘–•’’ þ’ù’•”–•Žî™›”••––’™›”•–•“Ž þªꎖ•–•™€Ž‘“•–•–”Ž•‘–••ü–•™ þ™þŽ••ú™€’•”••û–•––••ü–“™ þ™õŽ••”•”Ž••–••ú–•–•–••ý“™ þ™öŽ•–•–””––••ý“™ þ™þŽ••ü–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™þŽ••þ”••ý“™ þ™÷Ž•–•”•–”••û”•”–••ý“™ þ™þŽ••ú“—™—–••þ–••þ–••ý“™ þ™þŽ••™û”’””••þ”••ý“™ þªýŽ–••陀Ÿ“•”•––•–——•”•–”•“™ þ’ù’•–•“Žª”•û—™ªª””•ý—Ž þªùª•”•’’•””’’™••””’’$ú™’––ªªû•––ªªû•––ª%ü€¿€ü€¿€ü€¿€Ž™€€&ú™’“–ª€ú™’“–ª þªùª•–•’’“”•”ª€Ž‘–•’’ þ’ù’•”–•Žî™›”••––’™›”•–•“Ž þªꎖ•–•™€Ž‘“•–•–”Ž•‘–••ü–•™ þ™þŽ••ú™€’•”••û–•––••ü–“™ þ™õŽ••”•”Ž••–••ú–•–•–••ý“™ þ™öŽ•–•–””––••ý“™ þ™þŽ••ü–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™ùŽ•”–•”••ý“™ þ™þŽ••þ”••ý“™ þ™÷Ž•–•”•–”••û”•”–••ý“™ þ™þŽ••ú“—™—–••þ–••þ–••ý“™ þ™þŽ••™û”’””••þ”••ý“™ þªýŽ–••陀Ÿ“•”•––•–——•”•–”•“™ þ’ù’•–•“Žª”•û—™ªª””•ý—Ž þªùª•”•’’•””’’™••””’’$ú™’––ªªû•––ªªû•––ª%ü€¿€ü€¿€ü€¿€Ž™üü%ú!ûú! þùKc/ï 20 Nc/ þù5™A î9c‘39e œB þ ä Dª¬F  U˜ÄÛ±J U˜ÅݳF þ ä F¯¯F 9e©àõõÌyMKh©àõó¸G þ ä F¯±M)[™ÅçúÿüëÌ»ºÉçúÿö¹G þ ó F±ÂyOV|´âõüÿÿóüøõõøüÿÿö¹G þ õ F¶â˼ÀÔíûÿ ÿûö¹G þ ö F¸ò÷ööúýÿ ÿûö¹G þ ÷ F¸ò÷öøüÿ ÿûö¹G þ õ F¶â̾Êçùþÿ ÿûö¹G þ ô F±ÂzRh¥Øñüÿÿúýù÷ùüÿÿûö¹G þ ä F¯²NLˆ¼äöüÿüì̾Êåöüÿö¹G þ ä F¯¯F 1_›ÆçúøÌzRgœÆçúõ¹G þ ä D«­F :fªáí¹N:fªáí¶G þù5šB í V™¼¡B  V™¼¡B þùLc/ï:]f/:]f/$ú"ù "ù "%üüüŽÐù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªõ€“—˜••–•›þª••û–“™ªü’–”••ü”•Žú€—•””••þ–÷’•–••–“™󪌖’••–”–”“ªü€™”••ý”•þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ý–—÷ª“””••–• ÷ª“””••“•ýª’™™ý’‘þ’••ü–“™ ÷•–••”–—ªþ™ýŽ–••ý“™ ûŽ•––••þ’!üŽ•”••ý“™ ÷Ž•–”•––Ÿ!ýŽ”••ý“™ ÷Ž•–••”“€þ¿÷ª“•”––“™ ý•”••ý‹€ý¿÷€™”–••–• ÷ª“”••””Žý€ªŽŽü‹™—÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ü˜—“üª“”••ý’™ý™‘••þ™ú€–•“–••–ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ý–™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¥Ðù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªõ€“—˜••–•›þª••û–“™ªü’–”••ü”•Žú€—•””••þ–÷’•–••–“™󪌖’••–”–”“ªü€™”••ý”•þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ý–—÷ª“””••–• ÷ª“””••“•ýª’™™ý’‘þ’••ü–“™ ÷•–••”–—ªþ™ýŽ–••ý“™ ûŽ•––••þ’!üŽ•”••ý“™ ÷Ž•–”•––Ÿ!ýŽ”••ý“™ ÷Ž•–••”“€þ¿÷ª“•”––“™ ý•”••ý‹€ý¿÷€™”–••–• ÷ª“”••””Žý€ªŽŽü‹™—÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ü˜—“üª“”••ý’™ý™‘••þ™ú€–•“–••–ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ý–™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¥Ðù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªõ€“—˜••–•›þª••û–“™ªü’–”••ü”•Žú€—•””••þ–÷’•–••–“™󪌖’••–”–”“ªü€™”••ý”•þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ý–—÷ª“””••–• ÷ª“””••“•ýª’™™ý’‘þ’••ü–“™ ÷•–••”–—ªþ™ýŽ–••ý“™ ûŽ•––••þ’!üŽ•”••ý“™ ÷Ž•–”•––Ÿ!ýŽ”••ý“™ ÷Ž•–••”“€þ¿÷ª“•”––“™ ý•”••ý‹€ý¿÷€™”–••–• ÷ª“”••””Žý€ªŽŽü‹™—÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ü˜—“üª“”••ý’™ý™‘••þ™ú€–•“–••–ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ý–™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¥Ðù 6î 5DC3 ,ì9c˜³¯15DC3*ëT˜ÂÝèÕ3R–³±…3)éV¤×ÛÆ¶–R5–Ýòì³H 'èV¢ËÀ›gI6 D´óþøÊhý  ýæV¥Ë§f;  D±ìööå©Uõ-@EFFD5õT¦ÙÀf! ó3†²»ÌçÞ™: õ `˜¬¯¯«ŽNö5–Ýà›; ó3DMxÇíÄdõJŒª¯¯­žv÷ H¶ìÉgô =œââ™6û5DFFýISöfÉï»K  öfÉì¶I ý  ý÷5˜äó¸G ÷ K»ïÉfý÷ D´óõ¹G ÷ F¸òã˜5!÷ F¸õõ¹G ÷ F¸ôì§=!÷ C²òõ¹G ÷ F¸ñÛˆ-þ÷4•ãò¸G ÷ JºìÀ[ýöbÄìºK  öfÆÞ›9 ý  ü ;÷ :›ÞÇh ÷ 9šÜÃdû/AFFüELSödÃÞ©WöeÁÚš: õ"c𬝭œr?ô :™ÜÞ§W ô W¨×¶]õL«¯«ŽNæU§ÝÝ©hH5 5Hg§ØÍ.ö5DFD5èW¤ÖÛÆ¶™fJFJe˜¶ÄÏ¿’Fý  ý êP޽ÝêáȺ¸ºÇßéÚ§f9*ì4ašÁÜéììëäÒ¼˜V ,ï 9_®·¸¶¤zT80ò 1BFGF<&3ü  ü¥4€;ú™’•’™€ €!ñ™’–•–•ªª”•”› úª–“’™ô™’—”•”•’’––þ•õ€ªŽŽ™•––’™û™’—–••õ–ª€ˆ—•–•™ó¿’–—–•–•–••ªûª••–••ü“™ª––•ý“™ò¿’“”“”•”•”–’ý€ªŽŽü™•”••û“™™–••ñ–•›™¿““”–•–••ü”–’ôª”–”••—”••–••ú“™ª’•––•ó™‹‹™—”—™‹‹”–••þªþ’––ý•–••ä“™™’“”“–”––••––—™’–”““™üŽ–”• •õ“™¢–”–•“––ý“™ú€™ž™€üŽ•–• •î“™Ž–”•”‹•”••–••üÿ€ÿüŽ•–• •󓙎–”•–¢•–••ý“•üŽ•–• •ô“™Ž–”•”™–••ü”“™€ûŽ–•”••þ–••å“™™’•–•—–”““”–—™ª–“’™ü’–”• •ä“™ª””•”’”•“••“•”•“‹Ž™•––’™õªŒ–’“”“””–••ã“™ª”–”““•“™¿–””––•–•–••ª÷ª’™™•’“–••ô“™™—”–•”•™ò™“’•”“”–•”•–’홑”••–•–˜™ª–••––•™ø’•—•–•––ý—’ûŽ•–”••÷ŸU’•–••úª’Ž‹‘””ý™ªüª•“••ù˜™’”•• ù™—‘•ªªð™’“•”—™€ªŒ’–• ü€¿€ ù™›—’’€ûª’’ª1ûUª’ªH4€;ú™’•’™€ €!ñ™’–•–•ªª”•”› úª–“’™ô™’—”•”•’’––þ•õ€ªŽŽ™•––’™û™’—–••õ–ª€ˆ—•–•™ó¿’–—–•–•–••ªûª••–••ü“™ª––•ý“™ò¿’“”“”•”•”–’ý€ªŽŽü™•”••û“™™–••ñ–•›™¿““”–•–••ü”–’ôª”–”••—”••–••ú“™ª’•––•ó™‹‹™—”—™‹‹”–••þªþ’––ý•–••ä“™™’“”“–”––••––—™’–”““™üŽ–”• •õ“™¢–”–•“––ý“™ú€™ž™€üŽ•–• •î“™Ž–”•”‹•”••–••üÿ€ÿüŽ•–• •󓙎–”•–¢•–••ý“•üŽ•–• •ô“™Ž–”•”™–••ü”“™€ûŽ–•”••þ–••å“™™’•–•—–”““”–—™ª–“’™ü’–”• •ä“™ª””•”’”•“••“•”•“‹Ž™•––’™õªŒ–’“”“””–••ã“™ª”–”““•“™¿–””––•–•–••ª÷ª’™™•’“–••ô“™™—”–•”•™ò™“’•”“”–•”•–’홑”••–•–˜™ª–••––•™ø’•—•–•––ý—’ûŽ•–”••÷ŸU’•–••úª’Ž‹‘””ý™ªüª•“••ù˜™’”•• ù™—‘•ªªð™’“•”—™€ªŒ’–• ü€¿€ ù™›—’’€ûª’’ª1ûUª’ªH4€;ú™’•’™€ €!ñ™’–•–•ªª”•”› úª–“’™ô™’—”•”•’’––þ•õ€ªŽŽ™•––’™û™’—–••õ–ª€ˆ—•–•™ó¿’–—–•–•–••ªûª••–••ü“™ª––•ý“™ò¿’“”“”•”•”–’ý€ªŽŽü™•”••û“™™–••ñ–•›™¿““”–•–••ü”–’ôª”–”••—”••–••ú“™ª’•––•ó™‹‹™—”—™‹‹”–••þªþ’––ý•–••ä“™™’“”“–”––••––—™’–”““™üŽ–”• •õ“™¢–”–•“––ý“™ú€™ž™€üŽ•–• •î“™Ž–”•”‹•”••–••üÿ€ÿüŽ•–• •󓙎–”•–¢•–••ý“•üŽ•–• •ô“™Ž–”•”™–••ü”“™€ûŽ–•”••þ–••å“™™’•–•—–”““”–—™ª–“’™ü’–”• •ä“™ª””•”’”•“••“•”•“‹Ž™•––’™õªŒ–’“”“””–••ã“™ª”–”““•“™¿–””––•–•–••ª÷ª’™™•’“–••ô“™™—”–•”•™ò™“’•”“”–•”•–’홑”••–•–˜™ª–••––•™ø’•—•–•––ý—’ûŽ•–”••÷ŸU’•–••úª’Ž‹‘””ý™ªüª•“••ù˜™’”•• ù™—‘•ªªð™’“•”—™€ªŒ’–• ü€¿€ ù™›—’’€ûª’’ª1ûUª’ªH4ü:ú$û ü ñPtN02 ú!ðV¥È”53Rõ 5fNîV§âî´D G«Î•ó.;=Fr¯ TìT§âúõ¹G 3aš¼­ò=apt†´áÛ’3ý  Û<™àúÿö¹G "`jl’A;SJ?A_¤ÝÚ’3Õ3CFFLwÇõþÿö¹G HpU8`W< ;Q; \¡šTÖ3…±¸¸»Ìëüÿÿö¹G Nd;K>UPHHPU;'OBû D±ìõõýøüÿÿëö¹G ?pDMP”³³”Pú û F¸õÿÿëö¹G =rFO H³ìì³H üû F¸õÿÿëö¹G =rFP H³ìì´I û F¸õÿÿëö¹G =rFOP•´´•Qüö D²íööøüþÿÿãö¹G =oDM;UQIIQU;!Ö3†²¹»Çâ÷þÿÿö¹G >[9KQ< wÊñâ¨W$D§Ó—6ûž6÷ D²íööøüÿÿîö¹I?›áõâ¨`a´¿fû…]ö3†²¹»Êèúÿÿîö¹G U¨ãõⱛŰI ûB õ3DGKi­çüÿÿïö»MXªç÷éØÏ•6ü3ã !gÅöþÿÿøÌw<(oÌ÷øß¦Uü_é :™áúÿÿüëÈ›fKP}Ìïá¨Xü: êU¨ãúüøôíÜÀ±²ÀÑÙV ýìW¨ÞãÊ»¸¶²¯¯®—d: þöU“•fKGGFFúD6 .ù34  ý1ûWÍù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªô€“—˜••–•›™þª••û–“™ªü’–”••ü”•Žú€—•””••ü–“™÷’•–••–“™󪌖’••–”–”“ªü€™”••ú”••›™þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ú–—••™÷ª“””••–• ÷ª“””••“•ýª’™™ú’‘”––þ’••ü–“™ ÷•–••”–—ªû™“––ýŽ–••ý“™ ûŽ•––••þ’ü‹•”üŽ•”••ý“™ ÷Ž•–”•––Ÿü¢•–ýŽ”••ý“™ ÷Ž•–••”“€û¿™–•÷ª“•”––“™ ý•”••ý‹€ú¿—–”÷€™”–••–• ÷ª“”••””Žý€ªŽŽù‹™—”•“÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ù˜—““™üª“”••ý’™ý™‘••þ™ú€–•“–••–ý™ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ü–™™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¨Íù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªô€“—˜••–•›™þª••û–“™ªü’–”••ü”•Žú€—•””••ü–“™÷’•–••–“™󪌖’••–”–”“ªü€™”••ú”••›™þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ú–—••™÷ª“””••–• ÷ª“””••“•ýª’™™ú’‘”––þ’••ü–“™ ÷•–••”–—ªû™“––ýŽ–••ý“™ ûŽ•––••þ’ü‹•”üŽ•”••ý“™ ÷Ž•–”•––Ÿü¢•–ýŽ”••ý“™ ÷Ž•–••”“€û¿™–•÷ª“•”––“™ ý•”••ý‹€ú¿—–”÷€™”–••–• ÷ª“”••””Žý€ªŽŽù‹™—”•“÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ù˜—““™üª“”••ý’™ý™‘••þ™ú€–•“–••–ý™ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ü–™™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¨Íù€ªŽŽ’U6“•–”–”ª€ªŽŽ’U,ì™›”••–•”—’™›•–”–”ª*ñ™’••––•”•–’ª••––þ’)ü™’”••–•ûª’•–••ü–••(è™’”–•––•“’•™Ž–••–••–”™ý€ªŽŽý’Uî™’—”•––“—•’ªŽ––••ü–•ªô€“—˜••–•›™þª••û–“™ªü’–”••ü”•Žú€—•””••ü–“™÷’•–••–“™󪌖’••–”–”“ªü€™”••ú”••›™þ‹••û”•—ªúª’™Ÿ–••ü”—’û™›•–••ú–—••™÷ª“””••–• ÷ª“””••“•ýª’™™ú’‘”––þ’••ü–“™ ÷•–••”–—ªû™“––ýŽ–••ý“™ ûŽ•––••þ’ü‹•”üŽ•”••ý“™ ÷Ž•–”•––Ÿü¢•–ýŽ”••ý“™ ÷Ž•–••”“€û¿™–•÷ª“•”––“™ ý•”••ý‹€ú¿—–”÷€™”–••–• ÷ª“”••””Žý€ªŽŽù‹™—”•“÷Ž•–••–”™ ÷Ž˜•”•”“ªü€–’••ù˜—““™üª“”••ý’™ý™‘••þ™ú€–•“–••–ý™ôŽ•””•–•™‹’Uô€ª‹‘•–••”™ªý€’””•ü–™™ûª•“”••î–••“‹Ž‹“••—–••––Ÿö™›•–•–•›™ý™’••–ò˜•”—•––•–”•–€ýª’™™ý’ª ê™—“•”••”••–•––••–””—€*ø™’““••–••”ý™ª,ü€Ž“””•–ù•–•’•™0òªŽ•’“•“’•”ŽŸª3ü€ªª™™üŸ™ÿ¨Íù 6î 5DC3 ,ì9c˜³¯15DC3*ëT˜ÂÝèÕ3R–³±…3)éV¤×ÛÆ¶–R5–Ýòì³H 'èV¢ËÀ›gI6 D´óþøÊhý  ýæV¥Ë§f;  D±ìööå©Uô-@EFFD5õT¦ÙÀf! ó3†²»ÌçÞ™: ó `˜¬¯¯«ŽNö5–Ýà›; ó3DMxÇíÄdòJŒª¯¯­žvA÷ H¶ìÉgô =œââ™6û5DFFúISW<öfÉï»K  öfÉì¶I ý  ú>UP÷5˜äó¸G ÷ K»ïÉfúP”÷ D´óõ¹G ÷ F¸òã˜5ü H³÷ F¸õõ¹G ÷ F¸ôì§=ü H³÷ C²òõ¹G ÷ F¸ñÛˆ-ûP•÷4•ãò¸G ÷ JºìÀ[ú;UQöbÄìºK  öfÆÞ›9 ý  ù ;Q<÷ :›ÞÇh ÷ 9šÜÃdû/AFFùELS;ödÃÞ©WöeÁÚš: ó"c𬝭œr?ô :™ÜÞ§W ô W¨×¶]ôL«¯«ŽNæU§ÝÝ©hH5 5Hg§ØÍ.ö5DFD5èW¤ÖÛÆ¶™fJFJe˜¶ÄÏ¿’Fý  ý êP޽ÝêáȺ¸ºÇßéÚ§f9*ì4ašÁÜéììëäÒ¼˜V ,ï 9_®·¸¶¤zT80ò 1BFGF<&3ü  ü¨ûª”–”••ü”–”þ’––üŽ–”••–üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“€ üŽ•–••þ“úª–“’™ üŽ•–••þ“õ€ªŽŽ™•––’™ üŽ•–••þ“ó¿’–—–•–•–••ª üŽ•–••þ“ò¿’“”“”•”•”–’ üŽ•–••ô“¿““”–•–••ü”–’ üŽ•–••ó“‹‹™—”—™‹‹”–••þª üŽ•–••ï“••––—™’–”““™ üŽ•–••þ“––ý“™ú€™ž™€ üŽ•–••ù“••–••üÿ€ÿ üŽ•–••þ“••ý“•üŽ•–••þ“••ü”“™€ üŽ•–••“ó”–—™ª–“’™ üŽ•–••ï“••“•”•“‹Ž™•––’™ üŽ•–••î“¿–””––•–•–••ª üŽ•–••þ“ò™“’•”“”–•”•–’ üŽ•–••þ“ø’•—•–•––ý—’ üŽ•–••þ“úª’Ž‹‘””ý™ª üŽ•–••þ“ù™—‘•ªª üŽ•–••þ“ü€¿€ üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“ûŽ–•”••ü–•–ü’–”••ý”–ûªŒ–’““ý’–Œûª”–”••ü”–”þ’––üŽ–”••–üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“€ üŽ•–••þ“úª–“’™ üŽ•–••þ“õ€ªŽŽ™•––’™ üŽ•–••þ“ó¿’–—–•–•–••ª üŽ•–••þ“ò¿’“”“”•”•”–’ üŽ•–••ô“¿““”–•–••ü”–’ üŽ•–••ó“‹‹™—”—™‹‹”–••þª üŽ•–••ï“••––—™’–”““™ üŽ•–••þ“––ý“™ú€™ž™€ üŽ•–••ù“••–••üÿ€ÿ üŽ•–••þ“••ý“•üŽ•–••þ“••ü”“™€ üŽ•–••“ó”–—™ª–“’™ üŽ•–••ï“••“•”•“‹Ž™•––’™ üŽ•–••î“¿–””––•–•–••ª üŽ•–••þ“ò™“’•”“”–•”•–’ üŽ•–••þ“ø’•—•–•––ý—’ üŽ•–••þ“úª’Ž‹‘””ý™ª üŽ•–••þ“ù™—‘•ªª üŽ•–••þ“ü€¿€ üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“ûŽ–•”••ü–•–ü’–”••ý”–ûªŒ–’““ý’–Œûª”–”••ü”–”þ’––üŽ–”••–üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“€ üŽ•–••þ“úª–“’™ üŽ•–••þ“õ€ªŽŽ™•––’™ üŽ•–••þ“ó¿’–—–•–•–••ª üŽ•–••þ“ò¿’“”“”•”•”–’ üŽ•–••ô“¿““”–•–••ü”–’ üŽ•–••ó“‹‹™—”—™‹‹”–••þª üŽ•–••ï“••––—™’–”““™ üŽ•–••þ“––ý“™ú€™ž™€ üŽ•–••ù“••–••üÿ€ÿ üŽ•–••þ“••ý“•üŽ•–••þ“••ü”“™€ üŽ•–••“ó”–—™ª–“’™ üŽ•–••ï“••“•”•“‹Ž™•––’™ üŽ•–••î“¿–””––•–•–••ª üŽ•–••þ“ò™“’•”“”–•”•–’ üŽ•–••þ“ø’•—•–•––ý—’ üŽ•–••þ“úª’Ž‹‘””ý™ª üŽ•–••þ“ù™—‘•ªª üŽ•–••þ“ü€¿€ üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“üŽ•–••þ“ûŽ–•”••ü–•–ü’–”••ý”–ûªŒ–’““ý’–Œîü ú!õ 5fNó.;=Fr¯ Tò=apt†´áÛ’3ñ;SJ?A_¤ÝÚ’3 ñ;Q; \¡šTHòPU;'OB³û”Pú ìû³H üìû´I ´û•QüIóQU;! òHÖ/ƒŒ³¼Eâ®¶éÞ˜Ÿ¬râ£óz0”ÅÆdË|+@ù–Ý!Àï‡S`Ê¥äóh Ì7F có¾pêäxù¹¥6zaý÷–"l£î$pÞäGS,fH§)0µ¤g£ü’~÷Œ\Ü,SžAÈ=kóB¢¡‡)O÷%„ ÖÑš‡}eؼŒ³a—@ÆÑX˜«ne‚_id rµŠk «ÄJ&zj§º/h”W¬‘ç˜÷¯À ±/xúcf ?Æó¡Ÿiçä +º¸åÕ…)üj˜CåÜLxEÿÀn\/Q^ÄŶÛÙé)޽øÿñWSZ;á8Ïñ $íhÀøòâ±Y£Ä"ñBíyìOëe2à ŠÇ#7ìLé*¯ôxp>Qóí]N°›üâ§XÑf’¿“+z¹’±CR £ÄËñ‰s̺E\ê¶b`Š?P%~a9£«<›÷-ƒTäFÏ>ùwæËÑNv? j\ÈÈ…cyœqtaô²A @D r ¿üë&pÜ®ò$Ó®$ü×±/¿ûæìG¨E;Í0t¯ ìVƒ§o` 5d™€†jË_~¬v­íñŠ@† ›Õ?õXt• Ò‹.¶ôžÒ³Oþ­ps»ÍÑ3ܳъÁm2°@9ëääßàñA5AÒÛÎ@ÔñRíø€Èßo€Áï?}Ð'|aH;}¿¥”Zì³-Aún™e` , c ÉÚK1}ßÈî7üèJ¶¢zq›ÀŠý´ÎÙn3b $oâ`.ÔÉž”Úg)-ê-#&ÚiaÖi r†ñPlœ Â\ËZv±O*ñ ‰5@? ²¼úÛ€OÆ Y‚ÈZD˜÷6£,-XJZ$«çxÉÍ,бL`@vö¬ô-@ãÙ¶¾’x{íØ¿6 øí?« Ý󃽻ۡ;˜5 duO;<¶¹ cwƒ^£ ¤Ôxê³ %nF0OüÄ)ظŽÌ¶®asɺ¯RîF‘Æ~L³'V–Ö›6…àG}¶E•_8‡Ÿœ «¯2V;.#¬(º@zEkhÐ }Q«n<Ä—ã½\ žª¿ €Ú¿‹XA£­äè®ಙ ”7ö¬hg@Y*²Å - •5Ñè.?ƇPìñ†v¼‡ÓŠØÊ”Æ/ˆ@)]…ò:_t.ƒ®–rãbO”¬CŒr5.žA€É«@Cÿ0’u¼²Ôkô'Æqˆ_…%@âSø/*>­\åÛ5ð?Æš¦Q¡IEND®B`‚remuco-source-0.9.6/client/android/res/drawable/rate_star_half.png0000644000000000000000000000146211700415064025211 0ustar rootroot00000000000000‰PNG  IHDR&&¨=é®tEXtSoftwareAdobe ImageReadyqÉe<ÔIDATxÚì˜ËkQÆÏ¤I b4P°"HvBhV®LÿÆEp)Ýù¬-¢hDTÜ™…ÝY¡ºàNÚ\ˆAhJ¡muLJ•43×ïÎܘGÇÎMçÚÌÂ_ngÉ/ß=çÜ3ÕcäÇOCXþ£6Y(â¾¢óXF}v³¬e‘ª1ü‡kQ߀…"t­£†Ò¾»1¯e‰Q‚Ú`I®T¹ÕÓuÒ›x§e”pã®…¶?ÖvË¡OŸØÕ·Z†Lâ¢?êóâZ@•[Ž…½¸¶+°ë﵃[uÊ!víšævˆ£¤°ðæ™A)¡Xï{Ï=:çðu¡uhC¬õ\.Ww;}W‹¥T$Š~D–N‰/Nõó+GÁvŠ¨Ñ‚åàæ÷(È_Œ-¢Å9º—°áö2Z‡~B¬kçØÌ¦n påŸ?ºó¦yŒ Ü*mKþ™‹npµ=ë‚ÚV•O/ÙpUWïn2RåØ.ž]fz³WûçŽ9Býµ=¿¸† · 8Ó”“*¨ì‹ À5il©,¿­ª \;pœ[Z rcSÙVºBIIÅI» ðÅU`U(é³òåÓƒû”leCÖÖ ìáHBA§? tº8óКTU8W  c|VÔÇdT¤¶2rОëETLÞ …0uŽÐ=2‘Ò«Ÿ¤ÁŽ(s éè˜i}_±¤›MGjãtØÅ15`ü­÷^í Ñ×EÒ ƒàòþì-¦‹ªˆçʤ—ÊtÃt›9Þ¾ÞøF´V%ÚúEÓ¸Ÿ½mµBŒÌ%r÷N:T¢TeºÎühÙá£ô˜OëËD$_Y@yV•¬Â¸î¸ýÄmæwßJlãêgkëøQ2õ:ÏJý” ˜á‹LŠ-ŽÊT¦+ØÚ²µœ}s‡M{éä¹W`Z&Ï´ÿÿƒí3~ 0RÕ!Ø× FIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/rate_star_off.png0000644000000000000000000000101711700415064025045 0ustar rootroot00000000000000‰PNG  IHDR&&¨=é®tEXtSoftwareAdobe ImageReadyqÉe<±IDATxÚì˜;n„0†d‘ªMU*º4K•sä œŠ3¤J@•TI³UªM•Š­hÈŒ4–ØÆv‘‘F°Òbú=/ú¾?øháÁS¶ TU%o ð/ð‹ÉóeYn®Ø=øÉ·£ÌÁ#ð <ñ ¬X¸w –TÊ9T ™ÕbS-´ÌÈ¥˜’1çL±“"K÷#µ2XäB1UÍŠlT WªuT¨e­šÐ„¸Oiü}«¹>þÿ¼ÿ¿Òµ%_´§ Ø<¢Íbʲ”`Ž÷jì«Ýö ½ó2Vìa±Ép¸£k#‡€: remuco-source-0.9.6/client/android/res/drawable/remuco_100.png0000644000000000000000000003533611700415064024114 0ustar rootroot00000000000000‰PNG  IHDRddpâ•TsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÛ'1ð]æ IDATxÚì½w˜%WyçÿyO…;LwOÎ9(ç0ŠEÀ¡E0–E„µA€N ¶1˜Å`Â"ŒmXÉ+‘L’IÈBq$ÍŒ¤ÑH3š¨™žî™Ž7UÕ9çýýQÕ=#ÃzÃOØò>ªyîs»ï­êº÷|Ï›¿ï;(//˜Ã¼¸/òâñ" /òâñ" /òâñ" /òâñ¯|„/´¤ªs€Å£¯Õjô4ÍJ£ÙŒÛíNÔi·âv§eYfYxçŒâPƒ`‚@ƒ taÛR©l+•rZ.—ÓZ¥jkõZ»§»{Æ€QÙûBúþòo©«ê<`10غå±Å÷þòÞe=ñÄÀ3;vö ê¯LL6ÊÍV«ä²,Æe‘ñ6Â{A½êëDQÄ€` *¢&ˆ25¡ â(©Vªi½^ítw÷´gõ÷5-Z4¶fͪѓO:q×™g³d8ì‘íÿÏâl¶xpðÀ™ûOݽ{W÷Ýwý|á?ý⮕۟Ù>¿9ÙŒrd¨Åô” õ]‘ÐSŽ(‡ºêU¬µ¤I (‚bUëŒ4:ŠÇAD´“ZIbë2Þ¶´¬£‘9&SGÓzZY¾¥Rè-^|àÔSOÛvîyçï^¶bÅøœÙ³7÷õõýbÖ¬Ùÿ?ˆª®ÿÞ?~ûÂoïöó6oÞ8·9´w ›í¯…†™Ýeê%º*Z‹Dú»ë˜Àf™z祓fˆ"`‚ïÞ{Œ‚ÀÐj55MS‰£P“$G@³í‘0ƈ ¢t’ŒÌzD Þ{ÂÀ¨óNÔC3u¤êm¦ŒµRF;‰ƒRw÷äÜ%ˆ׮]{ð¬3ϼÿ×¾ë{Ÿüä'w¾ÿýïßúïU]\þº×^qå·¿÷ƒS×ήÅ'Ì©³ûzè­W1‚¢NÂ0RA¥ÕlÆY–EQc³”ÌZ¼µÄq‰ ŠHZMÒ,¡\ª$mJå2íf“ Œ±™e´‘b}d'±”J1"$IfcCƒµJ³Ý! ¬S’Ì©uNÚVµãŒ<ÛQ?am¶jåòÝßøæ7ÿ~Ù²•ß2F6ÿ»DUnÚôè|ÃÕW¿~×Ö-ËÞtö]9¯_¬¢"Æhql–b3 "ˆ1xg)—Ëxïi6DQ„wc Î[P0bðêO„$­6†Ø4%s–(Š™h¦¤™Å1ÍVk= ˆœó8§8õx¨bUQï±ÖkË:±>TÖe‚nÝ~`”«füÓŸþËo]tñ%Ÿ9sÖCÿnQÕE?þñï»æ-¿sõÜ =påúuZ¯Tpˆ¨zDÀ9OEØÌâ\F„¤6C€,Í(U+¤­a£Þãœ#KSJ¥Šâ”4é•Jàs`ƒæŸN§Cb $ÃyOt’4w¼G‹on#Í"‚iê°Þ# -kÍ–¤²P÷<+£cO'þð~ðÛoü?]´hÑý/x··V«ýíŽg¶½ýmoùׯëfà•gœ¨ˆ Êq¬6ËÄeåJg-"Å%DÒ E#$í6q\4M £ˆ(Š0AÄ@Ñi·(Wj€Ç{—ƒ§ŠsÂ0(l„aH–Y@ò¿á•(4x͉ƒŠÁ:OäöÉyOàR‰h©'‘¹ OÓ¨Ü_úÓââ¹sæ¶TõXÙô‚¤ÑhÜ}Ôºµ®»ÆÌËN;IMIˆÞ{%®”I: ÞZŒ1„qL»ÙĆ g…v»…ɯÂUņv³AÇxïH;âreZ2œuaD$†H”šƒ±‰6F ÆxÅÁ©u ‚C'³x¯få(ÀÒ‘HÚ´´-=sNÓf{¬ô®÷¼÷Õ+W¬Øö‚ŽÔUõ¤}ôO^±ý©­Ë®}ʼnZ*W$*Ū…nˆËe‚ ÄZG¥V£\¯ƒÞ9â¸D\.“¥)AÒnµ0"„qŒ† ŠH“6ê=ê•Z¬PQ=ýýx猠ª”ë5¼wù.wQK¹£"AQ¬u¤™¥¨z2ç誕(W"¼‚ª§VމB! 3ÄŽ¡É¨–ƒT–­¹\Õ—ª×}ðƒ¯Ûµk×K_°€:ñ _úòú«×¯"Œ"qÎ)ˆa.ˆ.Ë0AHx¯Ø¤Cˆb¼%i5F½C“6q(DqL–fxïi7aˆµ–N§…Ë,A­Fƒµ:Ü[³ÖâÏAU’N–›NU¼óL4ȲŒ4±¨WPHÒܶà-ÆMPv#R²#*QEVwµ>ñøã øÃï¿ê©²–.]zÍ_þóçhslæqKWh–Y1A ˆ‚'‚U¨¢.eïà>³ŸíC“H`ˆ"C«‹²rv/Ç.ì£+²Äa‚ç OLkÓ\Eù47ðÓ¯;r²4— ( MFšfšl3ØÊØ;Þ¡í”rlp^ɬ§·0+™Ó]ƃ uä›Ä5©Fctì!qía »–K\[Z½û®Ÿ¿yóæ“9昇^P€<úȆ{¯þí7_»jV-TgñAL` ê”K5œµAÈ–gpû£Û™½`€ />…®›Ooõž$IÙ;8ʆÇöðË»Ú{ˆu³ê·¸ªµšGýc°…²iŠâ¸D’¦Ém“³“ãcìj°áÙ&õžk–tqÁüyÌî)Hî4Ú–Z<¶{œûL2§±´·’;aH)šÉÎ áƒ~‰â.zûVÉæÇŸ{èСã_p²sçî%;vì˜}Îü~J¥Q¥LÆ…'%¨w4[m~üè6F€^%k–ÏFq¤I†ÍR¼·˜@Y8¯›%óŽâ•¬fÏÞQ¾öƒMÜúè^N™×Ų¹®ˆ3Àã­Ã’Q*WHÚmÚ­&²4cp´Á¦MÂz™·¿æ(fuGñXë°Î‘kU¥V6½¸ÆQ «Œ6R~ôè!îvœ5}5ÂPi'– „’§,ã´|“Þîv>}÷ÜÁÁý ÿÕQÕãå7ýïWîÞ³·;Š#·võêC]rÙ“ÀÞM›6^Ò™+×öâ¼W×jK©¤˜0ï94Þàûlãô³â ¯>ƒ(¢°ð˜Ô jÀY%uu–ysº¸þšõlزÜõOoÚÉÙ+g#Y–& ™%ˆcL‘¶Û¨sÜ¿ã Y¥Ìyg¯àôµ %ÚÍ )"1^ç=^=]Õ€+Î˜ÃÆÝm~ùøA:0P/“eBƒ¤5FMh„—N;©4&'æ¨êi@üðC¬½ïûçMNL–úúúZ/»ðÂ]‹—­xꓟüäèÿNÚ%üßâDà‚×_õÚO}çûwœ”tÒ¸»‰uÚÉpsgõ]ÿ¡ë~ü’ó. ÔµJg½tÏè!Ë2¼sdIÆ­÷>ÁÕo¸€óÏ: #ŽÌY gAóà$¢ÕYk9zyËæŸÂ÷lç[?{’«OZBE¹ªÄ1íV“4Iƒnfùêy¼æ¼•T+!Þe¹Ë…Ôº+tZ´³üVy˜™'œU¼÷¬]8ƒz½—ÛïÛF-Í(Ç!Îw¨mÚ®)zlš¡Þ—ï¹ûç¯ÿOï|çÅÛv΅¡ ŒuÖ±Ç{ôö¿þë/üÐ{}™1ò£ÿëH½ÕjûÍoÜúŽëÞ÷{ÙÖxÏE'®dýêùZ-Eâc÷Áqîxtlbñò¥{\s²÷§/éš=Ð;íÉÄå ?Þ°•ú¢9|øÝ—c]†âóÛª¢äéŠÜµ8kqÎá² oSœÍðÎâmŠwJFÜö“­|ëöÍ\¾v&ÕRÎ:Œš­6îk1oÙÞvùQ´Ó õÔ“‡æù½½w4Æ[d©Åy‡z‡³Šu¹gæœ`©àÂ>îyr­[žaUO "¨. ©­$qÊcOÜÁš£Vn¹ïÁ‡×öG†%3ê:£Ú%„5S׃ŒöˆH’¼ç=×Þý–·¼õ–ÕkÖ|ùÿU½ä}¿÷Ÿß÷ß¿ú•³_qÜÂè%G/Öž®.I­¥Ýj« ñÖâ3§#ÍßèiitxÃKŽÒj9c Q²ÿà?Ü6ÈWþò”J^ó\¢ÅõŠ/¤Á;—?l†³)Þeø,Æeë•8âçöðµ[䥫f‡&)*†;Ÿ<Èég®âu®¡“昢¹g'ù3xT=.³LŽ7p™Ãy‡wë<Îæ¶%óe²° z¹õ'¿ÄŽŒ²´¿N `k+‰ãX÷î~C#ÏʪþšVL€ Œ„$u„"¥~Úñ|Ý×ÈäÙý›8û¬ãÿâoúÜò+þú×­{üñ¯ãÌkßñö|õ¦/]xÝg§µLKåH2ïuptBšI&¢P¯U” ”Z¹,kæ÷éšy}‡c(Å%Ä;þö®Çø×\ÌÚ5 qÎ"b#$˜vWMQY’éçüg‘\Ñ‹)@DI3ÇüÙ=Dåw>ð Kf”ɬç¡Ýc{â ^ûÒuXç@AÉÓð†Ü•5ŠÁL'21dY6%й[Ô«à‰±a/ fÍâþ'ž¢?(•ªHTLjÒ+,¬#µR€1*åX4#”,¨Š*:AhGé©÷Ó5û$yôÁYÜ÷ÓÅmxäw?ñ‰O¼æiCÎ9眗~õ+_~ÛnúÛsoüëY9o&&4òã ÛùÑÆ2ÖH±ÞQ‰VÍé‘KO\Bwµ„ˆ‘ž®Î{Â0"Mžyö Z­rÉ…'ÑÉ2ÄL¥xÕ€¨»P‘#@ð"0¹ŽÏ“¼Rl‹sʧ/cûÞqß±›’!èãòó×䀫#ù>Sò "‡=.—ˆÓ”´•@  5Š÷Šš¢®CµgË—-fäÀ~fWRÄwˆ5õmòT„H‡úT#”®ve!Z Ô~–ÙéYè§Zñ¬Z÷J½÷¯­ýàu¿÷ö];w½xÉ’ÇþE yðî½ö=ï}Ý¥ëúfŸuü*™hµô–_l‘ïoÜ‹„eÂ8&#2;†<¾{ˆUóûè­•àŠh9Ë2¾÷àӼ뗱lé|¼ú|§"H ˜üçBZDL‘Xœ’ŠÜuÍ)Ò "¨Ê´ªC„ÕK¸íîl͸æ5'³pN7^ób”).‡¼Æ’?Š?Wü™¼ÚkÈŠ ¤jþÀç­Sƒ31ÎtQ.×ydË“ÌíªD\Ú&ðãÄé¨òØ„‘C6"Ž”RàÊÝØîµ 3@«y™ºOã¸[âþãeÓ#wôwܱñ­·ÝvÚÿ4u¢ªK¿û½<»=´{ÅúãV«7?ybP6vX0o.í$`d\h'1år•Þî:Ã-Ï—üûŽSŠBĬw88F©VáøcVyŸ§Å%“ƒÔ(†¼nL„€1H!A„ #‚0&ˆr—6Œ"‚(""ÄúgTyÝÅGsþË8ùèù(`LP¨Æ$8œ!ÉïUü>¥&ƒ0$*Źz3Ó…yO@Fà; )=3æR­×m&di‡•LðT;"‰ë ôuG“ã š#צ:°š‘ÞÓÙÑ)K©±Iû«%iúy3î¸ã‡'mÛ¶íÒ)—uòç>ó™õÇ/)½]Ùºk¿>¸sŒzµÆ¡‘QÞ÷Ö·ýUÀGß ý}&(Ñ]¯2Úñ|ó¡ŒMP*Å °Ö­YLµ«žK‚Å#ÌA‘#b"Ä„`BT bLˆ˜„˜0D˜ Œ§2Qˆ ¬W^rÊ2®¾ì:6¯iˆ 0¡)²Ç¦ÈòæÁhAa¿L@‡…Dæbc )E-âS°m¨ĬYóÊ¡"®Á³uÌ“Åuz»ê4[–J<Æ{Þð¡779iÅ¡QJ½K*¯âP»-•æ:göZ¾ýí×j¶NþŸÚM>|Ö¶§·.¼êu/Á%m~ôØ~Á”èëµÜüùµôÕ4&;¬^žqÞ 7|¡Ä]÷+¥Ø²g¤Í{†X»Œ o¶X¼0 óaáï«Få°×¯àE1âQðEIÑ€!@½€Q‚œzŒWL¨„ á¬Ï5(¼µ Pð^¦]\5SÆÚäŸx0jPÉ«ˆa£ÒÌÕ›€/>ƒx‡"šÏzûç°÷À³ÌÈ"ͱž1S§Z.ã¼ç¼Ó2ÞtÅL&›-WcùeÃÎ߸§×^ÉÎýÏrlsôö®ÐgÆ“Ú7oû‡cGÆ'Võõt?õ QÕ•·ÝvÛŠþZÙ¬[<[·g稥§nøØï¯bf¬‚‰»°T ã*¿ûfá˜Õ5¦" ˜ äÅ[ŒOÀ[jµÔ–Èx†³ Š Ã¥ó3®zÕLÝDå.Jå ÖG¬Yî©ö Ю̧ã½2N½g·}ã'„Fÿ:•µê—÷=0ç˜%3QïäÁ#Ú]«rîúµv&Ö„q0ª„Œ‰éí xÙYår„1;5ŸlåëTª•ÜH“« ‘bñÅ †]Íô9¨A§ô¼HaorP(Tš¹º’ B“Û #ˆÁv`Ê­ WZ ï.èp8&„q„z-¼¾bqT,¢)hJ¹T+j:–ÄyÚÇ1™u¼ìÜ3úºˆKeâR…8.G‚gÅü”ÅóJ˜Ò “Piï“™+ص{×ÌÍ>²ü×2ëéíÛf®™ßOê…‘6R.…¬?­•8÷Ùƒ2)%$(!rüºZ5$ C5Ú™Ç $YF\.å@˜Â›’#Ÿs²Áô'Éuº6¶ªùîÖ)0M˜ïz“;AäRæ6ÁÒu¤`¦ÔÔ‘á°–†Âåò@\*¡ÞOŸæu*‹£ˆæu‘0*ѱŠà¢€T¢0$6çœ9€ó1AX&ŠÊ9k&2Ä2£îX4S)W»׊˜ôÝÝsh·ÛÑã?¾èWñÞ‡£cÝ‹f÷3ÚhãªUÃ’ÅÝ@±ËM„qÎy2JÈÂ9ž¾5Ú™g¼Õ!IRLáö‹É½+¯*AîY‰A5Èm†äž–NíØƒ ä*lJ™À|ñƒ`Ä`m:í*ç—K^ó¿ï1øbñu*Q@nkD=Quáþ2u¢\¿à‰!¥•9B² N>®’;*AHDyñ, `‹Á±pnF©R#“ N“(ˆQ1fß¾}=¿H'Iƒ+¾pO+å€z-FÕ ’/hîEEgè®{*å(OÐyÅ*ÄQšgsU‹¯PÓÊBŽÜ°r8±¨RìnšÛ-T Óv'(\¡\ÝÒ™Ë3Ç2•<®)„ej‘sƒù\U•%&¿µ1G€QœŽ‚÷o±YBfQxXZëY²°ŒóާÜmF,ÕŒ5K„¹KºaÜk‰øW¼,UJ¥24}®z™NyÉ»†é¬ì‘ A`òXA Ól£>÷í'q§ê>.Zä¶´X«¼6Ž(Rp°Týôýò¥(b £¨w˜ ×Kb/EÒ²9¿‡Ž§¾Çsž‹ÏR°}aKòïë±€¥ÓîP …4ÍÈT‘@ð0Ój.ó†)-ÄhT|ƒHDh J–çØïÆW ÒÉF“( 1Y­–-¾‡"jQµ0õŒ§Ñ”¢Nûî¥ÐÐjµ±©eb¼‡é,ÆàMA„6‡µÍs[ÅnŘüãº~ÚØO96Ò˜|˨+ûÃRÉtT.…­üᕞv¿Sl‚â}Ÿ¦T–6¤Õš ISœ÷D&/M¡°w#~ú\ï-ê¼í€K2&ššg»ÕbPM¬ÃÚ†VÊÕìW)Å¥´ÚÕ514Ú »’ïðV[Ùµ§™‹<Šú \žUo{CFÆ[¨*Õ8 Pr0t`8gN×9dÚ»B‹…ŸJêk*ùXìºÂ{bÊ#+Üái°¬Mr»ä§b ƒ‘ÜUžŠÖåˆZ‹‘#œЍ^ "aaßÌ´JÔ©œšzð cc)9²@ò8%á¡G[€C5ÏX;—`m'Å¥àvíó¤­IB;IˆˆÏà37sæ¬É_\¾lÙÁ­û‡¬?~…ΨÙ=©<ðð§ŸÒzŹNžw Î%ÍØô¤0ÙȰÎ1P¨•BT¡Gì|öÍÉIz»¨Äg ª¹ÞùàQçQÍð*ù¢úÜxz-vœs8ãpâñâp’á\‚£ƒsm‚0¥\ÏëçøHˆ7ÝG-‹'¯‹xosÒB±û½÷ZH…ºJ!%-ç5ç±™Åze"54²6#‡†ˆCâPðxŒÏ°Îbm…{î?Ä©'Ì æŒ{›zlêp.d"©²g:íÒ„1cû(•ÊvÅÊ{ ÛN=åÄÁ[ÿî&Þò ä¤Å3ôÉ Cò‹ûƹìe#Ì™)¸¬‰w›uPŸ2Ñpüä—J’XÔ{æ÷TÁ9Ú©åî§÷óÄpƒÖØ~>ð…›ùÊ­ÿD½ÖY²4û•rŒqâEátpæ½§“¤ÓQC„aß÷9m~FÒÔN»­h®Â~Bf•0”¢¶þ?/Å‘¡“yŽZØËeg¬Å¹6Oµ)›*õr@Í8&²ŒJ¥Â¿h²bIL`ÀÚ¼LeïKìܧìÚ×Â&ô›¶¶]—ÙÃüyóF–-_µýW‘-wÞqû¾ôùÏ»'v ‹ç̹]#œT>õù|èÝó¨GIž¿ÑŒñ‰„¯}×ðÀÆNÎÁ³v^»Nòè˜å¢W¾œÏ\|½=5Þû–—sÍUçò¹¯ÞÉÿî}ü‡×]ÉŸüÑæ” “ÇéS5ÿô·üÛ˜œlpþð©Oü9ÍvJj_úâ¹ó·òõO¼™Z9ÂÚ õJ»1IÚjrÃWàúþ+Çs F„(0<ýÌ>pݵœtlÌ}qÅ¥‹ùÜMyÛÛßÇ»®ýO´Ûm¼W²ÌÑNRšíŒmÛ¶òî·]û^¾ˆîz‡pѧðäPÆæí;h 1³[Él±mWÀ?æœSË&gPº$dïÁˆÞÝÇø¸£š 1[uªãÍyݯ|ÜZ¿ó×V µo8ö˜£þì¨>3ÿÊóO♃“ú‡‰èïépΩJ_}”ƒ#ž»2lܪ8Û¢Õê°¨7æœ%½lœP>÷©÷³pá:i–ÉÎ8F-c#ã\òæ?#ªôòÍo~“uÇŸ'M‚i'Œáƒ‡øøÇ?Φ‚ÎZoük¨uÍ Ùêpß½¿àšßy3òŽs¹â²Si·Ûàm®^ÒŒÉÑClÙº—ïm6|þËǬ9s1Q7ßr+7}ñOè´ž¥“•9öøWð—Ÿþ+zºëdNIRK'±tRÇÁƒÃ¼ëoEö?Ào¶€FMßMÎÚb:¦Ÿ_ÞûºF71aº˜Œº¨”+$I² Ö.óD¡°k°ÌÃ;ç3ææÐi7Yž<€´t_R—Á¤ÙùúÍ7öÒK/}ÿ¯¤Ýî¬úÜg?sã?yÃ×]u¾VË%ùÑægÙ2”R­VHKcr”‰ÉªkÍ%c¹æÌ¥<øô®zÛë¸øâ³sjg0ÅXì´F Mȶm»¸êÝŸeÙʵüÅ'þœ“N]ó…ƒ*¹;ë¼c²ÑÄy¨Öê¤iÊS[·pçíßç‹_ø<—œ±€\û[˜œKñYŠuyyÖ{>ÀÏîÝÊ“ã¼÷ý×sâɧ`­'ŠBöìÞÍžÝ{˜5³Ÿ•«Wá½'³Ž4µ¤ÖÓhLòã;nçnù{º'¶pöº>Ä[’ :ÔHƒY$á\\u ƒcMžüÅM,é¶´Jh¹N¥çê*íàœÅãÃZÒÃL»Ÿ•²ŽÙ|ÈrÎ+.ØðÞ÷þç¿8ï¼ónþµÙÞJ¥üÔ–-O\÷¥/åÄOîZvöIkõ‚£æËèä6Ý9:*•r %÷jrJgB5ð\sîQÌŸÕËæÁK—ÌÅ;‡¨rhprSëëÃ1™MY¼l>_úø[yïÿ-/Å%¼é·¯æ}×}€JW¥ç”›yÚqÝp?ÿpËÍ|ÿûߣ19Á;^{*×\ý2¼*ûö 0J"Êð6n}–åóz8ãØÌÝ{ˆ½ëjæ­:w¾ã­,Z¼œJ­ÎQÇžâ›há¼'³ž4é°eóÃüùŸý;žx«ÎœÃ¢e3óÞoóö9×FÝ5\6N9îÆ‡UBÚ¬®¤lž#MÊ„A0]è²Y‹$Éè‘!]Rš罎&"Z'Ï?ï¼'ã×–pW®Xùo~ãNþèÇ>º`^_w´dÁl½úìÕrûÃÏè–ýãb¼%Á±hvËNZƼY}d©ÅÚÜX’$ã­×ýŸ{<×¾ã*l©Š÷8åÄãWò½¯\ÇG?ó þáæ¿ãk_ÿ:—]v«V­¥ÙjИœäÀð0÷üÓÝ ¤«°fù\ÞþÚ—rÖiëâ*þ¹oñåoÜÏk^z ׿ûR†‡GøýOŸ‡ŸÜÇÉkçò±·ŸÉ¢¹½|èª.|l ×½ý·è¹ˆÕëŽaöÜyô̘I½§ç¡Ñ˜dó£ò¸™£Õyÿ«–…JÚÉð>'IQ~²qÛ¸ü¬nŒm¢Îe)íÄG'ô8žšh0™¬Ï¹ÃÏÌÀ³¬.âj3¶Oèù/{ùÖÙ³g¸ú_$Œ¢Ýcc#/â‰',ætˆRIDATfþùm·œÿ+Ïו‹fë+NX*Ç/×ÑFGT B™Õ]# Cuªâgh´A§“ ˆ&I&‚gëö}yôVˆ+BÖž ËRê½ÝüÙõodËÓ»yà‘§ÙôÄÜý̃”âc •rÄ•/[Ëòų™;PgÅÒYÌèÀzx–.šÍ¿ûN;n ¡@½ðûo;»7ì@\B’ämp¥j§Ÿ´†cVÌâÐè$C#›™|üA†­â%¤Ýq´ZMz*†ë®XÃÌ®`Z…ùi÷8Ø2¯DDt°¾f¢$S¼Wb#¬¨*-gi[ˆD Pª¡Á9¥•z6LdÝ '<õ¦7½ékW^ùº»ÿ·ˆr½½}wìÛ¿ÿí•rÉ|ìï¾zî;/9•S×­ÔZJÏì^M;ižô0d™ zÇÃOÉ£{éÓ;žÕSO=>ïWC£•LGÄAcêýØ´EÖiÊêU X±|>WÚ³ŠF-Áå)ã ƒˆ¨Ò“Ç%X¬ó\~ÑiàYÒbÏö§¨×Ë t+—œ1Ÿ,ËìõZa©‚sžz!aD½¡Þã5oõNñ®;;¬%³g]ÎS-R(¹}‹!…PDÛÚier°ÕááÔ±¦·¢µ8ÒŠ–ÔKÇ¢‘±Nu´mÙ<’ʪukvýþõ×ëŠ+®øôÿsqÞܹ_Ú³gÏÕ¥r9ýÜM_=ã›wuuÔb]<³W*å íVKí }b÷üüñÝÚ2•áË—O>ý̳˯A`¤Z)16Þ˜.‡Nåö¢¢®â²6kãµCh„ °!y21O­‡q• ŠQçòÔÈÙzLîlà}o8• Š(UëT‚Dxçɲ4¯CWÿ•zi§Eštpi›,ÍÈ\ÎÎÓÉt~ïŸ&BOÙ€¦`SiN޳rùâÝžÀ=´}ûÂ9e gVBºb#™UA†›VÛNƈ’õçž³õýï¿îÖK.½ô£ÿWTÒ… ~}||üìóÎ;ïUŸùìçοåÁ§ùΖž®R:EÇ—Ôº{ÇÎzÙ%[ß}í;7|ù¦¯½wÏãËQ¤V-±tánùÎ/hN6‘8Îu1: L•1a‰¨äQ—༛¦‚ä©- Fv:éˆL×¥ÖUg¢åð^)—«Dån¬Íw»÷n:aàmL\­—Ë ]y“g–彎E3P§ÝæààÐs}ÐégE|†˜L“NCfÍš=öÉOýåßþη—|û;ß=iû¾ggúÑfïÅKàËÝ3s—Îú—]rÿ+^~ÑwןuÖ-ÿ¿¸½===wW«Õ¿}ê©­ï¾ëçwûÌŽgVŒw#øÞžÞ‘eË–n]°`Ñ£§œ~ÚäwÞù>ô ë½ £(bÉÂ94Û >²…3ן@–¹\ü 2iу–3 ƒ#!ˆ/@pEØçѸN0OJŠ`¨¨øU/žÞ徨Ó/û"³¬SR#òÁq©\¤á§ƒÃü±Ðê0xI’ó-O³ÌÞö|èÀå—^~ìC:fpðÀÜv§—ãRg``àÙcŽ9zSµÖõØ™gž±ëya¿·Z­7-X°ðMÿ«óþæ¦ÿvãÄd;› zõìÓÖJ¹±ñ±íœ}Ö‰ØbEüs®òG¤ó}‘fWŒjÁ¯*êC9‡é9 AÄ%læ«Ç"«=½Ñ }$Xîˆ:‰"¨ÏSøZ”óKòÔ|³ãXÔ_«"Ƛ°ÇϚݸð ßÑn·ßÄóp<¯-mgžyæÎ$ÓäÐè˜zãŽ^Æü9}Üóà¤iÄãñÔf2NŽ06Líî"^ptѼN’W3òŽ[Q!0y‡–W=‚XÍaòÛa¾h!u0EbÔç¤äóFÓÃ/ iændTcSêœ6’Äö÷÷ïz¾ÀxÞYµfÝÞ ,7÷ìÕÄÃþç×r×ý1|à@ÁN,Ô rx±sýä§%fJRdê÷#Uœ^@寮¨y(SEŸüý#ÕÕôë¾8=¢œ;õ«2ÓWF&2«ÌéŠð*š9+“Ôöõõ=ý‚múFV¯Yýì=ïÜsžúáÏ—ªzOT*ñw¾ŠÛþ(ƒCC¨ºb¦Ô–?b¡uúw_ÔEÔkQxÊ_›Ž\®Â:IFB÷Á÷È.ªê=25Á¡(Ñúi‰›²U9i’M§ï‡'2v¤œ²´Næ Bݼó€ÌžÙ?|̱ÇíxÁ""ÛÏ=÷œ»žioÛ¾‡ ˜[r±+9õøUlØðx^‚/ÖR¡ÞÏ›hŠ÷Ôw‡Ò#®S¥ÓIˆŠZøá€N‹ö4õ…Ý:B¼N©ª¢vî¦jèùµYš3"§LÙ;œ¶´F¥”{^íNÆŽcœ|±[{ûž}!KëÏ:{󲥋ÞtóRŠ x‡ W^¾ž»ïÝDÖiz:_`ïr)Qo )(ÔŒ÷¹˜î®*À*¢ì©ë›é ˆcœËßw€Su:-=S??/WU^ì½'é$8—¿&;žm:¬œU&µ ¢l—00ú­ Ë–.Ùû‚xøõ¯¿jãÏïÝ̾Á‘¢eÍqìÑË©Õ{øÎw~D ®P)…$±€êÞÙi©˜zO™Z`w„*S’$£ aã­+‚K=B’¦¤å°*snê^_H‡/€ñΓ´;pÂc{ÔËÝÕïΡ[÷Žpú©§lY¼dÙó>uîyDD¶_w݇îé¤Ú~ðá­EIÜc½ã÷ßõjî¼;óõïÑj6õ…4è´L©çóHÛݸÞZ¼Ÿ"øüçâwo§®³Ó“ƒÜjÑëaµä )šzÝMÛš|L“wJÒI™hZØ6Áþ1Ë¥ÇÎ 4ŠW˜hY9Ðð¼þ ¿½¹Ñ˜Üð‚$O‰D\|é«îûÑÏÄY'¨Wo-Οù/o 7þåÍÜsß&ZIðŽ0‚[uØ;R—«•)ɘV;¾èCt–(æÏ™&(vû”TPìú) É ·ŸN¦äL“04’“ñ\æØ{`‚»6q×–qªqÀEÇôPÁY¯(<¹¿ÉâUGíZ´xéÆõë×?ý¼oh~C̾ûÿøÙ·¾õ-Wõoë=jÝɲDÕûÜëUe×®ýÜþ³GxöÀõZ•å‹ç°láLV.Mw½Œ I‘jqÎæ:Ý)ÞÛÜàz›€¬ÃÙŒ° O¨-ì‹s8ç°YÞÄé :(êi·öšdð`ƒ¡Ñ#ãmZ §Jg²Á¼žˆù}1å(tæW@©ê×õ×¼ã]?™3gîï|ðƒ|öß ÉÉÞøÆ7~ñ—wÿôäŸÞò‡Rª–$§å»\ ~T³Ùbÿ¾ƒlØü ŸÜÃãÛö“¤–×.äåg­a ·Jw­L©å†0Q€8OšY’N‡áƒãdEÊ|ßÐÇÛìc²Y´©ùÜ•m2ÖHð^™?Pcþ@•¹3*ôÕKôÔcÄ[‡†§ghy狸D@D¿»qT¤Å®}ôOþø5¯¹âo~ëö¹xèà7žáË?ÙÑU¿ÿ®×pôš…†ÌZñ.ßÉ"yTàF”F³ÅÃí䮞fd¼I'ɦ§Z éï®b&Æš Qhç”Þ*]•˜Ù}U*q˜×7 {2ÐU¢^¨•‚‚‹ì°ÖçeÜÔòìî½dÅô9ïU%g×éðdƆ“²ß÷ßø_þèoæÌ[ø©K/½xðß ›6=zíŸ~üÏÞôóŸÞ~ª%³¢×^|:®?†R%Ö$ÍÄÙ 7½‹x‚¢SA$Og6?§ÙJkᜥ\ ¨W"âÈà¬#³›:¬·ØÌá¬ÇZ›«¬©8§ððr5è¦=°±áQœœñE^Ñ«ì8ØÑ ;&dßxÆšãOò¿}õóæ-øóW¿úU{~Sëõ¯2&vëÖ§~kËã½ìÓŸþÔÙ÷?ðÐÒ8¤zá™ë¸äÜãX´`–Îè©K¹¢Þ«ó™x§ªÞ‰ª-<¢Â Û|QÝT<â]á™i>Ëú8WLcÈAqÖã¦yºSn1 Nðhs²!ƒû‡i%VG'Syr“M{$>LW®X6ôú׿áþ“O9åÞ‹.ºè/~Ókõ¯6HyáÂE×<ñÄ{ï¿ï—çÜ~û«ï¾çÞ¥[¶<¹P|R›ÕWçÍê —.è7‹ç °pN/sêÄQHæcùá9ýzdT®¹ê±EùÕMáræ Ír œ³ØÌ’ÙŒ‘‰ƒ# ö O²c6­m¤b%®¤K–,ÙwÂqÇì:ë¬3Ÿ9ñÄSî{à Îú_cþMFŽ-œ˜X~pøàüíÛŸZôÀƒV>ýÔÓóöîï›èn5›]IÚ)—C‰jeUJ¡©–#*q å8Ì»’Œ‘ 5‚ Š/Œ·sž4W_š¦9­µ“:m§Ž$ó>Ép©—4ˆKI­ZkvuÕ'gÏš9²dÉ’¡cŽY·}Ù²•;ûúúöÕë]Û×­[ûØ¿öÚü›Í~?òX¼xñ5?ûÙ]?éݳgÏŒCC3šæ@’¦ýNgF’$=NÒ•¦Y—µYÅ:WòÞEªê}18ÿ*"¢"ÆI`²À˜4 ÃvG­RO”KñxGcq”K¥C}}}#sçΩջÆûúúÇW­Z9øo½/@^<~Ñú‹Ç‹€¼È‹Çoæø?‚yà 7žê½_xUD(¤@v„M*©j†Áýþð‡·×,!ïY‹ŠçénU5ƘùÈõo¼ñÆUÎùÓÿ™]cäÀõ×_Ç 7Üp–÷~mÑŒ˜¨jID¬1rÿõ×_¿ùcûØùªÌWU#Å &cÌý7ÜpÃ>üáoQ}N?ÌàG>rý7ÞxãçÜKAb@TµL=:@´E¤!ÂùÈG~ññ|^–ÙËE¤©ŠH™)¶˜ª+®i»ÿà>òíçݨßxãŸÝ´i󫺺Jš“bò®ÝiÛáá%"MFÖ®]ýÔ¦M›O®×Ká·JD‹ÞÚé ·K—,½óСƒ¯84r V.•¦h ¨W±wÔQGoÚ¼yóÚRYʇ{‚ÁZG­6£5kÖ¬MÛŸÙ¶> ÅæŸA4M3Ó×7k¢—Æ÷î]Ç¡›"KdVÃeK—ß544¼¢ÕŸ†’g%o …â¿íÁ šO8ètÔ­^½úGû÷XØîŒ*’³aTä~Ñt3vÀÄdbV¯Z³¥R©¼ãCúжçEB¾ô¥/¾â–[¾ñéË.ž=÷”cǃ¤“äi S@£‡[‚QÄTøå#}3¾üå[jï¾öä'®²4EŒŠ¨æmÄ‚Ƅܿ±«½häÌ»ïþÙŒþðøÙåp(:Ôºgð'ºÑ'+Ví|jë†_úÌY•‘ƒ»óᢤ®‡ÏÿÍ–Îe+V.œ÷’Ó+X›!ã­:_üêÃûf̘\|óÌÃ{ˆ{7ttë3rôÈ¡=s÷?ÍÀ ¡*„bŒ#4yÊÞ©Á{„<¶­7ûÎ÷ï{I­ÖÞóÖÞ…Æ?[Ì÷òÑé&kEp.oPmÎ×÷ä˜÷¿ï÷^󼩬0 g=ýô3ÕË/9/¨ë?aù T¯Lynüá럸êuׄÙÁïI”еü3õt²¨|h,0CCƒ3.8{>Ãû†§Ï«Ö,—_rŒùÂMß^pÕ•§ÄËæµ¨åíÓ"ЉªÄ±V›ÍÉ`ÅÒk—AšæÑýÁ‰21‚"Ë×X6¯ƒs†JÍ“;~òt÷Úµ½=ǯš“SS€HÐùü ïYµzaøéÏ=Òsù¥§•V-µªY$"Á?§îM‹‰së]ËeWÜ4«\®ö>Ÿ6$ʲ,¨V»¤—À˜çh»©uA®ÊÅØ‰QIÄ„}j‚H¦õ¥L+©å#”2çe||´Ôß_ £ZM%˜!ÆämÒiæyí«OÐë®ÿÇE¯¼øµ¦ÝÙLõ1EzëîîÅÈS]`T¤J•4ÿo0¸ï½)WjvR!ûƒH Dqç cLЉ|1• ÆØáùäLÅ(.I_Wè½ ƒ &^UEŒL-A¡gejŠÆ*”¤§§ÎÄÄái Ï ¥4ÍL­Òle¨{ÓHÕ C#­ÖØá/à=^S©UËÚAÕŠ×BM)<µ«Îûþà'4­|ž¢÷ÉâE«ÌqÇ.Ç7Ú¢ xOlŸáïÿÛÕÑŒên±6Ëÿƒ‘"¯eL¦Ý]¡kE"弬«°Y†ˆÑR\I|<­W‡QC–YŒ ¼1>±yÁK¢˜ ,‹w #NëL´êüø§‡hµ;Ç‚úLUm—"ah´Tî’,í¦I¾_¼|‡žžº4›ÍÒó H`3q”1iÇA"@e<­wëD{Û¶ÝÑWþj}4:¼‘ï-¢ éé©…>Ç» ñ4ûpÙBÃûôúéÖä§vóÿuCõ%g/§Óï'UÔL©mM6äŒã"ljŸ£T•´#²`~7m¬…áB¼k£.CÐhªµZ§ÞÕ•¶;{Q×uN=X "‹ú ¼›T bî~0æ[ßÒ_uå‰fÏî!î¹ÿÉÎ!7Üß?{ôŒÓÏž Ãñc¼›D]3È&0<¾’ÿè!ÿ[—řǎ‹w©xõ 3gN##£•çÙí5x?K‡¦¡1YæÛÿ¸Ù;—ÕJ‹ƒÉ0&ìÓÉN·oµëý8.F]|„z=¨}U#y]u/‘C‡ÆªëÖôIsòa|–ýsCƒË¦ièÏ9ÒöKÍgÿþÇê¥x&.Æe,šWaç3ÏÛ´éñþW^x*6Ä9 ²Œ1^}‚O‡ÔgãBF]~q_§Æk6¿ö?|é„Y³fM\vÙeÛW¯™Õñ^õ#ølX¼k(*Rª–ôžêƒ·¶®Y§sÏ8z²×fã9Á/¤\IÓ,x~Ág±…ËŽÔFåÖ›VÔW, xzÓ×0¤TŽØøÌѼé­_Z·n•óv¸nÛ;0Áaz`r5?¼«äÓT ut|¼=<<ÆòÅB{r+ÖMÍ.)ø½rø»ä.þáÉ¥m',^0'ß~ ÛÙ™ÿc@`÷êo9:N² &Ù æD^ ¡X›ëÞ,9@ÖË©AYO=va原î<ñ毜•¢ÖÌ{î»cæ¾] f6žxÊ Ÿzò ɒݪvB@hZä„5UN:vråêÅϘNóIÅ'â½Ã§3ÈlF†þyDóve;AÒ›šŠ!´†ˆ‚mlۘϵLÛ†%s2~˜¦.󶓯/î”Ó‚V0:YÒ¼ÞgA’4ºÍw >~æ´ÎRµž³Þÿdî7¨ÐÝ·@“ö„tÚã* ¶.œmer²QV×$mi–Ù)¯Z:“û¦ÌM1á Œs°Yz’¶†%m&D8eå!9ye9Ì.ð‰õš™5’šZý]Ùv«c²ö!\Z¬…ÂŒè.>úžZˆ>KÚh‚ä ¥“¤DQdŸ7@Ts··UÈš1&(åú<\̇þt¤yÆi Ëï}ufìÞ)æÿkïêY£ˆ¢è½óÆy»3³Éî&›Íb‘“HL„ˆ½••¿Á: ’Ö?`!v’B"ˆE Q$!Ć„ ˜MH÷ÓÙ™÷Þµ˜›¬‚…©ä~î|œ7ó8çrÏ0‘G8žßâ…A“G"2p€Ø‰O(†8lÌ€ª¢ãrCø!FešÐ›±áÕrv÷À¯{y~4198IóOw»wΛÂß`"(%ÀáIPToX R­»$Á •`r k68®´"A"Ì¢hŠc8ƒ~…«‘B ~jxãŒ"‘…È‹âEqäWàQ®`ìJH)¨ŸjÕ-pÝNÓ?Òj…ÞØ…áðÑ“r$›3$3ˆ%qbÜ.=ž_æç‡fúüú RmE"óáÝðÕš?Tr]{ÿÔ¼,DÜ™››{~pP¼ÉLÖQƒ@èØöέð{©t‘1S…ñ¦\çsÓoYJ©Q¿—ÇkLÆ-Ëô=¯9OzÆ30ʤ3Ë•Ê%"àär}kårå²Td·‹”ÒL÷¦6ÃHPàcñÀŽ çî"‘àË}ÙôÃFû]­ÕoàI3ªûB Pø¹þÌBI¬Öª·ÇÁïqa{µ½Å¥)Êä^Z–uovvöàTÑø‹Hcì­”òºnáꕆ&D¢¡ ÑЄhB44!š MÈÿ†Ÿ[€Öàä>qIEND®B`‚remuco-source-0.9.6/client/android/res/drawable/remuco_100_background.xml0000644000000000000000000000044611700415064026321 0ustar rootroot00000000000000 remuco-source-0.9.6/client/android/res/drawable/remuco_128.png0000644000000000000000000005477511700415064024136 0ustar rootroot00000000000000‰PNG  IHDR€€Ã>aËsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœ IDATxÚì½w¼]Wuïûs®¶Ëé’Žº¬b¹H¶Ü 6¶qÁÆ€)l 8<.-Ä€ É%„Ð.pSÓü0űqïUn²-˲¬bµ£Stv[e–ûÇ\{Ÿc $÷Ýï‘–>û³÷9g—µ×sŒßøß˜‚ÇãÀqà8p8ŽÇãÀqà8p8ŽÇãÀqàø­:¶nÝzà"üoâ·í„§§§éïïÿ•ÏqÎ@ÅS*ÎYk"cl(„PB ­s‡p8' pRk38´äJ©L‘!D'‚ü€üšçBˆŸÿ" ,o 0b)ò|¸Õl7‘V»=˜gY§“†´#³4“Y–ª½ÝnEA`Œ©J)Wy~êï?âÁ¼þú[vÿý÷¯Üùü®yP£ƒU–Œô1¯¹¾1·¿F%B9A«ÕF*‰¥$ PRíV‹$©„{÷ì! Ò,%#œ3¤Z!TD«#‰5Ž8qÖÑNs m1ÖöÞÓ9mSœÔ9öµr&ÚšF®I-X`xh°±víá[ÎxÉKž;öØã'Ž>úè-sæÌ½¥Ñh<>:::ðå/™w¾óÿõ Ë2â8ÀZ»VqÚw¾ýÏ'|éª/óðcµ§'‡—×8dáóú†j‰¨„Â韬”8çH’ðYÜÃXK'd6B‚@QhÑš0ŠÈ³Œ$Ih·šT«UZÍ&A’vÚXc°@Z1¿:5hm½Á…!HÓœ( ÐÆg¡$Ö‚çZ[ríhä…KµûZ㙦©•z­¹ü ƒö\øšW?õ¾÷ðN!Õ}ý7<úè£yä‘ÿõ#€sŽ<Ï_9>>~ÊÛßö»gþøºë­Ç8gÍ"qÈœ*µjÅÕëuatC`tAÇXcRÐj¶pÎF!E–ãp„aH©ÈÚ-, óœ$©”A‘uÚ¤Y%%I¥F§Ý$©Tè´ZHå_kŠ‚ýÍ”ÔHœµ!ÉrM’DcQJeš4/z‘F)‰Ö–F+EJdzhã0Æ ¤ ×8ƒ»:°£Ùrí,-[²ë‹_üâŽ;þÄõëׯÿŸçŸ~±iÓ&>øàÿz¦)I’PEÁ?ºöÿ>ïøÀ9[7o^zÎÚżxõâ$Æ:RRJÜl§±†<ÏqÖH¥(ò¬—Jœs´Ûm¬.H*UŠ_%D1RŒ1DI‚!$àó²ÎsŸç“á@FHP B¤’$Õzy2„R ¤þý¥"KS’Z åÁ)Aà?§ÙÎÃk,BÉž•’D¡" ¤TÀZ‡Ã‘ÄZÂ(@ uŽ PHJVE}î¬uâ¡ïX¸{çŽä¬³Ï™á…Þ»|ùòâ7aùk_õy<;é–oxÑ¥—½å²µ úÔ›^²ÎÕûêXc1EŽ5ç¬7fQÔjäY)$yÚF*E\­b%KStQøk-GµÞ‡Š<ÃC¥V'V“"ËHЬCÚi£‚€ €³–BûÈPí¯SdVkœsH% •¥R QDJIžÄqHXëHS1ë,yîAa…ä…éE!„¯XpeôÈÈ6G"8hå¹bñâãÄw¾ûýSþîkÿãèÕ«W_vÓM7†¿ øµF€V«E¥R!Ïó‘çwl{Ûë/ºøµ2m ÿÞYG¸z­*„P„Q„TÞ Æ„€(IÊ0­qÖ ¥"LtQgAEÖ9Â(F8h·[Y† $!Bx£ )R‘g)qìW»Ö:Ï ã!”_õ…*QAˆ’ ÁZš­ gÝ 6)±…ŒÅZç«íÐÖbŒ%P’(Reê0„Jç$q\U!u‚¾•®hï·ßñ³ƒ?äàéuG»ã Ÿÿüó¿Õ V«u˽‹ÿöª«ß¼ùÙ%ðÒu®¯VQR!ˆB¬µ!pÆ’ÔjH)Ñ…FHIßà q­†Ä9ëWv”$¤I¥†) ÒN)Iµê¿T Â<ë`´F•Zë,íVƒ¤Z§xk-JIÞ I½†µ>yžBã¬&‰CÂ8Ä–DŠB—D‡ pÚ`£¯S«F”˜pÔ’ˆJ¬(tA-Ѹ¢Í„®E½Z­~¹sVFŸúËOŸ1=5õª}èCÑo=°Ö®žœ?ým—ÿÞkN]>X9ê Q¡”Gí*J‚uÈ0ÀjTÖY‚0Â9G§Ùð—k-Eš’u:È@¡ó­}”Â4ÍÐEA…äYê_‘k4ÎXT(Ežgè¼@*ÕCïYš!J®ÁƒÖ!$ÆZ:©ö)ËZœ‡#/,JJòB£ ÂÀ¯«v§Wž»sä…!×¾”ÔÆ`…ĉˆ ªRˆ[]$úBá6oº·¶`Á‚Æ¥—¾ißUW]õÌo­”HöÌÿþÉ+Ͼ㖛×]tÊa ö׉“ Fk‚(F °Ö‡^)•¯½%8ëȳ%%Öò,%í¤L6ZLîoRè‚@Özp„à Z«Ñi5q¬5¨ ¤È:Xk £°,Õ¬_¹yAœTȳJ &œ¼„p>Ê ‰‚4Ó„a@§#•@š,/heíÂÒ)4Ö8„säeÔR!|¸5Ö"”@ ïpJ†¨  B×qÕ¥bb×#rjr—9ï¼óÓÑÑÑ[o»í6ûë²Qðëdü€>`þ?}ã›/Z9:Äè@̓7­Qaäy<E^Ð7Pë•`F¬6´Òœg¶íæñ<7Ѧú+ ÙÊét2æÔ"VÌíçy}Ô#AÔl`%Ž=SèçˆÂ€ÜŸ“O3Zƒ€4m£¤,S…!ÊòË‘v:¨0ö!_…frºÍþNξT³·]0•j¤’Tb Z¹ÁYËP0¨$skÕc}?A[GUJZ !QÐD›)DÑGÖêƒx –Ì£üdÕömÛ/ºè¢5Ÿüä'ù­s€8ŽqÎÕo¹é†CwìÜ3rúÉ«œ. DR gBJêýP‚¶ P웜溞f_šsÐòùœwþñ¬Y9Ê¢Ñ~ÂÀ3tº0LL7Ùöü$oÚÅc›v³{çuá8vÙKæDhã! k>¤ë‚0Šh5¦©Öë­qÆøÕ*%a“e²${’j"Ïh5šL5;<¼£ÅžvÁÐP²ÅuNšWcÁPB_E!pXkÑÚ1ÕÌÙ>ž²yw“Íc)ùx›åCæ×}9ëœÇBHÚy «¦(L º*ƒËܳáM7ݰôàÕ‡¬~»ࡇâ˜cŽ˜{Ýu×­Üá‹Gˆ¢ˆ¨’„Q™—Ï·%ŸÕ<ðä6¾qÛ.{͉¼üÌu,@*pÆâ¬Æ”墎Á˜þú(kžÇkòÃØ³gš;Ú·~º•Cœµz.q’àŒ&KSâ8ÁZKR©Òi6q*ÕEž£ó‚,MRDžðÉÓ”,KÙ°»Å[&9õÈ…\°zˆ¡¾ˆ88ëÓ‰µk}ºP†ûCë‡/®ÑìlÞÕâ§ëÇÙ9qøœišt“zÜBÉmR¢j?ÕÊ wÝyת·¾ís>ñ‰OÿøÇõ¯ºæ{öìattô×çyžEQØ…BˆJ⇜ssÎ-kí¸16uÎu€O>õôÈp-¦J!¤ôÈÙA%XkZ §SÿíÁ§¹oÛ_ùÔeyø2œ°8cÀi¬° Rzúi‡% `ñÂ.ž$/;e_úÎ|ëáç9keÆ’á*Õj£5i§ ÎW*aH‘eäyŽ’J­Nš¦4÷ïÇ!›ns×¶&: øø[O`ñh)V‹<-°Ò", -8‡ ÊóÂ!¥¥¯ª8rùÍ«qõ=»ypO“C‡bª‘BJé+Ž¢ƒ šYhFQ¯ °}ûö¹N{ðÌ3Ϭ~ìcK 0 Xçg­B4ŒµSÖØìÞ½›ùóçÿ¿çZë.ß.ãƒw=¿mõµ×þèÐ7íß?„Q¨.\Ø:ñ„vœvú…܃3«víÞSY8XÁá©RQòÏ™mı×ãXËwo1PãÛ_x#sp¶@8 œ)AX$§3õ•Äb‘¬3€£ æÞr÷>¶“oýô1žÜ9ÅÙ‡Ï'Žâ8-òœ,MÉÓ´d #ZÍ&Ež…ë·îã±ñ”sO>ˆ3]Bx‡³Tk1a è´3,¬ôN€+õEÞ¡…(0ŽZÀ[ÎXÎMÆyü™}6˜ÐW‘ä…A¨[4)òQ’’¦ŽþJ•í{wÔL‘-8ê˜ã^¨§ŸÜpè¿Ýpê͛Ÿl6šQR©è%‹7_üâo9þÄ“ŸL³ì]÷ÕëõiçW_}5_|ñÿ™¤iJE±¤(Š‹6>õÄ‚¾ÿ}gÞrû]‡eY„JÊÁZ(:¹qÍT;(³lñ¢}ïý¿Þ}ûEo¸dK£ÙŒæ÷×EX õ¡·Zƒu\{ßSŒÇ×>|µzœ'„,Â7+”a.ôÀQx7r€W]ùFŒÄ‹@œÕ'®[ÈŠÅ|íóýGwqñÑK ¢¬S ¡'|ZÍi²,¥Ón7>±‹]&à×ÇÂÑ>ÿþV—+I˜D¨@Ðj¤ Ki™ –n#Ë–ÓÃQ©§± 'BžÚ´“µ ß ²QAKw(Y–‡YšFwßqë‹>qå•§?°þ‘•y¡¥B†*ÚX§má” ìêU+v~àýï¿õ•¯zí©ccc?BÜÿÔ JÓIR)¿€;bçóÛßøWŸù‹£¿ü寞+§N»‹{ŸÙ˶‰Gqøæñ‰ýÕå5=ÿ¢W‹0ñ+><"Oju~zßh ßÿò»k@”ýw|GÍuï­-ok Æø{«5ÖX£=¥lµlÎItnøÜ¿>Ȇ ;xÕÚù$@AYμ³Ýá‘=)Ó*âŠËŽ£Rz¤ÖöÎÇÖŸ_‘ç4§SlI;k±ÖbÃXS>kš-ûIMÈ7öµ6l{ʽì¥g=tÝõ?;6Ô7·V¡Wª‚QUÚ6tc­»'v‰,opæ/~ø?|ÅýÇÂOžÛºõÇÇ{lqÇwpê©§þ?ëæyqÚ–g7]pñÅ_ðè#üº“WsÒênÞЀâ£5é•Zœ£ÕlQÆmÛÏ5÷>-¶M´yÉ¡óÝE§¬³_µ¯Îؾ)þñ¶Ç¹â}rÊI‡ãœö·$Y(keïž·wÎãk}¹eµ) ßu3Æh¬.QÚï_®ÛÀM·>ū֎Ò?Ї1†ÆÔ•Z)àúÇŸ'â½G­Ì8\錇¾Î‡’Op޼“Ñjvp%lÁ_ãoÖJ 1…ìGË&§›üýîàоˆ Z$äÑ(&YJR­3±ç Úü¨ „+ûæVb§„¢l@+i‚8îC$s˜rƒŒ·¦Ùº}=#ÃÉÄ}øn|Ã%oºfáÂ…ÿ pÍ5×ðêW¿ú?çû÷ïg``€¢(ŽoNO]pì±Ç\>=±oþGßpýqàâ8ARä)YšE Y–¢ MÇ¤í” IóŒÛßÊÒ9}¬˜?ì)Ó8& BÚ­6?·‡‰8áSyqìû¥ëíÎŒýÎsïÎaq8kÀXl œñªçô ¢Ñc4F{ÊsøòÕðܦ]œ»z„NÖ¡’TétZ<¸½Áó.á¯Þs•Jˆ³¾!4;uW=x'°8(W|»Ù&O L×1g_[ŒƒÂD˜ ŸB bD6>Æm÷?Ésj b’¾ñ"DXEe»\gr³¦C¸v¦…’’$RkÈ´#RŠTCAŒ¬Ì¡.uY8Äægo¦kö¯?ûƒ—½â‚Ÿ-]²äÿÓ½€4MÀ3:59ñò3N?ýÒ©±=ó?rñinÉè\ú„ $"ç¹½ûÙ:•ñÄö½ìkTúÁ9†æ '1IñÒcVqð¢¹ëe\IœxÁOíä’WŸJœ„½ü*…©B‚P©åï„RH¡2@¨!¤ Aˆ #” {þ¦TOE’w¾þXl½ÆÏŽS­Öh·S¶ï/Ø¡#>õû§Q¯'\ÉþI¤ò %©üÍ¿Ÿïõ+éõ‡BJ’j‚ Rz±ˆoDù²PHßv–Ò"LÀà¤bù²ÕTêURm¨„…&9‰Ìq:ÃÅ`5BJ)ú«!qä?7•5²d>ãj.YØG_bˆò] ›ÅˆÜ/V­~™ ãÅÕ+®¸â‚ûï½çEÛ·ï8½Z©”Îü€@¯µƒN§ýƼÿ¿ù؆'—_ù†SÜâ¹CBë¡7=òw>õ<”Lû°Šy} /Z=cWÌŸQó‰ ‘”„aD–çdiÆC›w3Ñ<Ž?æ`Ͼ!ýJï¿26‰nð9¤C8 X¤7Vø ìJ'¥¼ÛõœÆy,Cœ„|üòó‘/ÝÄ“;Æ™[Q<°»Ã»/;…á‘zÉ1Èr•—âggÎët磀Ã!‘ˆ0$©$´-.Ò€“8RœpHáKZasQm˜•-eûæÍ Õ¹ÎQ6GA]¥¤í U:QH¦3ÁæFLƒA²xÏE:AÜÙÊH±…eìEOf$}ˆe+ÎtO<ö¾~ðý¯øö·¿3uëm·mBìûOõ´ÖçÜ{÷ݧ~èŠ?~ÅÛÎZœ´v¥0VÓlwøÖ­Oò³ÇŸ'w Ñm›J…v0ÙÎytÛ84ãàÅs”"¢A OÁZcøÆmOðGïy«V.ö„­ ¤`E¹ê½S”Côþ áŸ/åÌó™y­w7ë¹xÁ¯?I1¤Æ÷ïØÂö¦áØuËxåé‡–Þæ•8¢t¤®7ŠÒɺç9ÛI»Þ®Bå5Š®,K2Ú9ßÛÀ ¬X`U„UªIÂ]6±¨G RÅËä¢ð!Z:vvàñi… ¥,¡0þÚVçRTbÒÖ˜hM³(j t“¨:WT†sÏl¼½ÖjMóÒ—žg¾ô¥/=ð¦km¿Rê¨|äŠÓ– Uã“[æ¢$Á1ÿr×fÞÑ`tt”ªUO°Ôj5*• IâY¾ŸÜÃOîÛD§Ó)s±Á!ÐZÓlvxnç>âz•w¨Ï£B”Š[Ù3¬(¸Ýß;!qÒ‡e%ƒòï¡"ð‚N(„ P*D!2ÊT …T !}h>úð…~ØB:Rñ¶W… …—q‰ÙŸ/g4³~/D——Þ)J‡•*µÚŒÃÎj$yµH Bä([–¡¡ù ô±k:£f“aŠ&Îd$‘¢Z ÙK6¥1µZ•Z-¡V ¨Å†ŠlS¡I’ÄDsÖÐ<Ž í(¦ûŸ¤^à O–×ÿÛukžÙôô ?þøê_ée÷îkøýƒï¾ûÞ5¼h-Ãsæc-?¼÷i¶N,KLL¶Ø;ÖbßDJ«mP*$Žcâ8¦’ÄÜ´q÷nÚC„Ôê5¤ôâ g Û'šœ~ÒaD•jouÏùU&ï Hé#(œPÞ0¨ÒY$BxÃËˆÒøRH–÷Ý¿+„D‘âÍç¯å#¿s2µze&ÒȃKÙuÊ®ÁÅŒSJ1Ë!|êqB†*ݳR3â¿»(é4Ø ár\PaÍò¥ìng(¦(¨õX‚}©e{ÓW«R©T¨V«híØ7¶Ÿñ}“4öïÇê&Q.gªzÏt"úØCö,óÏø´úþ÷¾³,Š¢—þ» ( Œ1R)uاÿâÓ§öW#Ž]5Š.26íØË£;üPfžçù~>üÎ~N9*# ,mp|óZÅö]²‡œsܼq7ËGªÌŸ3DµZ!K Â0 YÀ™G­B†!8í .fx´Ù¡U”#[]> —Š•óìœñ©¹tgYNýɼKçPåc§KcYDz¥sʶ±óu¥‘±>¿;•|N9€×«°ÂâD÷µ)%F:¯n*Ì Ž‘ À€'¹(VƒÉ!€åK–së}S­( È:„ÊÐ1–ÍMI˜Tˆã˜ ™œœ`ñh‡w¼!aÞ<ËîFÆÍO¤lÜk@ÔpƒË™ÌÆx¾µ•añ ƒ#12﮽öÚcßþŽ?¸÷á‡^tÔQG=ÿ  C„ɆÇ9ú¡G_rÆË](²´Ã]›Æa‚Ö†e‹-WíP.¾`ˆ9s¨õõsúIU¾ðQÉ+ÏŒ Â*ªÌýÔðÈö ZÍ&­fc ­NÆt–³tÉüÒÆÈÑ »%‚ö«gf%Qþì3ƒÞqº¿ŸU5H…ìV åÊJ•U‚pJ9š¥ô1F(éA œ²˜žn EesšMÍLsgÀšò$ Îùþ¹p–ý I‘ëÞEŠ”$P¢ä i³M³¾üuW¥®¼ŸÉǾ©#zNæf—h¢›fç}f½^ÌD­.}Û‹~­Yg<¾ï‘63q¨û£›]”ŽíÞé˜1Pi¢Þ¨™ëíÐݺJ#6cbj S&R¢'6‘R°{o>Ó•tGW}TàlŽ5Øg ¤°LL;¬-°VICn Ó­Û.‰cSè"ûeЊãĆIÒŸj‚sôÅ~Þ-ËaûζŸÚ麀óFÇørÖôÛw4[%Ü_ ÑyÓeì›ð}þ„;f’@7TºÞ'Î*Ýì¦÷]ôßuáf°è¦©nÒŸw/°Ïñ¡e~@Õ‚1ÆïCT´v"¤æÁ§yš¡‹”¹2Å:‡“Ó»D%zÑÂE[£(Ì_àG}´Ï=Q´iÍšÃÆòÓël«Õ–ý}±x€Í!Ÿþâ³üÍ'¦«ÓžÓèÌ 4÷=*yô)ïÖZ’€} íNFQ6ìšâÁ­ãÌY8‡Îþ=|á_oæ‹ÿtSODÑT¿D½ôB¸*f˜Ö_¶“Ê/{ýì×ü*™´ûOüm¶äW½æW½Ç±+F8÷ø*ÃËC­”0€e}!µH1ZQ<ß*0&" [¶ÜýÀ8k©—ZC‡Ö†B Œç"Æš†§¶JšÍý¸¢É°LI ‹‰"Ó[X¾|ÁäàðÈ– ô/­œsOœxÂI{… ²{žØš¼ä˜CÄ’¡*ÕIr²þñ_û§ç¸ôÂ¹àŠž` „Íyt£ã ßäY ­5…Ö¶ Î`_…‡7íäÞ ŽXw(ú– 9é˜ÕT*—½öÅœ{Æ:¦§;|ì³ßcÓÖ½œpüqüå§þ¼äÁå/(p¬µüÕg¿ÀÈðÚhþþ¿ñ‚‹üÚ×¾–¾ï½ìo´èdy^ð•¯|™û?ÿoç³xþ08¯,ÆAžetûiw4Ÿ¿úa>pÅÇ9ìð5Da€*I£J%áôQ¶?{7'·ëoyžCäÒ×®äò÷ßΛ.yïy×;Kpèp?^¦5iVÐN ÆÇÇøýw¼—­›ÃÁ j$‰×é¾b9ýCKxfOƒ‡wlgžh²r¤Ê™1^øM°¢¸Ê?ÿ`’?x³ft$¤ÈÚhL!À4;ŠŸÝÝÏŽ]mtž’èI†£‚¢ØŸe.Í›âØãŽÝâ¹7¿àÎ9ÆÆöMœ~Æ.]4ÿ¥×¯ß\9ã胩Ä1'¯šÃ¿mch°«¯dûó ~çuæÔ§qÂ0¹ßðÝëà‡7+i¯Ä5†HºŃìØ5Á=»Ú|æOÿ€Ž]ƒP%£æ,#Ê12:SXÞy›wþÉ×ý®ßBräñ§^|)g#x{ÈZÞ|Ù›yðÁ•“RŠ÷àƒ¼÷}$ÚiF³òèƒwsÏ=÷pþ‹×röéÇø¹ƒ^H·XciLŽÓn4¹ðŒ•Üxã\øú7P˜C A¹Ü?ÿË¿rÒ‰'°o¢Å›ßpBÂg¿²žz½?ü£²öˆ5~uZ¿:óÂÐÉ ÚŒv'ã¾úy¢NZ=LJr­H±ÖX°h„Ñ£¬mî¼û§lŸÚÂAsö53råI¬ýÍ>>ý·ã¼ü%’ ‹Õ°asÂõõ±mJS¸6¶3Á·“gdô1îQ˜³Ï9÷I­‹-÷Þ{¯ûBÐl6MŽ}èo>÷¹óŸÚ¶—5«–°rN9•1¦²Œz½Ÿ»jrý­{™3¤1E‹ç÷x°æ\AQäEAQ>Zc´òÏ÷nç-oy'·Öãír\ÊS›1&o!¤àìÅ+Î|˜ÝôWýíUüù¢%Ì[°„0PH%¼ ·<ß¡¡a~ôãsË-·ðÜsÏ¡‚³Ï~©ß Í™n¶i6šl~úQ>yåGÁd¼ç²—€(çñ¬¯Çýðˆ£Ò?LQXN?ö nøÛ›ùÜgÿšw¾û½Ô† E %µzwÞuïxû;ø«/]K¥Ráõ¯=÷}éKÄqBQht¹Lžû½;‚éÆ4Þs+ÿøÏË¥‰rc .×Á‘bdJµ¾£{·]ÿwd ód‡=™*û!BÎ埮™à?h1wHÐè´s‡¬æhÕ¤°9ª½‹¹ªá‹S±ojŒcŽ9êéE‹–ì¹ñÆŸ=÷+禧Kšý—¯[wä{Ÿ_xëy'¸8ŽÄ¶}Ó\óÐNŒŒ¨Õ<Ïßn§ìÝ»°ã÷ñ+Š‚Nš± ?ä’ã—HÉŸÿøQ½ñ*ªƒ¾ Ò•[•›5d­q\¹ kÖnñÎ?þ;n»ÿiÎ>ë%|èƒäÈcN Š«e˜™°Îù1süVm4#ÏrZ­?²ž»ï¼•o|ã›TƒŒO½ïŽ;î_ ƒ- œ5¾ö¶Î>'˜ßËôä~>ÿíûY¶æTÞòÖ·³æˆ£¼ì\z‰yµ’vü~CQ(hvü&WÝ•Ÿšõ©é?ùøÇ—Kløõoÿð°£—ÍÃý ÷U™S xbÛ^¼72Õl6ȲŒ¢(ÈóœNš±t0æ’SetÞܱ½‘ñûoyeoÖÏè‚}»vA”TËíXRßKN>jcû&¹î¦{øÉO¯cÇÖ-zð ‚0¡°‚¼Ðd…!׆NZÐj¶™žœ`çö-Ü|ãu|î¯?Í×¾ú?¸ýöÛ9xñŸýà 8lí¡,û&Ø·o%(Å“å<ùÌN6<½“¾JD8ŽY=Jkl_ùúw¸í®è¯ÆôÕ+eX7VÒÉsš¬\íš4Ó´³œVcšÇÖßÏg?ó\uÕUÌ)¶òò£†8hÔï?du92æüÔ’±ã$BÆ#‚~víÙŠhîf¸ЯSŒFîÕÕZk¿Á…ó8 È 2] ²iǨ¹ÆBÓÄ<9>ΑG¬Ý|ñßxßå—_þ?†~æ™g~yøÞ÷¾Ç…^Èž=»†Æ÷M|ôâ‹/º`ßέ«>vÑi®Z« ¥ íøÞ]Ù1Ùi–1==íOÈZÖ,êç5'B_LLMó…᡾„•Ζ-[9û¢ðwŸygŸs*ÆÒé1ÏZÏ¢é,ãæÛáÊ/\ÃÞ‰&Arák_ÅYgÍ¢EKi·LÝi³uÛ6n¾ù|ðÁÞ—¨rÉËÖñºs`htB\󓻸òªë°Öñ—ï9/;kÓ“Ó|þë·ðàÜ“Vòî ×ùñ.íhw2zj7×Þ¹WስGrô1ǰté‡è!Œ¬uäYF£¹Ÿ|ï»|óß`¨ð†S±ja Åå<£õSÇ}Ï4¹}Sƒ×Ÿz#‘‡ 0Ébn¸ùT'ž`ñ@‚”’(lÞoÙ™•Ó’dëÎ$&XV÷ B,ÂAa¤ÛØ(DÃ’}òWþxÑ’eŸºä’Kø•ƒ!^xaW<¹oߨw¯¸âÃs.¿ü ÿþ†õÕw¼â$Rô‡’7r0›vM²u¬Ád+Åͯ‘Ë¡‹†Y¾`¥@Ðîø=~&÷7}ˆ/ûìÛvìÁX˦-»8BׇÉÚûqhÀ$1çœy‡¯œÃ+N]Í[Tcé/:PÁ9ÇôÄ8#ƒ1sG9æÐy`…1¤YáS@¦±fˆ(¡+œó’1º›ÝÉf×Ñ@%”( }±ÅÙ )3´I±EÆs‚ÑZ仲ݞ=°0\;*¡D¿g±ò¢­eG³[Z†WœÞ}¿ñÒûï¾û®ïÝyçÙwÞùŸßàˆ#Öšûï¿ÿ^ôÆyív;ü“OüÙùÏïO~÷ì£Yº`¾+ #’JŒs§žçW*@kƒµŽÂîöGŸ?|à ˆ Oo儆„-W<Â×Éôè`ߊªƒØ¸JÞiàLQŽjÁàPƒƒ5Ö¬YÑkªt&ÎêDz£…Q… ®ûß÷ØB˜·`.NûžykrŒÏmaÎH?N€Ó†ùCcjXëUH\é!0Æ28wY»M»1IžvpÎ"…¡ ’( ¯ª<4ÆO&[[îdê»/h w™ªÒª…k3pi{š,m1U8{ÿž¦\Ñ’Á$ 0–z¹Oa£ã»†€GG[·µ™‹]æ´S_ôäï¾í÷î^¿þ¡ÏìcÛ÷¿½AD™ ò›nºñ«—^ö;ÓIRqóù/¼èãß¼iÁikǬ\èV/ž+¬6T«UÚ­E–²oºå{n¸{㱫‘ggŸqÚ“×ßx˺ç¶ï'žà GR4[é ijݱp)C’Ú0ÖxêÖè´¤pMiøîm&œJ¥PA0N|®ç\³fË‹.4Z)ÿø£Çy×EÇR­%X!ý¦” )«5Úhžvã˜xE–Qd¿-m‘cŠ íü†’Vk?&î\9Ænžt/hÃ`%@ ‹u˜‚o‘¾ŠK -žÝ;ŞɦÐÖ±víÚgÞóÆ7>xôQGNÞ~ç=‡=¿{"î:ÿÒÅóè¯Wxø‰-`,N‰Þ ½ÿÇË;‚ˆT˜øÐirŒÎz2.„ð¿îä'Êñq1K½É,oùC_ÿ{&:e‚jÿ02ˆý8·1Øò?‰èéÊ®¡5¶Ü·¸F”$å&~$¼»½­Ñz&äã˜Ø;F¦ó_ä©_@e{‘¨†"ïk4gœqú³oyëïÝ÷«¿½æ'?½î¸­­NHŒ¡.×V4´¥cüTãÉ'°á ox㓇vø½7üìgÿðWŸùÌÄ´ëxð«ùvÿÂW¿úÕ9ðã§Ÿ~ú©?þèÇ_ù»o}Ûúï|ûêµwÞu×Ê;w mÜ72s†æ¶Î9á”]çœsΓ‡¶fÇ‚… ÇZºd`ÎÈ`cûó{cQ^ÐÑy#ô׫ì›â©§Ÿcõ¡+Jãt•7¾ÁbëzBø1/ËŒ\ÇÚ®¸¢Œ ³šÇ3/d>œƒ ôïÆQå…«U¸ýC¯‡?Óxè¶mE©lvœRxI¸o˜ùvs­ÞGÚÞW¦€Ù»Ø©˜µ 4ÍÿjïËãã*®t¿ºKß^Ôjí²6Ë6^±Á`6†„Åc’̃@2ÉCBÈÌ›ìÃæIä%“e^ö™I^&™ÉLB! d1ðÂjƒ¼à]Þ$Y²ÔR·z»kÕyܺݷe›`ˆ ðÓùGêíÞºU§N:õ︶ MSŴޮܲeîYºì½ó7}ëqï=g?ÿÂÆÃÇFër¶¥Gâ>½¾>¿pᙃ«®^õR÷ŒYƒœó'V®\ùøä1|M$Q×^{-î»ï>0Æú®¸bÅw¾ýíï̺õ¯þÇô›oùHG±«7K%ƒˆ„‰–ÆF<÷>|hÿUW]•%¢Õímã‡Gš\Ï/ÒF0v'Œà¥=‡0gþL ý–(I&’U «d +#“ª×F¢m âòUX®p¾óÁžª•ØFyú§wÁÚ]ÆAT¾ú(7†ü¨ ÍçL”àSª2œ±ˆâ³ŽÏ.T(æ‹GKu©ó¾ûïÿa{[[qÉ’%³>õ™Û§[–Ù^ÈçR–eꄦ€xž{dû¶mû?û¹Ïåÿä4q÷ßY“{l-Z´¨oöìÙ}·Ýv›Ê9W†††.84UCCCüÞ{ï Ϲüœ9s†Ÿ{批¹"R ï¾â<<¸n#öõ HÂH 2VAn~qWÁ q±% Ù ;;þ˜ ±rw•…¦j¸JÀ'Œ°îûqÿ  'QA²Šˆª©„°@™gX `r¤bªoA¤Œe3¨¯«ÏÇ ëÞ~{VþtÏÕW_½wÕªUÊèè¨:11Á¸HÄãü¹gŸO>õÔ«¢“}ÕD‘û÷ïÇí·ß.Am/+™eË– <üÐZäòªoH1¦(¸ìÂEP†{£X, ™¬‘äPáYTµT† Õ²„µ$DçRÉÌ—Ö\Tf`0 È‹Uø3Á5(L…ŠÓY¾™(7"@ ±28Ä?ä üPtî‰38žÀxÉCC&ý-ß±Íæóè8cVVÕ´£áŽ\»v-­]»ö•ôù§`„çñ‘ —_»i¯Ÿ…C~ºT,Ãm«¯ÄÀpþa ˆ\P€ù§I¤Œ b…tE((¤âøÙ6þ¬^Á`på ØŽ ]“œB$7áï…B |€®®<½U½¤pÓåÿ\2£–·D÷+Œ.ꈣü”LAßÐ8«KÕší{ï¹çç…7µÔ×û)hš¦m;÷Üs3}GFÜ‘cib8sgwá3¹ÿñëgà– Ò¡’1sÁ%`C€ˆKf.”¢+ë~å;BÎöÊ`‰Ð€ŠòÌ,•,hŠtÕ‚Ï…(·KH«ã›É ² ~ÀJŽ€Î@Aa¿Ä‡œU.íÛgä±dz©¸*¿Çผd1猙£±xbç¤Æ›s Lã»–,Y2RS“ÌÿúwÏÊu\&E0»a¸'ðìú­~'àý+é"_|į(C½ƒLˆ,Ñ»ö*VÁ²]Ä ª®KrG.·m”PÀFJ‚|bJ.€CÓ XË ¶iú Ü9gl<ÛWÀ¥ójýäQùü%‹ãHº€ Î?oo}}ÃÑŸþô'#o ¶Q¶m¹õÖo®KÕæÿëáõð\O:ç~\À0 ô|âZüòÑm¸ûÀsÌ.½Rì åÁ’°*iâ‰s SŸD(-± ¾Py/l! xùu…õ›*Ǻ¥ô?f(-®+ðRîÌá]gÕaa{¼¼l€Fr6&&®~÷{öØöàƒ:o`Œ¡¦&q¬¦65xóêŸ JÉxIDAT~ô©180\Žš1áŸÑ·´µàÛŸ¿ ;÷ áÓwþCGŽøÎª½s‹·ð“ÕOLá•’(†žÇýƒélв Eÿ¤%rŸ„ BI¾à²@yƒ@L¦Ï ˜Å²9¿~!£®\ÂYqŸ ÄD¾þ@óæÍ=4wÞü±¯}íkÏàuåõºc ‚óg?ô‘[÷x¤eûÈÁ¥WOÒT{hmkÁþö/qåEgâŸü~vï£èÛ{c£cð¸ß¿ûQhª†DÂÀœî6Lk®ÅŒ®f$jÑrú¸> ŸÎƒrê:Ú[ÐÑÞä£xæŸ=gFòT.T!·€J(¨d[.Æó%ŒŒ—É™ÏYÈmäKŽÜ)<³„Q\¾ šêeøÏJÖ– Z·g‚uu¶­X±bû=÷Üóøë9&¯[ùøþþ~tuu¡¿¿¿9=:Ò{å•+ol¬ÕîýÞg(Y›`\x•äÎPÀœˆP*™ÈŒå0pt[w àà`}ýiLäJ¨K%ð¶…ÓqÑ’YhiH@a@sCÒçKÄ,˜ê3ÐrÏó‘¹VÉÄX¶.3ƒ800Ž¢åb(ÇØ„Zzüv8ÇÑt¦, ß4ÐRCSÊ@cÒ@2ª£>ñ+‡ Å̘\ Hn5?†ÉB• '÷æÙ ‡‹Xó¥/Þwî’ó¸zõêGÇÇÇù[N`ÇŽX¸p!ÆÇ3+~ÿðooüÐ-·~ðŠ ç=Ÿ¼--u2«W"gC¡\(!"îù\r?pxwÄÓ›bd,!—CU|m*æt5¢µ1 ad¼€Ñl ƒ#9Dt¥Rœ‚€íu0t­õqÔÕø%渨D 5ÆÐÕœ@DWQUaªŸç¨\6ž8ÁãCƒðlW*XÅY ºÜñˆv5ÙïwMÐM7þ÷'oXý¡‡yäáþæ7¿YxKZ€°lÞ´IëšÞ}ý½?ÿÙuwü}Ï;;š©¯y;½kÅ$“q&~æ1IÒ‰àMT‡‰‰f™ƒ<^v¬òEÓ¯>*¶ãà`ÿÒã Ô%£¨KÆÐÞ’„‘@NOøE,xòLç"¤…ÛV*û$SÈË;AÈŽg0‘ð3Ž "A¯B±°éPžÌxâ½×üŦn¼ií¾}û¾Çw»ñÆq÷Ýw¿u ŒQ;pàÀû·oÛºê‹_üßmÞ²mNS} ®[ù6\·ò|´·5B ‚42ô[F× .­Bˆ6ER§€ûÛ:^.2EåuWÈÝFpV$†ze S¨ÖƒûÛ5A\y»ç/pmÓÆÈÑyß¼p!`9»†LzáPž9Ú¦µŒøC·<½lùòMO>ùä÷¾þõ¯§ÿ“ñÏbŠpðà¡KÇYþØ#kþèßÿý‚]»÷µZ–›?kšvÉùsñ¶Å³ÐÒT‡Tm j>šØŸ…<ä¹û\{åóƒ`sÈN•½½Õåx>çþ,ök挑³Ï>{xæs3ÍÍÍNMMÍç|óöíÛ7­[·nlxxØÞ¾}»x#ôûFN$±XL]·nÝ,ÈÎÐ4­Ãó܆RÉLr™d___ÓƒZ K©ËIJ¹‰X¡PŠ8®«ºž§p+犂 !ü‚=eºç=>ó]z…‘ÂRU…TE!UÓ„¦ªB×5‘ˆÇœÚd]__Wjll(¶´´Ntuv¦gΜ9ÚÐÐ4aÄbE]×s\ˆÁR±xäÑG=ð­o}kâÚÇoh˜,7Ýt“¶zõê„ JDôH À’Œ¡ )îºIîyÉB±4M+aYVÂuݘç¹Ïã!¸&iD‚ùŒwJ€ScL(ªâ©ŠêªšjëšnEŒˆ5ŒB"‘(èšžgªš'b9!xŽs‘gŒ•\×- ùÒáÇ wÞy§õféÓ7•œHt]g©T 555Èçó ãœ39ë’´žBEö+yf ùgBþ%ƘP…E!"¢h4J¹\¦i'àˆÒu®ëbJ¦dJ¦dJ¦ä­$kÖ¬yM¿¿ë®»Nû½_k_Ïþx­}òZÚÁ^CƒÛ‰èægU‚ˆ4óK‚Ø¥/‘Ê3ˆÈ°£···O^ãL²*¤Á¡ àHooïfù -Œ±óqâÒ· ÀΞžžýkÖ¬9À"ÆXP Á!¢ˆtì D´¾··7}×]wuÑÙŒ1U¶Urãxš1Vp €ÚI÷â^ìéé9ºfÍš€w0Æê¥S¨Q@D¾§‘-¯i0cE":ÐÛÛ»Q>W+€²½*Ƙ+òQ2cÌ"¢<€ƒ½½½ÏJ0™æO¦RÃTÆØ'=Ï{Ÿã¸Ué¹ÕÔ­ “?cÌ÷Žu]@‡ã8‹¸LÐ¯Ê cLn¹ˆÉüírO@Q¡šØµ{,ÿŽw\q€sNÏ<³nÞÜ9-‡¢ø…y£ðoAP˜ÊŽÚfCÃŒCçž»8÷ÔSO6¥gÖ¥¢ÇµÏvˆõõ†>üáíÿÑþmöYg5·)Ìa1! dù"@sß’%ç?ôгgt×Ô)ŠŠÃèh‘ššçìIÕ¦Üý}›´4Ç´°‚pΨï@nüÚk¯ï[¿~CƒªdfÕÔ@“ILUIa,jªÊ`ÙˆÁ „Jœï?R,Í_pþ¾éÓ§;=¶®iZ«˜i\ ¦(>."ø[鿎‘ ¡ò¾ƒ9󬳖îíîî~\qGOOÏ+Æœ2"HÓ´K×®ý}ûç>ûÎÖ•ga›Ù²&1%H© UØ’'î~§(2W4Þò±{óéôXì7¿úXjzÓ^x®ÆüìØpŽf c(ÑBý–¿ú}Ç¢E ÇÚ×vÏß©‹‘Ai¾ íŸïH§Ça7ÿëw.Ó3Ã.•ÉñÑ|þþ‹;:T:wqªõ ; –™.[ EѰóP îü‡ Mmíí…ßrNü‚³Çý“Hù\‰ä4|ºg{Ûöí;†ËuþŸX*˦FUüJ¡ óù‹SHcä #hÚÑÌùµ¼ù¾¹ïÿ [ÚÚ"ßøâÜC²êYÀ¨Já™êW® ˆ#D´tñâ䊫0¯§§÷`¡Pèpä´)€T6;¡Ÿµ°Ì; y“Â''±-/‡Ù3¢ˆÆôØÄD¦vÙ²N:ºûy¦+ÊËÚ$"¤‘ÆÜ¹Óâ¶m+…üD¢³-3ëN24nâ¹Byàßu^½ê|Í- È‚Já\sB"JP2lÛV[£P«ò,²ØˆçxˆD ®*šÀ*“‹‰.xÛüçÝ;RçžÓKD ‡WŠ\ˆ †XP¡B0 Î[”"f23æÎn2˜ÈÊ6øÈ¡ã;„U-­°qÖâf«aL‰3Ƨ4¡_…D<ÏSb±˜Z Þ+\I2 $„‹Ç®2E««*8¬Ï±D š“x?EkF}}NËf³z"Qkj° ©ãîQ*äqëG߉¥Ë?Õñ¯]«ÙVT½þ8Ÿ¤.^ðV ªš‚¢…ÖE…IÀ_»£NÉÒ¡jõ rCßIÀ0ÏóEaLUàZݤ’U'ï"ÀãĺºZ‘NÝ] ¦¨>Ò£v©žY:K&0M3Âü*^§UT!ÓTVAÌNš…á¬R]Š%‹0¿ÄI5ã>­?þÅúÂq\(ŒÁ²_ÂŽý¼{Æ™ñùó§ƒ;…€MªJ<×Âìé«V½=:½Íb‚Û²Õt2±( kBó"1ìØiÒíét:nD: ø8„;Úi)X0·6lèÚ¸ikó?®¹Üq³lö…Ç`[4MD.ÈË’ð2erBU‹`ÓŽ4öõ^rÉ¥Gnû뜧ë÷òËW¸hùY™X,Æe ó-©ò2^±|͈cãÖQìï+õ·¶¶çv÷•Íh2÷òå‹ÜÍ@×pÎÙI‚cj/€»Ã¨ì¹ñq|úÖåê•—¾7uÙEQ |.¾‘Â9xïÒ/›‹{d4}d6ñ ¸sì8`zeÌ3˜í% „A ¥}Þ)Š‘Îv®5þŽ[]äÐÖÚˆ\.g¸3 îdª¾ÓžòhÓ“ï‹–,D›j‘9q¸ÊœpÝatÂu=¿€«; <3;ÛA”m~êɇRwþ¯U‘¶VÝxná³÷Ûõ‹[ñD}^Uc…¶öî1À†çŽ@¸…ò5\Ò1³« Ž=6m` ÓÚÖÜÌl³³ËKxc~Š;õÀî«T$rp­Á =›4­Š=ˆ3Ûu ì6«6-ŠR‹-[Q*òâ²eKGï»oÿlÎ3píIK!›ï`øø3âÈ‘4w]NŠ¢rB\°ô¼1ËrZÚ[\”†#˜ ²xýmas/)e‚b“eŽ ½õL‹Å(ƒ Ï„ëŒW+‰=Àu¢`È•¼ãNM+ j´Âu]…àÎ0sí¡ªþ¨ègÿÒm8®j4¦vÞ(®Zš"5ÒÉ2y-Zrš£ßøþ±æmÛwÒyg·À³‡ˆ»¹ò½\èn°èžÿÛÕ#*âÚã°‹ƒUÜu‚ÏD±X‚aD„ 5Ÿ^`ˆs¸–}œFpX`“¸ ¼R×­tñÿ~ÕܰmÛŽ”e»®À59…WE9R£øÖWßΊ¦®† Ûâ:St<øÐþî ë³ZS°o¿U)¯J@4Ùš†yȯwrå÷D;âu³‘ÙÏË—ûM(šê,ËÒˆžíÂ3O-!׉d˲t!"äX.sM§Êíð¬!Æ0@¡œð=€}€–æ3‹NC4u[À³<æ9Õ×È[‡™ŽÃ€”ŽÛÀç4ö8E%âTδWípÀ5/é;†[±`úrǶV=ÈÀ®Çñµ/|˜]·ú±é†AŠà ®) }†gžµs“ýLIù…‘=Ñ­³YĈÁ3‹p+K1TMCQ]‰+ßóÝÿƒ…L˜ÏI'L¨»7|l3þí«‹ÈÍ=W¶’ŒÛµ€ñ‰<“X‘~ v c2_Á³ÜSƒqGYraI!àÚ ž}ŠË±«Ã¶]¨ªê‘8•àW£ç\Q¡”™ ÐŽÑ"ºæ¦Ìýç÷Ä.ìGf¸ŸUfªZö8»æ=³þ㧘¦¦PÊÊÊ퓤DÅŠ¹@¬¾ãÙ¢ÒÐPÃJ9”2ÅIÔÆðü–"††rÖP¶-V[È:ºéþu&^z©ßá¸Ü0³(—Ÿc ¨ÂcÈ4sí™™WÃ1ÀˆÔÒø±x<îÓÈ.©¬”9ñÆã¤ PoP¡`³H¤Q¨Zv° ¯ü>w†AfÉa‘ˆœbž>BÄ&”xÃhœqu¹GIx`Š£f;kÑ‚¡â×C{þÎPc$Dzâï4o_Þ¡~û»¿§­›©ëì2Ç:ÉÔc L@Qè5]øá¼úº˜VÓ¼DmœY(j[‘Þã ¾¾ilûþDÛõ—~@uÌ,Zæ\̾ü¾tfÍ:c$ÖxNW\ãþ™…¢hh}!€_à¹Yûæ÷¿×h®¬ŠúE¥qœ“ ¨j¦ÖÉþéwãÚkWnßödK¢óÚx¼þÐËjS5(ª^¾Oªm6Û´å_p͵—Ol޶ɽ᚛usü ˆ»’ÓÀó«ë0%òËÇr^ÞiXúb62ú„רØ0V, §ºœŸ’|õ«_½cûö«7nÜÐÖ=£Uq]!ˆt]cÁ*•hÖg‰ ¶¥êj‰ËlEõ‹0Nd'hÁ‚%‡Ÿxâ©öήFýåša;. Nä:.utt;v4•H¨±h,rz ÃGÓâÂå—Ü´qckCS´`è¡Å‹Ï 8thw‡¦Œ1À²\â‚ȵ-V_ß<ÑÞޙ߻oGg<cÕNž,ÿÎi²^¶=/zW¬¸lpÆŒîÁÍ›_œ±wßζd2¦¼Üôr³ef«„È¥2Ù–.˜?ïá(Ô‡vìØ1 ú?  ®®®¡yF뇧&&?RÈçfkUÜu´+ADmY×´Æa-ƒ-“Öš™eh ð`9R†É€CmÙT*ÙÓÖÞ~«Wñîœ|Çœ²ù}í/ì~î®ññ܉©8ϩ˵s²hJJÔÇj”±°lžžƒH„AÕ·¨†~dhBÉÈ`$ÖÓ–Z[Z~—­kø\w÷+;Þ1«Ö¬iï9pðß+­Þ´¸Um^ÒŠtÌ6FkÖ:"kMóÖ‚ÁàiÆh„‘x~ß×ðC]µ¥ÀeMŽÒò=£”]uÜÊžzr{Ï[ù&߀T‚È ÞM çM‘åd“ã ¥â²Xõf‹ùÓŽ?~õýýƒ‡_ÐÖÖÖ‘Ëå~.mصf~ƒªF }Ã%«[—7‹U Ôš‰ñݻӹ؀¿Øº  $$ˆH0áØE͘(zxlï8†*'®™…‹O_ I¤µõ˜¹©,!áÆH5àÅsΉæàªëö``À ËRÁ;ÜÔ}°»ULU¼LÌQ¶)™ ÆeïQLiœzrʱ5Fl¸Æy¡j:2¤ !H:ÒP„µD6í0¦©@@€À f‡Pd@’X ™8é„F(•‚£€Sß¿?)˜ˆ$‘sbB@S*"B,.k%I8Š@TKFl-ÂÈ‚H¼}‰¸VkNƒ€P€xm_üaÄf¦W×jVb`£†A¨GA9„Æ ­Í‚eCéÀŒ¡Áb‘±ôôŽI,ê¨8ÀÀ@€0dHb(¶xô·{pÞY'!Š4˜f¬A¬Á°0Q€Ð÷¡CQÕCP­@‡¬Ö0ÆÀè0Öjè DP­Â+WP)•áU5üHalʇ‚EBƦ"ìÝ[ÀQ+b`Mø÷û!DœÉTA`k´ª£—,Éõìß?UðÃLC&)nûIÖk0«Õ÷M‰¸Ðè/3fø!Îýø×q° sÚ[‹¹ FrSð<U?À¼9íLæ hmH€™Qö"¤Ó `r9XA‰t6‹D<c¦ÊP¢1C^3\À‘ ·ÿd_»†ðÊ¡)ìÛ; ÇÆ¨U À5(€ÓÔØxo67ÕÁéT‚Ûg¦¸½5ÆéTœŽâ-i¾è¼M<ºçyþ¼dA/ìœÇÏnßÁÅ|‘?sÙgyÉ’%¼uËi|ÓßÝ‹;çò¦µ¼ûžOñÓ?¾7¯Ç+W®àGŸøoÞº…;æÎä]óù™Ý{¸o,ÏŸý•¼hN+_µ¥/ߺW/ZÆuñ/lLsS6Æ­Š›\®KµÙÙ©,Ç” S©Ô³6nŒ¬_¿~ãŽOoëš‘u’ñ8õOú¨T}8Âbýü:˜Œpã×.å»ï·ô­k/Äž—{pŵw`x¬„¥K–bùŠåËM`çÎçà{EÌŸU"Æy[—ãɽØ(‡†lT¶ õ-hŸ;…B»w>æ±i#éî}1Š®•¼mç.êt5¦4¸¢‰˜™’È‹"!‚Yí³.í¸]ÀàààÀ‚ùè{OC›—¶PWK4ÁX`ÏP'n8š¾yë=8ù=+±qÍRœwæz8’ј•¶ˆ†d„å ñ¹‹7áü3× RñaƬ–$êÓ1|üô%X·¸1xHq²2*÷cys€S–(4Ƽ§±½'Äìz—žiƒ,,¹°ˆ³¥Rd‘g²ét桱\îzÁ«Õh÷¡ƒ_YØ9_îíë»z`²ÂT+3lÁ T2•ˆFFÇ]m å*„tÉdðùKÎ[k#°Õ°ÖÀj E¸ìÂqÚÅ·â²sWáýº„²™3›Sˆ¡_Eày¨V›Â}n¯• $?t’áõáSB“€¤|]¾.”ƒŠ' bqHÇ \ÉB[F¾â¡„ÎœŽŽïÄ2™û}éH¤Ó¿šßÙyA±X_èêêrº»»m±TŠþÐ_ñ&BÇöõõù4±rœþGŸÚm¯øäÈMñÈã»ÀZO‹ 6¶¦…­[ 65:°ÖÖ4rí:OW¡<}ža™Q žê ±b†Ä`ÑX&*ôööö°ÝÝÝ€èoK'“¿/š†ºÎ=}ßrûËÃêFG°&‚ѵ¡u£5L‚™k Îm M­h3ÚÂh3½^# Cìòa,£#بX[_WßÛñímhnœù@êðG?{Ü\uééT©úøÄUÿˆ^:ù0Q…0QP:D0Ú€15µŒ\E Äx¾‚wNaÛ*N˜-x¸ÄlA‘Pò‰w¬­rê©§Æv>·óçFW·üò¶Ë–†4®ÿνØöÔ^´·ÖcÓºÅH'½x&®‚1!Xk¼¸‰˜ÀÈx¥rÕj°Xc`ÌÃþ¬Õ,ÙÒ†Ù—4~¹ŸtHñý‹,^ûüž]•w¬±µúØU+÷Ø÷@*¡Z/úÀyòÆ%8Ô;Š]/ à¥îa¤kcˆMMi1cQ,‡H&ŒN”1«)ÎuqIqXÑî"(—‘›¨ o"ÀÎQ2“k[ÛÚ?62<ô£w¼µ¸nÍq+_޻ﮊç-bf¹la;g’.³åXŠÇ‚ ZÓhoNA‡zšß¢¨ í{(–<ì=8c5 å*¶½0ŽJUÛIÏØ@[J&’ÝÙLÝW‡G†ïz}`{Ç›»³gŸU©”/2lç•ËÞcL1³¨Ï$ª®#éH¿ª&¾˜-3´a.yËÌQ”J¥’ƒÙlö¶þþ{ˆÈþ¯¶×;::æÏli•V#ÝÛè$c£&"– Hz­/ ËÒZ¥úæ¦Í Mƒã¹‘¨¯¯/ òß}ÿøú7¿/FG‡eÅ©Zñá8 Í3暯üÍEæŠO}ÓÉšÀ’)aoýîçõ§.ûŠ _f²³íÍ7^¢pË¿89o’Æ‹ }ÓWÿÊ^wÃuN6ã+.ÿ¢þÊ ×(£]\{Í_뛾óò{ß½¹ytäð""B<é9î¸ãâûö¿r4” AƲ¼á‹ß{òò«Ï7o `öìYg”ËÅo âÔë»ûF³6–­ëçˆ2g‡¡‰G*!HZËEÖÄbR€5ÖjÃ6æ Å µµ®#„¡”"¥”ù|¹ê²É|Z_”,*õ¨®.9EHÞ•Ï®`Þ @,™L=¹fuëŠÇ'cÌ€ÄL¿y2oö(Ч?Ö)¼j„ J†ÿù_ÒI'´Ûµ«êÄs/”ðУ¸ø/aN»CwÞ=`õ䕟^ŽÉ)cø“½â²O,·™„ß¿³Û³¼Ž6_/bq  ¥Àßï€Ç%ä¼92 ÍxòéR´ýÙñžööŽ•ìóÞ°jhjAP-'6?ƒ¯½rú‡Bîí÷è½ëëp•wˆú+ôåÏ/@oÇmþ yž&k™ß³¶_úÌzù•*‚ äo_¿”düj[ŽúŠüÉ ÚiϾÿôÓý|þÙ³xáüîøY/­[U‡k¿0¿ÝQ‚”’û‡"„¡¡¹iþÒå 04\E±b°òè ®ûÖxzç„L¤oÞÜ•µ®2Y]†_ pùÕC8xÈbh¨ËÚDLjÜtÝb>Ô¯ñÝÛ{¸![¡?À æ€î»£L4Èl-ìTèîƒÌ8GH$ÈŒ íÇ6ÚQuýì‹vª ©T ˆ°FpçϦ̽¿ÊÑS÷.$²%AéЛw§åtµhò€×\š€¼Ânìë–Öh+ÂòËä-z4†±IB:EXÔ ãUzâY[Þ«q÷}à”gœTGÛŸ³ÈÄöbõB#žºÛE[óh?"C6GT>ŒÏ\  „âbÉå[~ =¡KÏcóGÌ›ALÁ d¢L­w¤Ä›ÿ(Ô@ä&¥xäñzÜÿ8¸o8âO(+ÖËò¡' remuco-source-0.9.6/client/android/res/layout/action_dialog.xml0000644000000000000000000000130411700415064024572 0ustar rootroot00000000000000