pax_global_header00006660000000000000000000000064132347764730014532gustar00rootroot0000000000000052 comment=72deafacae9e5c6cfa83f1f466966438449eceef seafile-6.1.5/000077500000000000000000000000001323477647300131535ustar00rootroot00000000000000seafile-6.1.5/.gitignore000066400000000000000000000043271323477647300151510ustar00rootroot00000000000000*~ *.bak *.o *.exe cscope* *# Makefile.in ltmain.sh libtool *.lo *.la install-sh depcomp config.guess config.h config.log config.status config.sub config.cache configure */.deps autom4te* po/POTFILES po/Makefile* po/stamp-it po/*.gmo po/*.pot missing mkinstalldirs stamp-h1 *.libs/ Makefile aclocal.m4 *core m4/intltool.m4 m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 ccnet-*.tar.gz config.h.in py-compile intltool-extract.in intltool-merge.in intltool-update.in *.stamp *.pyc *.tmp.ui *.defs *.log .deps *.db *.dll *.aps *.so build-stamp debian/files debian/seafile debian/*.substvars lib/searpc-marshal.h lib/searpc-signature.h lib/*.tmp lib/dir.c lib/dirent.c lib/seafile-object.h lib/task.c lib/webaccess.c lib/branch.c lib/commit.c lib/crypt.c lib/repo.c lib/copy-task.c app/seafile app/seafserv-tool daemon/seaf-daemon gui/gtk/seafile-applet server/seaf-server server/gc/seafserv-gc monitor/seaf-mon controller/seafile-controller fileserver/fileserver tests/common-conf.sh tools/seaf-server-init *.mo seafile-web tests/basic/conf1/c882e263e9d02c63ca6b61c68508761cbc74c358.peer tests/basic/conf1/c882e263e9d02c63ca6b61c68508761cbc74c358.user tests/basic/conf1/group-db/ tests/basic/conf1/peer-db/ tests/basic/conf1/user-db/ tests/basic/conf2/376cf9b6ef33a6839cf1fc096131893b5ecc673f.peer tests/basic/conf2/376cf9b6ef33a6839cf1fc096131893b5ecc673f.user tests/basic/conf2/group-db/ tests/basic/conf2/peer-db/ tests/basic/conf2/user-db/ tests/basic/conf3/1e5b5e0f49010b94aa6c2995a6e7b7cba462d388.peer tests/basic/conf3/1e5b5e0f49010b94aa6c2995a6e7b7cba462d388.user tests/basic/conf3/group-db/ tests/basic/conf3/peer-db/ tests/basic/conf3/user-db/ tests/basic/conf4/93ae3e01eea6667cbdd03c4afde413ccd9f1eb43.peer tests/basic/conf4/93ae3e01eea6667cbdd03c4afde413ccd9f1eb43.user tests/basic/conf4/peer-db/ tests/basic/conf4/user-db/ web/local_settings.py gui/win/applet-po-gbk.h *.dylib .DS_Store gui/mac/seafile/build/ gui/mac/seafile/ccnet gui/mac/seafile/seaf-daemon gui/mac/seafile/seafileweb.app web/build/ web/dist/ tests/basic/conf2/misc/ tests/basic/conf2/seafile-data/ tests/test-cdc tests/test-index tests/test-seafile-fmt *.pc seaf-fsck *.tar.gz fuse/seaf-fuse server/gc/seaf-migrate /compile /test-driver *.dmp /symbols seafile-6.1.5/.travis.yml000066400000000000000000000011501323477647300152610ustar00rootroot00000000000000sudo: false # Must set language to python so we can install custom python pacakges in # docker-based travis builds language: python compiler: - gcc - clang addons: apt: packages: - valac - uuid-dev - libevent-dev - libarchive-dev - intltool - re2c - libjansson-dev - libonig-dev - libfuse-dev - net-tools cache: directories: - $HOME/.cache/pip - $HOME/.ccache - $HOME/downloads before_install: - ccache -s - export PATH=/usr/lib/ccache:${PATH} install: - ./integration-tests/install-deps.sh script: - ./integration-tests/run.py seafile-6.1.5/LICENSE.txt000066400000000000000000000443611323477647300150060ustar00rootroot00000000000000This program is released under GPLv2, with the following addition permission to link with OpenSSL library. If you modify this program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, Seafile Ltd. grants you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. seafile-6.1.5/Makefile.am000066400000000000000000000004361323477647300152120ustar00rootroot00000000000000SUBDIRS = include lib common daemon app doc python DIST_SUBDIRS = include lib common app daemon doc python EXTRA_DIST = install-sh $(INTLTOOL) README.markdown scripts debian msi LICENSE.txt dmg ACLOCAL_AMFLAGS = -I m4 dist-hook: git log --format='%H' -1 > $(distdir)/latest_commit seafile-6.1.5/README.markdown000066400000000000000000000103061323477647300156540ustar00rootroot00000000000000Introduction [![Build Status](https://secure.travis-ci.org/haiwen/seafile.svg?branch=master)](http://travis-ci.org/haiwen/seafile) ============ Seafile is an open source cloud storage system with privacy protection and teamwork features. Collections of files are called libraries. Each library can be synced separately. A library can also be encrypted with a user chosen password. Seafile also allows users to create groups and easily sharing files into groups. Feature Summary =============== Seafile has the following features: ### File syncing 1. Selective sync for any folder. 2. Correctly handles file conflicts based on history instead of timestamp. 3. Only transfer content delta to the server. Interrupted transfers can be resumed. 4. Sync with two or more servers. 5. Sync with existing folders. ### File sharing and collaboration 1. Sharing folders between users or into groups. 3. Download links with password protection 4. Upload links 5. Version control with configurable revision number. 6. Restoring deleted files from trash, history or snapshots. ### Privacy protection 1. Library encryption with a user chosen password. 2. Client side encryption when using the desktop syncing. Internal ======== Seafile's version control model is similar to Git, but it is simplified for automatic synchronization. Each Seafile library behaves like a Git repository. It has its own unique history, which consists of a list of commits. A commit points to the root of a file system snapshot. The snapshot consists of directories and files. Files are further divided into blocks for more efficient network transfer and storage usage. However, Seafile doesn't rely on Git to run. Source repositories for Seafile components ========================================== Each component of Seafile has its own source code repository on Github. * Sync client daemon (this repository): https://github.com/haiwen/seafile * Sync client GUI: https://github.com/haiwen/seafile-client * Server core: https://github.com/haiwen/seafile-server * Server web UI: https://github.com/haiwen/seahub * iOS app: https://github.com/haiwen/seafile-iOS * Android app: https://github.com/haiwen/seadroid * WebDAV: https://github.com/haiwen/seafdav Before version 6.0, the source code of "sync client daemon" and "server core" are mixed together in https://github.com/haiwen/seafile. But after 6.0 version, the server core is separated into its own repository. For this reason, the sync client daemon repository is still the "front page" for Seafile project on Github. Build and Run ============= See Bug and Feature Request Reports =============================== Please only submit bugs in GitHub issues (Pro customers should contact us via Email): * Server and Web interface (Seahub): https://github.com/haiwen/seafile/issues * Desktop client: https://github.com/haiwen/seafile-client/issues * Android client: https://github.com/haiwen/seadroid/issues * iOS client: https://github.com/haiwen/seafile-iOS/issues Feature requests and installation/usage problem should be asked in the forum https://forum.seafile.com/. Internationalization (I18n) =========================== * [Translate Seafile web ui](https://github.com/haiwen/seafile/wiki/Seahub-Translation) * [Translate Seafile desktop client](https://github.com/haiwen/seafile-client/#internationalization) * [Translate Seafile Android app](https://github.com/haiwen/seadroid#internationalization) * [Translate Seafile iOS app](https://github.com/haiwen/seafile-ios#internationalization-i18n) Change Logs =========== See Why Open Source =============== Our primary goal is to build a first-class product. We think this goal can only be achieved by collaborating with the whole world. Contributing =========== For more informations read [Contribution](http://manual.seafile.com/contribution.html). License ======= - Seafile iOS client: Apache License v2 - Seafile Android client: GPLv3 - Desktop syncing client (this repository): GPLv2 - Seafile Server core: AGPLv3 - Seahub (Seafile server Web UI): Apache License v2 Contact ======= Twitter: @seafile Forum: seafile-6.1.5/app/000077500000000000000000000000001323477647300137335ustar00rootroot00000000000000seafile-6.1.5/app/Makefile.am000066400000000000000000000000561323477647300157700ustar00rootroot00000000000000bin_SCRIPTS = seaf-cli EXTRA_DIST = seaf-cli seafile-6.1.5/app/seaf-cli000077500000000000000000000651571323477647300153620ustar00rootroot00000000000000#!/usr/bin/env python # pylint: disable=E1121 ''' seaf-cli is command line interface for seafile client. Subcommands: init: create config files for seafile client start: start and run seafile client as daemon stop: stop seafile client list: list local liraries status: show syncing status download: download a library from seafile server (using libary id) download-by-name: download a library from seafile server (using library name) sync: synchronize an existing folder with a library in seafile server desync: desynchronize a library with seafile server create: create a new library Detail ====== Seafile client stores all its configure information in a config dir. The default location is `~/.ccnet`. All the commands below accept an option `-c `. init ---- Initialize seafile client. This command initializes the config dir. It also creates sub-directories `seafile-data` and `seafile` under `parent-dir`. `seafile-data` is used to store internal data, while `seafile` is used as the default location put downloaded libraries. seaf-cli init [-c ] -d start ----- Start seafile client. This command start `ccnet` and `seaf-daemon`, `ccnet` is the network part of seafile client, `seaf-daemon` manages the files. seaf-cli start [-c ] stop ---- Stop seafile client. seaf-cli stop [-c ] Download by id -------- Download a library from seafile server (using library id) seaf-cli download -l -s -d -u -p Download by name -------- Download a library from seafile server (using library name) seaf-cli download -L -s -d -u -p sync ---- Synchronize a library with an existing folder. seaf-cli sync -l -s -d -u -p desync ------ Desynchronize a library from seafile server seaf-cli desync -d create ------ Create a new library seaf-cli create -s -n -u -p -t [-e ] ''' import argparse import os import json import subprocess import sys import time import getpass import urllib import urllib2 from urlparse import urlparse import ccnet import seafile if 'HOME' in os.environ: DEFAULT_CONF_DIR = "%s/.ccnet" % os.environ['HOME'] else: DEFAULT_CONF_DIR = None seafile_datadir = None seafile_worktree = None def _check_seafile(): ''' Check ccnet and seafile have been installed ''' dirs = os.environ['PATH'].split(':') def exist_in_path(prog): ''' Check whether 'prog' exists in system path ''' for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return True progs = [ 'ccnet', 'ccnet-init', 'seaf-daemon' ] for prog in progs: if not exist_in_path(prog): print "%s not found in PATH. Have you installed seafile?" % prog sys.exit(1) def _config_valid(conf): ''' Check config directory valid ''' if not os.path.exists(conf) or not os.path.isdir(conf): print "%s not exists" % conf return False config_conf = conf + "/ccnet.conf" seafile_ini = conf + "/seafile.ini" if not os.path.exists(config_conf): print "Could not load %s" % config_conf return False if not os.path.exists(seafile_ini): print "Could not load %s" % seafile_ini return False with open(seafile_ini) as f: for line in f: global seafile_datadir, seafile_worktree seafile_datadir = line.strip() seafile_worktree = os.path.join( os.path.dirname(seafile_datadir), "seafile") break if not seafile_datadir or not seafile_worktree: print "Could not load seafile_datadir and seafile_worktree" return False return True def _conf_dir(args): ''' Determine and return the value of conf_dir ''' conf_dir = DEFAULT_CONF_DIR if args.confdir: conf_dir = args.confdir conf_dir = os.path.abspath(conf_dir) if not _config_valid(conf_dir): print "Invalid config directory" sys.exit(1) else: return conf_dir def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def get_env(): env = dict(os.environ) ld_library_path = os.environ.get('SEAFILE_LD_LIBRARY_PATH', '') if ld_library_path: env['LD_LIBRARY_PATH'] = ld_library_path return env def urlopen(url, data=None, headers=None): if data: data = urllib.urlencode(data) headers = headers or {} req = urllib2.Request(url, data=data, headers=headers) resp = urllib2.urlopen(req) return resp.read() SEAF_CLI_VERSION = "" def get_peer_id(conf_dir): pool = ccnet.ClientPool(conf_dir) ccnet_rpc = ccnet.CcnetRpcClient(pool) info = ccnet_rpc.get_session_info() return info.id def get_token(url, username, password, conf_dir): platform = 'linux' device_id = get_peer_id(conf_dir) device_name = 'terminal-' + os.uname()[1] client_version = SEAF_CLI_VERSION platform_version = '' data = { 'username': username, 'password': password, 'platform': platform, 'device_id': device_id, 'device_name': device_name, 'client_version': client_version, 'platform_version': platform_version, } token_json = urlopen("%s/api2/auth-token/" % url, data=data) tmp = json.loads(token_json) token = tmp['token'] return token def get_repo_download_info(url, token): headers = { 'Authorization': 'Token %s' % token } repo_info = urlopen(url, headers=headers) return json.loads(repo_info) def seaf_init(args): ''' Initialize config directories''' ccnet_conf_dir = DEFAULT_CONF_DIR if args.confdir: ccnet_conf_dir = args.confdir if args.dir: seafile_path = args.dir else: print "Must specify the parent path for put seafile-data" sys.exit(0) seafile_path = os.path.abspath(seafile_path) if os.path.exists(ccnet_conf_dir): print "%s already exists" % ccnet_conf_dir sys.exit(0) cmd = [ "ccnet-init", "-c", ccnet_conf_dir, "-n", "anonymous" ] if run_argv(cmd, env=get_env()) != 0: print "Failed to init ccnet" sys.exit(1) if not os.path.exists(seafile_path): print "%s not exists" % seafile_path sys.exit(0) seafile_ini = ccnet_conf_dir + "/seafile.ini" seafile_data = seafile_path + "/seafile-data" fp = open(seafile_ini, 'w') fp.write(seafile_data) fp.close() print "Writen seafile data directory %s to %s" % (seafile_data, seafile_ini) def seaf_start_all(args): ''' Start ccnet and seafile daemon ''' seaf_start_ccnet(args) # wait ccnet process time.sleep(1) seaf_start_seafile(args) def seaf_start_ccnet(args): ''' Start ccnet daemon ''' conf_dir = _conf_dir(args) print "Starting ccnet daemon ..." cmd = [ "ccnet", "--daemon", "-c", conf_dir ] if run_argv(cmd, env=get_env()) != 0: print "CCNet daemon failed to start." sys.exit(1) print "Started: ccnet daemon ..." def seaf_start_seafile(args): ''' start seafile daemon ''' conf_dir = _conf_dir(args) print "Starting seafile daemon ..." cmd = [ "seaf-daemon", "--daemon", "-c", conf_dir, "-d", seafile_datadir, "-w", seafile_worktree ] if run_argv(cmd, env=get_env()) != 0: print 'Failed to start seafile daemon' sys.exit(1) print "Started: seafile daemon ..." def seaf_stop(args): '''Stop seafile daemon ''' conf_dir = _conf_dir(args) pool = ccnet.ClientPool(conf_dir) client = pool.get_client() try: client.send_cmd("shutdown") except: # ignore NetworkError("Failed to read from socket") pass def seaf_list(args): '''List local libraries''' conf_dir = _conf_dir(args) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) repos = seafile_rpc.get_repo_list(-1, -1) print "Name\tID\tPath" for repo in repos: print repo.name, repo.id, repo.worktree def seaf_list_remote(args): '''List remote libraries''' conf_dir = _conf_dir(args) url = args.server if not url: print "Seafile server url need to be presented" sys.exit(1) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) username = args.username if not username: username = raw_input("Enter username: ") password = args.password if not password: password = getpass.getpass("Enter password for user %s : " % username) # curl -d 'username=&password=' http://127.0.0.1:8000/api2/auth-token token = get_token(url, username, password, conf_dir) repos = get_repo_download_info("%s/api2/repos/" % (url), token) printed = {} print "Name\tID" for repo in repos: if repo['id'] in printed: continue printed[repo['id']] = repo['id'] print repo['name'], repo['id'] def get_base_url(url): parse_result = urlparse(url) scheme = parse_result.scheme netloc = parse_result.netloc if scheme and netloc: return '%s://%s' % (scheme, netloc) return None def seaf_download(args): '''Download a library from seafile server ''' conf_dir = _conf_dir(args) repo = args.library if not repo: print "Library id is required" sys.exit(1) url = args.server if not url: print "Seafile server url need to be presented" sys.exit(1) download_dir = seafile_worktree if args.dir: download_dir = os.path.abspath(args.dir) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) username = args.username if not username: username = raw_input("Enter username: ") password = args.password if not password: password = getpass.getpass("Enter password for user %s : " % username) # curl -d 'username=&password=' http://127.0.0.1:8000/api2/auth-token token = get_token(url, username, password, conf_dir) tmp = get_repo_download_info("%s/api2/repos/%s/download-info/" % (url, repo), token) encrypted = tmp['encrypted'] magic = tmp.get('magic', None) enc_version = tmp.get('enc_version', None) random_key = tmp.get('random_key', None) clone_token = tmp['token'] relay_id = tmp['relay_id'] relay_addr = tmp['relay_addr'] relay_port = str(tmp['relay_port']) email = tmp['email'] repo_name = tmp['repo_name'] version = tmp.get('repo_version', 0) more_info = None base_url = get_base_url(url) if base_url: more_info = json.dumps({'server_url': base_url}) print "Starting to download ..." print "Library %s will be downloaded to %s" % (repo, download_dir) if encrypted == 1: repo_passwd = args.libpasswd if args.libpasswd else getpass.getpass("Enter password for the library: ") else: repo_passwd = None seafile_rpc.download(repo, version, relay_id, repo_name.encode('utf-8'), download_dir.encode('utf-8'), clone_token, repo_passwd, magic, relay_addr, relay_port, email, random_key, enc_version, more_info) def seaf_download_by_name(args): '''Download a library defined by name from seafile server''' id = None conf_dir = _conf_dir(args) libraryname = args.libraryname if not libraryname: print "Library name is required" sys.exit(1) url = args.server if not url: print "Seafile server url need to be presented" sys.exit(1) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) username = args.username if not username: username = raw_input("Enter username: ") args.username = username password = args.password if not password: password = getpass.getpass("Enter password for user %s : " % username) args.password = password # curl -d 'username=&password=' http://127.0.0.1:8000/api2/auth-token token = get_token(url, username, password, conf_dir) tmp = get_repo_download_info("%s/api2/repos/" % (url), token) for i in tmp: if libraryname == i['name']: id = i['id'] if not id: print "Defined library name not found" sys.exit(1) args.library = id seaf_download(args) def seaf_sync(args): ''' synchronize a library from seafile server ''' conf_dir = _conf_dir(args) repo = args.library if not repo: print "Library id is required" sys.exit(1) url = args.server if not url: print "Seafile server url is required" sys.exit(1) folder = args.folder if not folder: print "The local directory is required" sys.exit(1) folder = os.path.abspath(folder) if not os.path.exists(folder): print "The local directory does not exists" sys.exit(1) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) username = args.username if not username: username = raw_input("Enter username: ") password = args.password if not password: password = getpass.getpass("Enter password for user %s : " % username) token = get_token(url, username, password, conf_dir) tmp = get_repo_download_info("%s/api2/repos/%s/download-info/" % (url, repo), token) encrypted = tmp['encrypted'] magic = tmp.get('magic', None) enc_version = tmp.get('enc_version', None) random_key = tmp.get('random_key', None) clone_token = tmp['token'] relay_id = tmp['relay_id'] relay_addr = tmp['relay_addr'] relay_port = str(tmp['relay_port']) email = tmp['email'] repo_name = tmp['repo_name'] version = tmp.get('repo_version', 0) more_info = None base_url = get_base_url(url) if base_url: more_info = json.dumps({'server_url': base_url}) print "Starting to download ..." if encrypted == 1: repo_passwd = args.libpasswd if args.libpasswd else getpass.getpass("Enter password for the library: ") else: repo_passwd = None seafile_rpc.clone(repo, version, relay_id, repo_name.encode('utf-8'), folder, clone_token, repo_passwd, magic, relay_addr, relay_port, email, random_key, enc_version, more_info) def seaf_desync(args): '''Desynchronize a library from seafile server''' conf_dir = _conf_dir(args) repo_path = args.folder if not repo_path: print "Must specify the local path of the library" sys.exit(1) repo_path = os.path.abspath(repo_path) pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) repos = seafile_rpc.get_repo_list(-1, -1) repo = None for r in repos: if r.worktree == repo_path.decode('utf-8'): repo = r break if repo: print "Desynchronize %s" % repo.name seafile_rpc.remove_repo(repo.id) else: print "%s is not a library" % args.folder def seaf_config(args): '''Configure the seafile client''' conf_dir = _conf_dir(args) config_key = args.key if not config_key: print "Must specify configuration key" sys.exit(1) config_value = args.value pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) if config_value: # set configuration key seafile_rpc.seafile_set_config(config_key, config_value) else: # print configuration key val = seafile_rpc.seafile_get_config(config_key) print "%s = %s" % (config_key, val) def seaf_status(args): '''Show status''' conf_dir = _conf_dir(args) pool = ccnet.ClientPool(conf_dir) ccnet_rpc = ccnet.CcnetRpcClient(pool, req_pool=False) seafile_rpc = seafile.RpcClient(pool, req_pool=False) tasks = seafile_rpc.get_clone_tasks() print "# Name\tStatus\tProgress" for task in tasks: if task.state == "fetch": tx_task = seafile_rpc.find_transfer_task(task.repo_id) print "%s\t%s\t%d/%d, %.1fKB/s" % (task.repo_name, "downloading", tx_task.block_done, tx_task.block_total, tx_task.rate/1024.0) elif task.state == "checkout": checkout_task = seafile_rpc.get_checkout_task(task.repo_id) print "%s\t%s\t%d/%d" % (task.repo_name, "checkout", checkout_task.finished_files, checkout_task.total_files) elif task.state == "error": tx_task = seafile_rpc.find_transfer_task(task.repo_id) if tx_task: err = tx_task.error_str else: err = task.error_str print "%s\t%s\t%s" % (task.repo_name, "error", err) elif task.state == 'done': # will be shown in repo status pass else: print "%s\t%s" % (task.repo_name, "unknown") # show repo status print "" print "# Name\tStatus" repos = seafile_rpc.get_repo_list(-1, -1) for repo in repos: auto_sync_enabled = seafile_rpc.is_auto_sync_enabled() if not auto_sync_enabled or not repo.auto_sync: print "%s\t%s" % (repo.name, "auto sync disabled") continue t = seafile_rpc.get_repo_sync_task(repo.id) if not t: print "%s\twaiting for sync" % repo.name elif t.state == "error": print "%s\t%s" % (repo.name, t.error) else: print "%s\t%s" % (repo.name, t.state) def create_repo(url, token, args): headers = { 'Authorization': 'Token %s' % token } data = { 'name': args.name, 'desc': args.desc, } if args.libpasswd: data['passwd'] = args.libpasswd repo_info_json = urlopen(url, data=data, headers=headers) repo_info = json.loads(repo_info_json) return repo_info['repo_id'] def seaf_create(args): '''Create a library''' conf_dir = DEFAULT_CONF_DIR if args.confdir: conf_dir = args.confdir conf_dir = os.path.abspath(conf_dir) # check username and password username = args.username if not username: username = raw_input("Enter username: ") password = args.password if not password: password = getpass.getpass("Enter password for user %s " % username) # check url url = args.server if not url: print "Seafile server url need to be presented" sys.exit(1) # curl -d 'username=&password=' http://127.0.0.1:8000/api2/auth-token token = get_token(url, username, password, conf_dir) repo_id = create_repo("%s/api2/repos/" % (url), token, args) print repo_id def main(): ''' Main entry ''' _check_seafile() parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title='subcommands', description='') confdir_required = DEFAULT_CONF_DIR is None # init parser_init = subparsers.add_parser('init', help='Initialize config directory') parser_init.set_defaults(func=seaf_init) parser_init.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_init.add_argument('-d', '--dir', help='the parent directory to put seafile-data', type=str) # start parser_start = subparsers.add_parser('start', help='Start ccnet and seafile daemon') parser_start.set_defaults(func=seaf_start_all) parser_start.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) # stop parser_stop = subparsers.add_parser('stop', help='Stop ccnet and seafile daemon') parser_stop.set_defaults(func=seaf_stop) parser_stop.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) # list parser_list = subparsers.add_parser('list', help='List local libraries') parser_list.set_defaults(func=seaf_list) parser_list.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) # list-remote parser_download = subparsers.add_parser('list-remote', help='List remote libraries') parser_download.set_defaults(func=seaf_list_remote) parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str) parser_download.add_argument('-u', '--username', help='username', type=str) parser_download.add_argument('-p', '--password', help='password', type=str) # status parser_status = subparsers.add_parser('status', help='Show syncing status') parser_status.set_defaults(func=seaf_status) parser_status.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) # download parser_download = subparsers.add_parser('download', help='Download a library from seafile server') parser_download.set_defaults(func=seaf_download) parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_download.add_argument('-l', '--library', help='library id', type=str) parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str) parser_download.add_argument('-d', '--dir', help='the directory to put the library', type=str) parser_download.add_argument('-u', '--username', help='username', type=str) parser_download.add_argument('-p', '--password', help='password', type=str) parser_download.add_argument('-e', '--libpasswd', help='library password', type=str) # download-by-name parser_download = subparsers.add_parser('download-by-name', help='Download a library defined by name from seafile server') parser_download.set_defaults(func=seaf_download_by_name) parser_download.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_download.add_argument('-L', '--libraryname', help='library name', type=str) parser_download.add_argument('-s', '--server', help='URL for seafile server', type=str) parser_download.add_argument('-d', '--dir', help='the directory to put the library', type=str) parser_download.add_argument('-u', '--username', help='username', type=str) parser_download.add_argument('-p', '--password', help='password', type=str) parser_download.add_argument('-e', '--libpasswd', help='library password', type=str) # sync parser_sync = subparsers.add_parser('sync', help='Sync a library with an existing foler') parser_sync.set_defaults(func=seaf_sync) parser_sync.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_sync.add_argument('-l', '--library', help='library id', type=str) parser_sync.add_argument('-s', '--server', help='URL for seafile server', type=str) parser_sync.add_argument('-u', '--username', help='username', type=str) parser_sync.add_argument('-p', '--password', help='password', type=str) parser_sync.add_argument('-d', '--folder', help='the existing local folder', type=str) parser_sync.add_argument('-e', '--libpasswd', help='library password', type=str) # desync parser_desync = subparsers.add_parser('desync', help='Desync a library with seafile server') parser_desync.set_defaults(func=seaf_desync) parser_desync.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_desync.add_argument('-d', '--folder', help='the local folder', type=str) # create parser_create = subparsers.add_parser('create', help='Create a library') parser_create.set_defaults(func=seaf_create) parser_create.add_argument('-n', '--name', help='library name', type=str) parser_create.add_argument('-t', '--desc', help='library description', type=str) parser_create.add_argument('-e', '--libpasswd', help='library password', type=str) parser_create.add_argument('-s', '--server', help='URL for seafile server', type=str) parser_create.add_argument('-u', '--username', help='username', type=str) parser_create.add_argument('-p', '--password', help='password', type=str) parser_create.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) # config parser_config = subparsers.add_parser('config', help='Configure seafile client') parser_config.set_defaults(func=seaf_config) parser_config.add_argument('-c', '--confdir', help='the config directory', type=str, required=confdir_required) parser_config.add_argument('-k', '--key', help='configuration key', type=str) parser_config.add_argument('-v', '--value', help='configuration value (if provided, key is set to this value)', type=str, required=False) if len(sys.argv) == 1: print parser.format_help() return args = parser.parse_args() args.func(args) if __name__ == '__main__': main() seafile-6.1.5/autogen.sh000077500000000000000000000065241323477647300151630ustar00rootroot00000000000000#!/bin/bash # Run this to generate all the initial makefiles, etc. : ${AUTOCONF=autoconf} : ${AUTOHEADER=autoheader} : ${AUTOMAKE=automake} : ${ACLOCAL=aclocal} if test "$(uname)" != "Darwin"; then : ${LIBTOOLIZE=libtoolize} else : ${LIBTOOLIZE=glibtoolize} fi : ${INTLTOOLIZE=intltoolize} : ${LIBTOOL=libtool} srcdir=`dirname $0` test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir PROJECT=ccnet TEST_TYPE=-f FILE=net/main.c CONFIGURE=configure.ac DIE=0 ($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || { echo echo "You must have autoconf installed to compile $PROJECT." echo "Download the appropriate package for your distribution," echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" DIE=1 } (grep "^AC_PROG_INTLTOOL" $srcdir/$CONFIGURE >/dev/null) && { ($INTLTOOLIZE --version) < /dev/null > /dev/null 2>&1 || { echo echo "You must have \`intltoolize' installed to compile $PROJECT." echo "Get ftp://ftp.gnome.org/pub/GNOME/stable/sources/intltool/intltool-0.22.tar.gz" echo "(or a newer version if it is available)" DIE=1 } } ($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || { echo echo "You must have automake installed to compile $PROJECT." echo "Get ftp://sourceware.cygnus.com/pub/automake/automake-1.7.tar.gz" echo "(or a newer version if it is available)" DIE=1 } if test "$(uname)" != "Darwin"; then (grep "^AC_PROG_LIBTOOL" $CONFIGURE >/dev/null) && { ($LIBTOOL --version) < /dev/null > /dev/null 2>&1 || { echo echo "**Error**: You must have \`libtool' installed to compile $PROJECT." echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.4.tar.gz" echo "(or a newer version if it is available)" DIE=1 } } fi if grep "^AM_[A-Z0-9_]\{1,\}_GETTEXT" "$CONFIGURE" >/dev/null; then if grep "sed.*POTFILES" "$CONFIGURE" >/dev/null; then GETTEXTIZE="" else if grep "^AM_GLIB_GNU_GETTEXT" "$CONFIGURE" >/dev/null; then GETTEXTIZE="glib-gettextize" GETTEXTIZE_URL="ftp://ftp.gtk.org/pub/gtk/v2.0/glib-2.0.0.tar.gz" else GETTEXTIZE="gettextize" GETTEXTIZE_URL="ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz" fi $GETTEXTIZE --version < /dev/null > /dev/null 2>&1 if test $? -ne 0; then echo echo "**Error**: You must have \`$GETTEXTIZE' installed to compile $PKG_NAME." echo "Get $GETTEXTIZE_URL" echo "(or a newer version if it is available)" DIE=1 fi fi fi if test "$DIE" -eq 1; then exit 1 fi dr=`dirname .` echo processing $dr aclocalinclude="$aclocalinclude -I m4" if test x"$MSYSTEM" = x"MINGW32"; then aclocalinclude="$aclocalinclude -I /mingw32/share/aclocal" elif test "$(uname)" = "Darwin"; then aclocalinclude="$aclocalinclude -I /opt/local/share/aclocal" fi echo "Creating $dr/aclocal.m4 ..." test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 echo "Running glib-gettextize... Ignore non-fatal messages." echo "no" | glib-gettextize --force --copy echo "Making $dr/aclocal.m4 writable ..." test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 echo "Running intltoolize..." intltoolize --copy --force --automake echo "Running $LIBTOOLIZE..." $LIBTOOLIZE --force --copy echo "Running $ACLOCAL $aclocalinclude ..." $ACLOCAL $aclocalinclude echo "Running $AUTOHEADER..." $AUTOHEADER echo "Running $AUTOMAKE --gnu $am_opt ..." $AUTOMAKE --add-missing --gnu $am_opt echo "Running $AUTOCONF ..." $AUTOCONF seafile-6.1.5/common/000077500000000000000000000000001323477647300144435ustar00rootroot00000000000000seafile-6.1.5/common/Makefile.am000066400000000000000000000007141323477647300165010ustar00rootroot00000000000000SUBDIRS = cdc index proc_headers = $(addprefix processors/, \ objecttx-common.h) noinst_HEADERS = \ unpack-trees.h \ seaf-tree-walk.h \ diff-simple.h \ seafile-crypt.h \ common.h \ branch-mgr.h \ fs-mgr.h \ block-mgr.h \ commit-mgr.h \ log.h \ object-list.h \ vc-common.h \ seaf-utils.h \ obj-store.h \ obj-backend.h \ block-backend.h \ block.h \ mq-mgr.h \ seaf-db.h \ merge-new.h \ block-tx-utils.h \ curl-init.h \ $(proc_headers) seafile-6.1.5/common/block-backend-fs.c000066400000000000000000000322501323477647300176760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #include "common.h" #include "utils.h" #include "log.h" #include #include #include #include "block-backend.h" #include "obj-store.h" struct _BHandle { char *store_id; int version; char block_id[41]; int fd; int rw_type; char *tmp_file; }; typedef struct { char *v0_block_dir; int v0_block_dir_len; char *block_dir; int block_dir_len; char *tmp_dir; int tmp_dir_len; } FsPriv; static char * get_block_path (BlockBackend *bend, const char *block_sha1, char path[], const char *store_id, int version); static int open_tmp_file (BlockBackend *bend, const char *basename, char **path); static BHandle * block_backend_fs_open_block (BlockBackend *bend, const char *store_id, int version, const char *block_id, int rw_type) { BHandle *handle; int fd = -1; char *tmp_file; g_return_val_if_fail (block_id != NULL, NULL); g_return_val_if_fail (strlen(block_id) == 40, NULL); g_return_val_if_fail (rw_type == BLOCK_READ || rw_type == BLOCK_WRITE, NULL); if (rw_type == BLOCK_READ) { char path[SEAF_PATH_MAX]; get_block_path (bend, block_id, path, store_id, version); fd = g_open (path, O_RDONLY | O_BINARY, 0); if (fd < 0) { ccnet_warning ("[block bend] failed to open block %s for read: %s\n", block_id, strerror(errno)); return NULL; } } else { fd = open_tmp_file (bend, block_id, &tmp_file); if (fd < 0) { ccnet_warning ("[block bend] failed to open block %s for write: %s\n", block_id, strerror(errno)); return NULL; } } handle = g_new0(BHandle, 1); handle->fd = fd; memcpy (handle->block_id, block_id, 41); handle->rw_type = rw_type; if (rw_type == BLOCK_WRITE) handle->tmp_file = tmp_file; if (store_id) handle->store_id = g_strdup(store_id); handle->version = version; return handle; } static int block_backend_fs_read_block (BlockBackend *bend, BHandle *handle, void *buf, int len) { return (readn (handle->fd, buf, len)); } static int block_backend_fs_write_block (BlockBackend *bend, BHandle *handle, const void *buf, int len) { return (writen (handle->fd, buf, len)); } static int block_backend_fs_close_block (BlockBackend *bend, BHandle *handle) { int ret; ret = close (handle->fd); return ret; } static void block_backend_fs_block_handle_free (BlockBackend *bend, BHandle *handle) { if (handle->rw_type == BLOCK_WRITE) { /* make sure the tmp file is removed even on failure. */ g_unlink (handle->tmp_file); g_free (handle->tmp_file); } g_free (handle->store_id); g_free (handle); } static int create_parent_path (const char *path) { char *dir = g_path_get_dirname (path); if (!dir) return -1; if (g_file_test (dir, G_FILE_TEST_EXISTS)) { g_free (dir); return 0; } if (g_mkdir_with_parents (dir, 0777) < 0) { seaf_warning ("Failed to create object parent path: %s.\n", dir); g_free (dir); return -1; } g_free (dir); return 0; } static int block_backend_fs_commit_block (BlockBackend *bend, BHandle *handle) { char path[SEAF_PATH_MAX]; g_return_val_if_fail (handle->rw_type == BLOCK_WRITE, -1); get_block_path (bend, handle->block_id, path, handle->store_id, handle->version); if (create_parent_path (path) < 0) { seaf_warning ("Failed to create path for block %s:%s.\n", handle->store_id, handle->block_id); return -1; } if (g_rename (handle->tmp_file, path) < 0) { seaf_warning ("[block bend] failed to commit block %s:%s: %s\n", handle->store_id, handle->block_id, strerror(errno)); return -1; } return 0; } static gboolean block_backend_fs_block_exists (BlockBackend *bend, const char *store_id, int version, const char *block_sha1) { char block_path[SEAF_PATH_MAX]; get_block_path (bend, block_sha1, block_path, store_id, version); if (g_access (block_path, F_OK) == 0) return TRUE; else return FALSE; } static int block_backend_fs_remove_block (BlockBackend *bend, const char *store_id, int version, const char *block_id) { char path[SEAF_PATH_MAX]; get_block_path (bend, block_id, path, store_id, version); return g_unlink (path); } static BMetadata * block_backend_fs_stat_block (BlockBackend *bend, const char *store_id, int version, const char *block_id) { char path[SEAF_PATH_MAX]; SeafStat st; BMetadata *block_md; get_block_path (bend, block_id, path, store_id, version); if (seaf_stat (path, &st) < 0) { seaf_warning ("[block bend] Failed to stat block %s:%s at %s: %s.\n", store_id, block_id, path, strerror(errno)); return NULL; } block_md = g_new0(BMetadata, 1); memcpy (block_md->id, block_id, 40); block_md->size = (uint32_t) st.st_size; return block_md; } static BMetadata * block_backend_fs_stat_block_by_handle (BlockBackend *bend, BHandle *handle) { SeafStat st; BMetadata *block_md; if (seaf_fstat (handle->fd, &st) < 0) { seaf_warning ("[block bend] Failed to stat block %s:%s.\n", handle->store_id, handle->block_id); return NULL; } block_md = g_new0(BMetadata, 1); memcpy (block_md->id, handle->block_id, 40); block_md->size = (uint32_t) st.st_size; return block_md; } static int block_backend_fs_foreach_block (BlockBackend *bend, const char *store_id, int version, SeafBlockFunc process, void *user_data) { FsPriv *priv = bend->be_priv; char *block_dir = NULL; int dir_len; GDir *dir1 = NULL, *dir2; const char *dname1, *dname2; char block_id[128]; char path[SEAF_PATH_MAX], *pos; int ret = 0; #if defined MIGRATION if (version > 0) block_dir = g_build_filename (priv->block_dir, store_id, NULL); else block_dir = g_strdup(priv->v0_block_dir); #else block_dir = g_build_filename (priv->block_dir, store_id, NULL); #endif dir_len = strlen (block_dir); dir1 = g_dir_open (block_dir, 0, NULL); if (!dir1) { goto out; } memcpy (path, block_dir, dir_len); pos = path + dir_len; while ((dname1 = g_dir_read_name(dir1)) != NULL) { snprintf (pos, sizeof(path) - dir_len, "/%s", dname1); dir2 = g_dir_open (path, 0, NULL); if (!dir2) { seaf_warning ("Failed to open block dir %s.\n", path); continue; } while ((dname2 = g_dir_read_name(dir2)) != NULL) { snprintf (block_id, sizeof(block_id), "%s%s", dname1, dname2); if (!process (store_id, version, block_id, user_data)) { g_dir_close (dir2); goto out; } } g_dir_close (dir2); } out: if (dir1) g_dir_close (dir1); g_free (block_dir); return ret; } static int block_backend_fs_copy (BlockBackend *bend, const char *src_store_id, int src_version, const char *dst_store_id, int dst_version, const char *block_id) { char src_path[SEAF_PATH_MAX]; char dst_path[SEAF_PATH_MAX]; get_block_path (bend, block_id, src_path, src_store_id, src_version); get_block_path (bend, block_id, dst_path, dst_store_id, dst_version); if (g_file_test (dst_path, G_FILE_TEST_EXISTS)) return 0; if (create_parent_path (dst_path) < 0) { seaf_warning ("Failed to create dst path %s for block %s.\n", dst_path, block_id); return -1; } #ifdef WIN32 if (!CreateHardLink (dst_path, src_path, NULL)) { seaf_warning ("Failed to link %s to %s: %lu.\n", src_path, dst_path, GetLastError()); return -1; } return 0; #else int ret = link (src_path, dst_path); if (ret < 0 && errno != EEXIST) { seaf_warning ("Failed to link %s to %s: %s.\n", src_path, dst_path, strerror(errno)); return -1; } return ret; #endif } static int block_backend_fs_remove_store (BlockBackend *bend, const char *store_id) { FsPriv *priv = bend->be_priv; char *block_dir = NULL; GDir *dir1, *dir2; const char *dname1, *dname2; char *path1, *path2; block_dir = g_build_filename (priv->block_dir, store_id, NULL); dir1 = g_dir_open (block_dir, 0, NULL); if (!dir1) { g_free (block_dir); return 0; } while ((dname1 = g_dir_read_name(dir1)) != NULL) { path1 = g_build_filename (block_dir, dname1, NULL); dir2 = g_dir_open (path1, 0, NULL); if (!dir2) { seaf_warning ("Failed to open block dir %s.\n", path1); g_dir_close (dir1); g_free (path1); g_free (block_dir); return -1; } while ((dname2 = g_dir_read_name(dir2)) != NULL) { path2 = g_build_filename (path1, dname2, NULL); g_unlink (path2); g_free (path2); } g_dir_close (dir2); g_rmdir (path1); g_free (path1); } g_dir_close (dir1); g_rmdir (block_dir); g_free (block_dir); return 0; } static char * get_block_path (BlockBackend *bend, const char *block_sha1, char path[], const char *store_id, int version) { FsPriv *priv = bend->be_priv; char *pos = path; int n; #if defined MIGRATION if (version > 0) { n = snprintf (path, SEAF_PATH_MAX, "%s/%s/", priv->block_dir, store_id); pos += n; } else { memcpy (pos, priv->v0_block_dir, priv->v0_block_dir_len); pos[priv->v0_block_dir_len] = '/'; pos += priv->v0_block_dir_len + 1; } #else n = snprintf (path, SEAF_PATH_MAX, "%s/%s/", priv->block_dir, store_id); pos += n; #endif memcpy (pos, block_sha1, 2); pos[2] = '/'; pos += 3; memcpy (pos, block_sha1 + 2, 41 - 2); return path; } static int open_tmp_file (BlockBackend *bend, const char *basename, char **path) { FsPriv *priv = bend->be_priv; int fd; *path = g_strdup_printf ("%s/%s.XXXXXX", priv->tmp_dir, basename); fd = g_mkstemp (*path); if (fd < 0) g_free (*path); return fd; } BlockBackend * block_backend_fs_new (const char *seaf_dir, const char *tmp_dir) { BlockBackend *bend; FsPriv *priv; bend = g_new0(BlockBackend, 1); priv = g_new0(FsPriv, 1); bend->be_priv = priv; priv->v0_block_dir = g_build_filename (seaf_dir, "blocks", NULL); priv->v0_block_dir_len = strlen(priv->v0_block_dir); priv->block_dir = g_build_filename (seaf_dir, "storage", "blocks", NULL); priv->block_dir_len = strlen (priv->block_dir); priv->tmp_dir = g_strdup (tmp_dir); priv->tmp_dir_len = strlen (tmp_dir); if (g_mkdir_with_parents (priv->block_dir, 0777) < 0) { seaf_warning ("Block dir %s does not exist and" " is unable to create\n", priv->block_dir); goto onerror; } if (g_mkdir_with_parents (tmp_dir, 0777) < 0) { seaf_warning ("Blocks tmp dir %s does not exist and" " is unable to create\n", tmp_dir); goto onerror; } bend->open_block = block_backend_fs_open_block; bend->read_block = block_backend_fs_read_block; bend->write_block = block_backend_fs_write_block; bend->commit_block = block_backend_fs_commit_block; bend->close_block = block_backend_fs_close_block; bend->exists = block_backend_fs_block_exists; bend->remove_block = block_backend_fs_remove_block; bend->stat_block = block_backend_fs_stat_block; bend->stat_block_by_handle = block_backend_fs_stat_block_by_handle; bend->block_handle_free = block_backend_fs_block_handle_free; bend->foreach_block = block_backend_fs_foreach_block; bend->remove_store = block_backend_fs_remove_store; bend->copy = block_backend_fs_copy; return bend; onerror: g_free (bend); g_free (bend->be_priv); return NULL; } seafile-6.1.5/common/block-backend.c000066400000000000000000000023141323477647300172660ustar00rootroot00000000000000 #include "common.h" #include "log.h" #include "block-backend.h" extern BlockBackend * block_backend_fs_new (const char *block_dir, const char *tmp_dir); BlockBackend* load_filesystem_block_backend(GKeyFile *config) { BlockBackend *bend; char *tmp_dir; char *block_dir; block_dir = g_key_file_get_string (config, "block_backend", "block_dir", NULL); if (!block_dir) { seaf_warning ("Block dir not set in config.\n"); return NULL; } tmp_dir = g_key_file_get_string (config, "block_backend", "tmp_dir", NULL); if (!tmp_dir) { seaf_warning ("Block tmp dir not set in config.\n"); return NULL; } bend = block_backend_fs_new (block_dir, tmp_dir); g_free (block_dir); g_free (tmp_dir); return bend; } BlockBackend* load_block_backend (GKeyFile *config) { char *backend; BlockBackend *bend; backend = g_key_file_get_string (config, "block_backend", "name", NULL); if (!backend) { return NULL; } if (strcmp(backend, "filesystem") == 0) { bend = load_filesystem_block_backend(config); g_free (backend); return bend; } seaf_warning ("Unknown backend\n"); return NULL; } seafile-6.1.5/common/block-backend.h000066400000000000000000000042321323477647300172740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef BLOCK_BACKEND_H #define BLOCK_BACKEND_H #include "block.h" typedef struct BlockBackend BlockBackend; struct BlockBackend { BHandle* (*open_block) (BlockBackend *bend, const char *store_id, int version, const char *block_id, int rw_type); int (*read_block) (BlockBackend *bend, BHandle *handle, void *buf, int len); int (*write_block) (BlockBackend *bend, BHandle *handle, const void *buf, int len); int (*commit_block) (BlockBackend *bend, BHandle *handle); int (*close_block) (BlockBackend *bend, BHandle *handle); int (*exists) (BlockBackend *bend, const char *store_id, int version, const char *block_id); int (*remove_block) (BlockBackend *bend, const char *store_id, int version, const char *block_id); BMetadata* (*stat_block) (BlockBackend *bend, const char *store_id, int version, const char *block_id); BMetadata* (*stat_block_by_handle) (BlockBackend *bend, BHandle *handle); void (*block_handle_free) (BlockBackend *bend, BHandle *handle); int (*foreach_block) (BlockBackend *bend, const char *store_id, int version, SeafBlockFunc process, void *user_data); int (*copy) (BlockBackend *bend, const char *src_store_id, int src_version, const char *dst_store_id, int dst_version, const char *block_id); /* Only valid for version 1 repo. Remove all blocks for the repo. */ int (*remove_store) (BlockBackend *bend, const char *store_id); void* be_priv; /* backend private field */ }; BlockBackend* load_block_backend (GKeyFile *config); #endif seafile-6.1.5/common/block-mgr.c000066400000000000000000000164741323477647300165000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "seafile-session.h" #include "utils.h" #include "seaf-utils.h" #include "block-mgr.h" #include "log.h" #include #include #include #include #include #include #include #include #include "block-backend.h" #define SEAF_BLOCK_DIR "blocks" extern BlockBackend * block_backend_fs_new (const char *block_dir, const char *tmp_dir); SeafBlockManager * seaf_block_manager_new (struct _SeafileSession *seaf, const char *seaf_dir) { SeafBlockManager *mgr; mgr = g_new0 (SeafBlockManager, 1); mgr->seaf = seaf; mgr->backend = block_backend_fs_new (seaf_dir, seaf->tmp_file_dir); if (!mgr->backend) { seaf_warning ("[Block mgr] Failed to load backend.\n"); goto onerror; } return mgr; onerror: g_free (mgr); return NULL; } int seaf_block_manager_init (SeafBlockManager *mgr) { return 0; } BlockHandle * seaf_block_manager_open_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id, int rw_type) { if (!store_id || !is_uuid_valid(store_id) || !block_id || !is_object_id_valid(block_id)) return NULL; return mgr->backend->open_block (mgr->backend, store_id, version, block_id, rw_type); } int seaf_block_manager_read_block (SeafBlockManager *mgr, BlockHandle *handle, void *buf, int len) { return mgr->backend->read_block (mgr->backend, handle, buf, len); } int seaf_block_manager_write_block (SeafBlockManager *mgr, BlockHandle *handle, const void *buf, int len) { return mgr->backend->write_block (mgr->backend, handle, buf, len); } int seaf_block_manager_close_block (SeafBlockManager *mgr, BlockHandle *handle) { return mgr->backend->close_block (mgr->backend, handle); } void seaf_block_manager_block_handle_free (SeafBlockManager *mgr, BlockHandle *handle) { return mgr->backend->block_handle_free (mgr->backend, handle); } int seaf_block_manager_commit_block (SeafBlockManager *mgr, BlockHandle *handle) { return mgr->backend->commit_block (mgr->backend, handle); } gboolean seaf_block_manager_block_exists (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id) { if (!store_id || !is_uuid_valid(store_id) || !block_id || !is_object_id_valid(block_id)) return FALSE; return mgr->backend->exists (mgr->backend, store_id, version, block_id); } int seaf_block_manager_remove_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id) { if (!store_id || !is_uuid_valid(store_id) || !block_id || !is_object_id_valid(block_id)) return -1; return mgr->backend->remove_block (mgr->backend, store_id, version, block_id); } BlockMetadata * seaf_block_manager_stat_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id) { if (!store_id || !is_uuid_valid(store_id) || !block_id || !is_object_id_valid(block_id)) return NULL; return mgr->backend->stat_block (mgr->backend, store_id, version, block_id); } BlockMetadata * seaf_block_manager_stat_block_by_handle (SeafBlockManager *mgr, BlockHandle *handle) { return mgr->backend->stat_block_by_handle (mgr->backend, handle); } int seaf_block_manager_foreach_block (SeafBlockManager *mgr, const char *store_id, int version, SeafBlockFunc process, void *user_data) { return mgr->backend->foreach_block (mgr->backend, store_id, version, process, user_data); } int seaf_block_manager_copy_block (SeafBlockManager *mgr, const char *src_store_id, int src_version, const char *dst_store_id, int dst_version, const char *block_id) { if (strcmp (block_id, EMPTY_SHA1) == 0) return 0; return mgr->backend->copy (mgr->backend, src_store_id, src_version, dst_store_id, dst_version, block_id); } static gboolean get_block_number (const char *store_id, int version, const char *block_id, void *data) { guint64 *n_blocks = data; ++(*n_blocks); return TRUE; } guint64 seaf_block_manager_get_block_number (SeafBlockManager *mgr, const char *store_id, int version) { guint64 n_blocks = 0; seaf_block_manager_foreach_block (mgr, store_id, version, get_block_number, &n_blocks); return n_blocks; } gboolean seaf_block_manager_verify_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id, gboolean *io_error) { BlockHandle *h; char buf[10240]; int n; GChecksum *cs; const char *check_id; gboolean ret; h = seaf_block_manager_open_block (mgr, store_id, version, block_id, BLOCK_READ); if (!h) { seaf_warning ("Failed to open block %s:%.8s.\n", store_id, block_id); *io_error = TRUE; return FALSE; } cs = g_checksum_new (G_CHECKSUM_SHA1); while (1) { n = seaf_block_manager_read_block (mgr, h, buf, sizeof(buf)); if (n < 0) { seaf_warning ("Failed to read block %s:%.8s.\n", store_id, block_id); *io_error = TRUE; g_checksum_free (cs); return FALSE; } if (n == 0) break; g_checksum_update (cs, (guchar *)buf, n); } seaf_block_manager_close_block (mgr, h); seaf_block_manager_block_handle_free (mgr, h); check_id = g_checksum_get_string (cs); if (strcmp (check_id, block_id) == 0) ret = TRUE; else ret = FALSE; g_checksum_free (cs); return ret; } int seaf_block_manager_remove_store (SeafBlockManager *mgr, const char *store_id) { return mgr->backend->remove_store (mgr->backend, store_id); } seafile-6.1.5/common/block-mgr.h000066400000000000000000000107631323477647300165000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_BLOCK_MGR_H #define SEAF_BLOCK_MGR_H #include #include #include #include "block.h" struct _SeafileSession; typedef struct _SeafBlockManager SeafBlockManager; struct _SeafBlockManager { struct _SeafileSession *seaf; struct BlockBackend *backend; }; SeafBlockManager * seaf_block_manager_new (struct _SeafileSession *seaf, const char *seaf_dir); /* * Open a block for read or write. * * @store_id: id for the block store * @version: data format version for the repo * @block_id: ID of block. * @rw_type: BLOCK_READ or BLOCK_WRITE. * Returns: A handle for the block. */ BlockHandle * seaf_block_manager_open_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id, int rw_type); /* * Read data from a block. * The semantics is similar to readn. * * @handle: Hanlde returned by seaf_block_manager_open_block(). * @buf: Data wuold be copied into this buf. * @len: At most @len bytes would be read. * * Returns: the bytes read. */ int seaf_block_manager_read_block (SeafBlockManager *mgr, BlockHandle *handle, void *buf, int len); /* * Write data to a block. * The semantics is similar to writen. * * @handle: Hanlde returned by seaf_block_manager_open_block(). * @buf: Data to be written to the block. * @len: At most @len bytes would be written. * * Returns: the bytes written. */ int seaf_block_manager_write_block (SeafBlockManager *mgr, BlockHandle *handle, const void *buf, int len); /* * Commit a block to storage. * The block must be opened for write. * * @handle: Hanlde returned by seaf_block_manager_open_block(). * * Returns: 0 on success, -1 on error. */ int seaf_block_manager_commit_block (SeafBlockManager *mgr, BlockHandle *handle); /* * Close an open block. * * @handle: Hanlde returned by seaf_block_manager_open_block(). * * Returns: 0 on success, -1 on error. */ int seaf_block_manager_close_block (SeafBlockManager *mgr, BlockHandle *handle); void seaf_block_manager_block_handle_free (SeafBlockManager *mgr, BlockHandle *handle); gboolean seaf_block_manager_block_exists (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id); int seaf_block_manager_remove_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id); BlockMetadata * seaf_block_manager_stat_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id); BlockMetadata * seaf_block_manager_stat_block_by_handle (SeafBlockManager *mgr, BlockHandle *handle); int seaf_block_manager_foreach_block (SeafBlockManager *mgr, const char *store_id, int version, SeafBlockFunc process, void *user_data); int seaf_block_manager_copy_block (SeafBlockManager *mgr, const char *src_store_id, int src_version, const char *dst_store_id, int dst_version, const char *block_id); /* Remove all blocks for a repo. Only valid for version 1 repo. */ int seaf_block_manager_remove_store (SeafBlockManager *mgr, const char *store_id); guint64 seaf_block_manager_get_block_number (SeafBlockManager *mgr, const char *store_id, int version); gboolean seaf_block_manager_verify_block (SeafBlockManager *mgr, const char *store_id, int version, const char *block_id, gboolean *io_error); #endif seafile-6.1.5/common/block-tx-utils.c000066400000000000000000000201421323477647300174670ustar00rootroot00000000000000#include "common.h" #ifndef USE_GPL_CRYPTO #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include "utils.h" #include "block-tx-utils.h" /* Utility functions for block transfer protocol. */ /* Encryption related functions. */ void blocktx_generate_encrypt_key (unsigned char *session_key, int sk_len, unsigned char *key, unsigned char *iv) { EVP_BytesToKey (EVP_aes_256_cbc(), /* cipher mode */ EVP_sha1(), /* message digest */ NULL, /* salt */ session_key, sk_len, 3, /* iteration times */ key, /* the derived key */ iv); /* IV, initial vector */ } int blocktx_encrypt_init (EVP_CIPHER_CTX **ctx, const unsigned char *key, const unsigned char *iv) { int ret; /* Prepare CTX for encryption. */ *ctx = EVP_CIPHER_CTX_new (); ret = EVP_EncryptInit_ex (*ctx, EVP_aes_256_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ key, /* derived key */ iv); /* initial vector */ if (ret == 0) { EVP_CIPHER_CTX_free (*ctx); return -1; } return 0; } int blocktx_decrypt_init (EVP_CIPHER_CTX **ctx, const unsigned char *key, const unsigned char *iv) { int ret; /* Prepare CTX for decryption. */ *ctx = EVP_CIPHER_CTX_new (); ret = EVP_DecryptInit_ex (*ctx, EVP_aes_256_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ key, /* derived key */ iv); /* initial vector */ if (ret == 0) { EVP_CIPHER_CTX_free (*ctx); return -1; } return 0; } /* Sending frame */ int send_encrypted_data_frame_begin (evutil_socket_t data_fd, int frame_len) { /* Compute data size after encryption. * Block size is 16 bytes and AES always add one padding block. */ int enc_frame_len; enc_frame_len = ((frame_len >> 4) + 1) << 4; enc_frame_len = htonl (enc_frame_len); if (sendn (data_fd, &enc_frame_len, sizeof(int)) < 0) { seaf_warning ("Failed to send frame length: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); return -1; } return 0; } int send_encrypted_data (EVP_CIPHER_CTX *ctx, evutil_socket_t data_fd, const void *buf, int len) { char out_buf[len + ENC_BLOCK_SIZE]; int out_len; if (EVP_EncryptUpdate (ctx, (unsigned char *)out_buf, &out_len, (unsigned char *)buf, len) == 0) { seaf_warning ("Failed to encrypt data.\n"); return -1; } if (sendn (data_fd, out_buf, out_len) < 0) { seaf_warning ("Failed to write data: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); return -1; } return 0; } int send_encrypted_data_frame_end (EVP_CIPHER_CTX *ctx, evutil_socket_t data_fd) { char out_buf[ENC_BLOCK_SIZE]; int out_len; if (EVP_EncryptFinal_ex (ctx, (unsigned char *)out_buf, &out_len) == 0) { seaf_warning ("Failed to encrypt data.\n"); return -1; } if (sendn (data_fd, out_buf, out_len) < 0) { seaf_warning ("Failed to write data: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); return -1; } return 0; } /* Receiving frame */ static int handle_frame_content (struct evbuffer *buf, FrameParser *parser) { char *frame; EVP_CIPHER_CTX *ctx; char *out; int outlen, outlen2; int ret = 0; struct evbuffer *input = buf; if (evbuffer_get_length (input) < parser->enc_frame_len) return 0; if (parser->version == 1) blocktx_decrypt_init (&ctx, parser->key, parser->iv); else if (parser->version == 2) blocktx_decrypt_init (&ctx, parser->key_v2, parser->iv_v2); frame = g_malloc (parser->enc_frame_len); out = g_malloc (parser->enc_frame_len + ENC_BLOCK_SIZE); evbuffer_remove (input, frame, parser->enc_frame_len); if (EVP_DecryptUpdate (ctx, (unsigned char *)out, &outlen, (unsigned char *)frame, parser->enc_frame_len) == 0) { seaf_warning ("Failed to decrypt frame content.\n"); ret = -1; goto out; } if (EVP_DecryptFinal_ex (ctx, (unsigned char *)(out + outlen), &outlen2) == 0) { seaf_warning ("Failed to decrypt frame content.\n"); ret = -1; goto out; } ret = parser->content_cb (out, outlen + outlen2, parser->cbarg); out: g_free (frame); g_free (out); parser->enc_frame_len = 0; EVP_CIPHER_CTX_free (ctx); return ret; } int handle_one_frame (struct evbuffer *buf, FrameParser *parser) { struct evbuffer *input = buf; if (!parser->enc_frame_len) { /* Read the length of the encrypted frame first. */ if (evbuffer_get_length (input) < sizeof(int)) return 0; int frame_len; evbuffer_remove (input, &frame_len, sizeof(int)); parser->enc_frame_len = ntohl (frame_len); if (evbuffer_get_length (input) > 0) return handle_frame_content (buf, parser); return 0; } else { return handle_frame_content (buf, parser); } } static int handle_frame_fragment_content (struct evbuffer *buf, FrameParser *parser) { char *fragment = NULL, *out = NULL; int fragment_len, outlen; int ret = 0; struct evbuffer *input = buf; fragment_len = evbuffer_get_length (input); fragment = g_malloc (fragment_len); evbuffer_remove (input, fragment, fragment_len); out = g_malloc (fragment_len + ENC_BLOCK_SIZE); if (EVP_DecryptUpdate (parser->ctx, (unsigned char *)out, &outlen, (unsigned char *)fragment, fragment_len) == 0) { seaf_warning ("Failed to decrypt frame fragment.\n"); ret = -1; goto out; } ret = parser->fragment_cb (out, outlen, 0, parser->cbarg); if (ret < 0) goto out; parser->remain -= fragment_len; if (parser->remain <= 0) { if (EVP_DecryptFinal_ex (parser->ctx, (unsigned char *)out, &outlen) == 0) { seaf_warning ("Failed to decrypt frame fragment.\n"); ret = -1; goto out; } ret = parser->fragment_cb (out, outlen, 1, parser->cbarg); if (ret < 0) goto out; EVP_CIPHER_CTX_free (parser->ctx); parser->enc_init = FALSE; parser->enc_frame_len = 0; } out: g_free (fragment); g_free (out); if (ret < 0) { EVP_CIPHER_CTX_free (parser->ctx); parser->enc_init = FALSE; parser->enc_frame_len = 0; } return ret; } int handle_frame_fragments (struct evbuffer *buf, FrameParser *parser) { struct evbuffer *input = buf; if (!parser->enc_frame_len) { /* Read the length of the encrypted frame first. */ if (evbuffer_get_length (input) < sizeof(int)) return 0; int frame_len; evbuffer_remove (input, &frame_len, sizeof(int)); parser->enc_frame_len = ntohl (frame_len); parser->remain = parser->enc_frame_len; if (parser->version == 1) blocktx_decrypt_init (&parser->ctx, parser->key, parser->iv); else if (parser->version == 2) blocktx_decrypt_init (&parser->ctx, parser->key_v2, parser->iv_v2); parser->enc_init = TRUE; if (evbuffer_get_length (input) > 0) return handle_frame_fragment_content (buf, parser); return 0; } else { return handle_frame_fragment_content (buf, parser); } } #endif seafile-6.1.5/common/block-tx-utils.h000066400000000000000000000063451323477647300175050ustar00rootroot00000000000000#ifndef BLOCK_TX_UTILS_H #define BLOCK_TX_UTILS_H #include #include #include /* Common structures and contants shared by the client and server. */ /* We use AES 256 */ #define ENC_KEY_SIZE 32 #define ENC_BLOCK_SIZE 16 #define BLOCK_PROTOCOL_VERSION 2 enum { STATUS_OK = 0, STATUS_VERSION_MISMATCH, STATUS_BAD_REQUEST, STATUS_ACCESS_DENIED, STATUS_INTERNAL_SERVER_ERROR, STATUS_NOT_FOUND, }; struct _HandshakeRequest { gint32 version; gint32 key_len; char enc_session_key[0]; } __attribute__((__packed__)); typedef struct _HandshakeRequest HandshakeRequest; struct _HandshakeResponse { gint32 status; gint32 version; } __attribute__((__packed__)); typedef struct _HandshakeResponse HandshakeResponse; struct _AuthResponse { gint32 status; } __attribute__((__packed__)); typedef struct _AuthResponse AuthResponse; enum { REQUEST_COMMAND_GET = 0, REQUEST_COMMAND_PUT, }; struct _RequestHeader { gint32 command; char block_id[40]; } __attribute__((__packed__)); typedef struct _RequestHeader RequestHeader; struct _ResponseHeader { gint32 status; } __attribute__((__packed__)); typedef struct _ResponseHeader ResponseHeader; /* Utility functions for encryption. */ void blocktx_generate_encrypt_key (unsigned char *session_key, int sk_len, unsigned char *key, unsigned char *iv); int blocktx_encrypt_init (EVP_CIPHER_CTX **ctx, const unsigned char *key, const unsigned char *iv); int blocktx_decrypt_init (EVP_CIPHER_CTX **ctx, const unsigned char *key, const unsigned char *iv); /* * Encrypted data is sent in "frames". * Format of a frame: * * length of data in the frame after encryption + encrypted data. * * Each frame can contain three types of contents: * 1. Auth request or response; * 2. Block request or response header; * 3. Block content. */ int send_encrypted_data_frame_begin (evutil_socket_t data_fd, int frame_len); int send_encrypted_data (EVP_CIPHER_CTX *ctx, evutil_socket_t data_fd, const void *buf, int len); int send_encrypted_data_frame_end (EVP_CIPHER_CTX *ctx, evutil_socket_t data_fd); typedef int (*FrameContentCB) (char *, int, void *); typedef int (*FrameFragmentCB) (char *, int, int, void *); typedef struct _FrameParser { int enc_frame_len; unsigned char key[ENC_KEY_SIZE]; unsigned char iv[ENC_BLOCK_SIZE]; gboolean enc_init; EVP_CIPHER_CTX *ctx; unsigned char key_v2[ENC_KEY_SIZE]; unsigned char iv_v2[ENC_BLOCK_SIZE]; int version; /* Used when parsing fragments */ int remain; FrameContentCB content_cb; FrameFragmentCB fragment_cb; void *cbarg; } FrameParser; /* Handle entire frame all at once. * parser->content_cb() will be called after the entire frame is read. */ int handle_one_frame (struct evbuffer *buf, FrameParser *parser); /* Handle a frame fragment by fragment. * parser->fragment_cb() will be called when any amount data is read. */ int handle_frame_fragments (struct evbuffer *buf, FrameParser *parser); #endif seafile-6.1.5/common/block.h000066400000000000000000000011631323477647300157070ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef BLOCK_H #define BLOCK_H typedef struct _BMetadata BlockMetadata; typedef struct _BMetadata BMetadata; struct _BMetadata { char id[41]; uint32_t size; }; /* Opaque block handle. */ typedef struct _BHandle BlockHandle; typedef struct _BHandle BHandle; enum { BLOCK_READ, BLOCK_WRITE, }; typedef gboolean (*SeafBlockFunc) (const char *store_id, int version, const char *block_id, void *user_data); #endif seafile-6.1.5/common/branch-mgr.c000066400000000000000000000437541323477647300166440ustar00rootroot00000000000000#include "common.h" #include "log.h" #ifndef SEAFILE_SERVER #include "db.h" #else #include "seaf-db.h" #endif #include "seafile-session.h" #include "branch-mgr.h" #define BRANCH_DB "branch.db" SeafBranch * seaf_branch_new (const char *name, const char *repo_id, const char *commit_id) { SeafBranch *branch; branch = g_new0 (SeafBranch, 1); branch->name = g_strdup (name); memcpy (branch->repo_id, repo_id, 36); branch->repo_id[36] = '\0'; memcpy (branch->commit_id, commit_id, 40); branch->commit_id[40] = '\0'; branch->ref = 1; return branch; } void seaf_branch_free (SeafBranch *branch) { if (branch == NULL) return; g_free (branch->name); g_free (branch); } void seaf_branch_list_free (GList *blist) { GList *ptr; for (ptr = blist; ptr; ptr = ptr->next) { seaf_branch_unref (ptr->data); } g_list_free (blist); } void seaf_branch_set_commit (SeafBranch *branch, const char *commit_id) { memcpy (branch->commit_id, commit_id, 40); branch->commit_id[40] = '\0'; } void seaf_branch_ref (SeafBranch *branch) { branch->ref++; } void seaf_branch_unref (SeafBranch *branch) { if (!branch) return; if (--branch->ref <= 0) seaf_branch_free (branch); } struct _SeafBranchManagerPriv { sqlite3 *db; #ifndef SEAFILE_SERVER pthread_mutex_t db_lock; #endif #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) uint32_t cevent_id; #endif }; #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) #include "mq-mgr.h" #include static void publish_repo_update_event (CEvent *event, void *data); #endif static int open_db (SeafBranchManager *mgr); SeafBranchManager * seaf_branch_manager_new (struct _SeafileSession *seaf) { SeafBranchManager *mgr; mgr = g_new0 (SeafBranchManager, 1); mgr->priv = g_new0 (SeafBranchManagerPriv, 1); mgr->seaf = seaf; #ifndef SEAFILE_SERVER pthread_mutex_init (&mgr->priv->db_lock, NULL); #endif return mgr; } int seaf_branch_manager_init (SeafBranchManager *mgr) { #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) mgr->priv->cevent_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)publish_repo_update_event, NULL); #endif return open_db (mgr); } static int open_db (SeafBranchManager *mgr) { #ifndef SEAFILE_SERVER char *db_path; const char *sql; db_path = g_build_filename (mgr->seaf->seaf_dir, BRANCH_DB, NULL); if (sqlite_open_db (db_path, &mgr->priv->db) < 0) { g_critical ("[Branch mgr] Failed to open branch db\n"); g_free (db_path); return -1; } g_free (db_path); sql = "CREATE TABLE IF NOT EXISTS Branch (" "name TEXT, repo_id TEXT, commit_id TEXT);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; sql = "CREATE INDEX IF NOT EXISTS branch_index ON Branch(repo_id, name);"; if (sqlite_query_exec (mgr->priv->db, sql) < 0) return -1; #elif defined FULL_FEATURE char *sql; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name)) ENGINE = INNODB"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_PGSQL: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(40), commit_id CHAR(40)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; case SEAF_DB_TYPE_SQLITE: sql = "CREATE TABLE IF NOT EXISTS Branch (" "name VARCHAR(10), repo_id CHAR(41), commit_id CHAR(41)," "PRIMARY KEY (repo_id, name))"; if (seaf_db_query (mgr->seaf->db, sql) < 0) return -1; break; } #endif return 0; } int seaf_branch_manager_add_branch (SeafBranchManager *mgr, SeafBranch *branch) { #ifndef SEAFILE_SERVER char sql[256]; pthread_mutex_lock (&mgr->priv->db_lock); sqlite3_snprintf (sizeof(sql), sql, "SELECT 1 FROM Branch WHERE name=%Q and repo_id=%Q", branch->name, branch->repo_id); if (sqlite_check_for_existence (mgr->priv->db, sql)) sqlite3_snprintf (sizeof(sql), sql, "UPDATE Branch SET commit_id=%Q WHERE " "name=%Q and repo_id=%Q", branch->commit_id, branch->name, branch->repo_id); else sqlite3_snprintf (sizeof(sql), sql, "INSERT INTO Branch VALUES (%Q, %Q, %Q)", branch->name, branch->repo_id, branch->commit_id); sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; #else char *sql; SeafDB *db = mgr->seaf->db; if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) { gboolean exists, err; int rc; sql = "SELECT repo_id FROM Branch WHERE name=? AND repo_id=?"; exists = seaf_db_statement_exists(db, sql, &err, 2, "string", branch->name, "string", branch->repo_id); if (err) return -1; if (exists) rc = seaf_db_statement_query (db, "UPDATE Branch SET commit_id=? " "WHERE name=? AND repo_id=?", 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id); else rc = seaf_db_statement_query (db, "INSERT INTO Branch VALUES (?, ?, ?)", 3, "string", branch->name, "string", branch->repo_id, "string", branch->commit_id); if (rc < 0) return -1; } else { int rc = seaf_db_statement_query (db, "REPLACE INTO Branch VALUES (?, ?, ?)", 3, "string", branch->name, "string", branch->repo_id, "string", branch->commit_id); if (rc < 0) return -1; } return 0; #endif } int seaf_branch_manager_del_branch (SeafBranchManager *mgr, const char *repo_id, const char *name) { #ifndef SEAFILE_SERVER char *sql; pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("DELETE FROM Branch WHERE name = %Q AND " "repo_id = '%s'", name, repo_id); if (sqlite_query_exec (mgr->priv->db, sql) < 0) seaf_warning ("Delete branch %s failed\n", name); sqlite3_free (sql); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; #else int rc = seaf_db_statement_query (mgr->seaf->db, "DELETE FROM Branch WHERE name=? AND repo_id=?", 2, "string", name, "string", repo_id); if (rc < 0) return -1; return 0; #endif } int seaf_branch_manager_update_branch (SeafBranchManager *mgr, SeafBranch *branch) { #ifndef SEAFILE_SERVER sqlite3 *db; char *sql; pthread_mutex_lock (&mgr->priv->db_lock); db = mgr->priv->db; sql = sqlite3_mprintf ("UPDATE Branch SET commit_id = %Q " "WHERE name = %Q AND repo_id = %Q", branch->commit_id, branch->name, branch->repo_id); sqlite_query_exec (db, sql); sqlite3_free (sql); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; #else int rc = seaf_db_statement_query (mgr->seaf->db, "UPDATE Branch SET commit_id = ? " "WHERE name = ? AND repo_id = ?", 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id); if (rc < 0) return -1; return 0; #endif } #if defined( SEAFILE_SERVER ) && defined( FULL_FEATURE ) static gboolean get_commit_id (SeafDBRow *row, void *data) { char *out_commit_id = data; const char *commit_id; commit_id = seaf_db_row_get_column_text (row, 0); memcpy (out_commit_id, commit_id, 41); out_commit_id[40] = '\0'; return FALSE; } typedef struct { char *repo_id; char *commit_id; } RepoUpdateEventData; static void publish_repo_update_event (CEvent *event, void *data) { RepoUpdateEventData *rdata = event->data; char buf[128]; snprintf (buf, sizeof(buf), "repo-update\t%s\t%s", rdata->repo_id, rdata->commit_id); seaf_mq_manager_publish_event (seaf->mq_mgr, buf); g_free (rdata->repo_id); g_free (rdata->commit_id); g_free (rdata); } static void on_branch_updated (SeafBranchManager *mgr, SeafBranch *branch) { if (seaf_repo_manager_is_virtual_repo (seaf->repo_mgr, branch->repo_id)) return; RepoUpdateEventData *rdata = g_new0 (RepoUpdateEventData, 1); rdata->repo_id = g_strdup (branch->repo_id); rdata->commit_id = g_strdup (branch->commit_id); cevent_manager_add_event (seaf->ev_mgr, mgr->priv->cevent_id, rdata); } int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id) { SeafDBTrans *trans; char *sql; char commit_id[41] = { 0 }; trans = seaf_db_begin_transaction (mgr->seaf->db); if (!trans) return -1; switch (seaf_db_type (mgr->seaf->db)) { case SEAF_DB_TYPE_MYSQL: case SEAF_DB_TYPE_PGSQL: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=? FOR UPDATE"; break; case SEAF_DB_TYPE_SQLITE: sql = "SELECT commit_id FROM Branch WHERE name=? " "AND repo_id=?"; break; default: g_return_val_if_reached (-1); } if (seaf_db_trans_foreach_selected_row (trans, sql, get_commit_id, commit_id, 2, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (strcmp (old_commit_id, commit_id) != 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } sql = "UPDATE Branch SET commit_id = ? " "WHERE name = ? AND repo_id = ?"; if (seaf_db_trans_query (trans, sql, 3, "string", branch->commit_id, "string", branch->name, "string", branch->repo_id) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } if (seaf_db_commit (trans) < 0) { seaf_db_rollback (trans); seaf_db_trans_close (trans); return -1; } seaf_db_trans_close (trans); on_branch_updated (mgr, branch); return 0; } #endif #ifndef SEAFILE_SERVER static SeafBranch * real_get_branch (SeafBranchManager *mgr, const char *repo_id, const char *name) { SeafBranch *branch = NULL; sqlite3_stmt *stmt; sqlite3 *db; char *sql; int result; pthread_mutex_lock (&mgr->priv->db_lock); db = mgr->priv->db; sql = sqlite3_mprintf ("SELECT commit_id FROM Branch " "WHERE name = %Q and repo_id='%s'", name, repo_id); if (!(stmt = sqlite_query_prepare (db, sql))) { seaf_warning ("[Branch mgr] Couldn't prepare query %s\n", sql); sqlite3_free (sql); pthread_mutex_unlock (&mgr->priv->db_lock); return NULL; } sqlite3_free (sql); result = sqlite3_step (stmt); if (result == SQLITE_ROW) { char *commit_id = (char *)sqlite3_column_text (stmt, 0); branch = seaf_branch_new (name, repo_id, commit_id); pthread_mutex_unlock (&mgr->priv->db_lock); sqlite3_finalize (stmt); return branch; } else if (result == SQLITE_ERROR) { const char *str = sqlite3_errmsg (db); seaf_warning ("Couldn't prepare query, error: %d->'%s'\n", result, str ? str : "no error given"); } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return NULL; } SeafBranch * seaf_branch_manager_get_branch (SeafBranchManager *mgr, const char *repo_id, const char *name) { SeafBranch *branch; /* "fetch_head" maps to "local" or "master" on client (LAN sync) */ if (strcmp (name, "fetch_head") == 0) { branch = real_get_branch (mgr, repo_id, "local"); if (!branch) { branch = real_get_branch (mgr, repo_id, "master"); } return branch; } else { return real_get_branch (mgr, repo_id, name); } } #else static gboolean get_branch (SeafDBRow *row, void *vid) { char *ret = vid; const char *commit_id; commit_id = seaf_db_row_get_column_text (row, 0); memcpy (ret, commit_id, 41); return FALSE; } static SeafBranch * real_get_branch (SeafBranchManager *mgr, const char *repo_id, const char *name) { char commit_id[41]; char *sql; commit_id[0] = 0; sql = "SELECT commit_id FROM Branch WHERE name=? AND repo_id=?"; if (seaf_db_statement_foreach_row (mgr->seaf->db, sql, get_branch, commit_id, 2, "string", name, "string", repo_id) < 0) { seaf_warning ("[branch mgr] DB error when get branch %s.\n", name); return NULL; } if (commit_id[0] == 0) return NULL; return seaf_branch_new (name, repo_id, commit_id); } SeafBranch * seaf_branch_manager_get_branch (SeafBranchManager *mgr, const char *repo_id, const char *name) { SeafBranch *branch; /* "fetch_head" maps to "master" on server. */ if (strcmp (name, "fetch_head") == 0) { branch = real_get_branch (mgr, repo_id, "master"); return branch; } else { return real_get_branch (mgr, repo_id, name); } } #endif /* not SEAFILE_SERVER */ gboolean seaf_branch_manager_branch_exists (SeafBranchManager *mgr, const char *repo_id, const char *name) { #ifndef SEAFILE_SERVER char *sql; gboolean ret; pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("SELECT name FROM Branch WHERE name = %Q " "AND repo_id='%s'", name, repo_id); ret = sqlite_check_for_existence (mgr->priv->db, sql); sqlite3_free (sql); pthread_mutex_unlock (&mgr->priv->db_lock); return ret; #else gboolean db_err = FALSE; return seaf_db_statement_exists (mgr->seaf->db, "SELECT name FROM Branch WHERE name=? " "AND repo_id=?", &db_err, 2, "string", name, "string", repo_id); #endif } #ifndef SEAFILE_SERVER GList * seaf_branch_manager_get_branch_list (SeafBranchManager *mgr, const char *repo_id) { sqlite3 *db = mgr->priv->db; int result; sqlite3_stmt *stmt; char sql[256]; char *name; char *commit_id; GList *ret = NULL; SeafBranch *branch; snprintf (sql, 256, "SELECT name, commit_id FROM branch WHERE repo_id ='%s'", repo_id); pthread_mutex_lock (&mgr->priv->db_lock); if ( !(stmt = sqlite_query_prepare(db, sql)) ) { pthread_mutex_unlock (&mgr->priv->db_lock); return NULL; } while (1) { result = sqlite3_step (stmt); if (result == SQLITE_ROW) { name = (char *)sqlite3_column_text(stmt, 0); commit_id = (char *)sqlite3_column_text(stmt, 1); branch = seaf_branch_new (name, repo_id, commit_id); ret = g_list_prepend (ret, branch); } if (result == SQLITE_DONE) break; if (result == SQLITE_ERROR) { const gchar *str = sqlite3_errmsg (db); seaf_warning ("Couldn't prepare query, error: %d->'%s'\n", result, str ? str : "no error given"); sqlite3_finalize (stmt); seaf_branch_list_free (ret); pthread_mutex_unlock (&mgr->priv->db_lock); return NULL; } } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return g_list_reverse(ret); } #else static gboolean get_branches (SeafDBRow *row, void *vplist) { GList **plist = vplist; const char *commit_id; const char *name; const char *repo_id; SeafBranch *branch; name = seaf_db_row_get_column_text (row, 0); repo_id = seaf_db_row_get_column_text (row, 1); commit_id = seaf_db_row_get_column_text (row, 2); branch = seaf_branch_new (name, repo_id, commit_id); *plist = g_list_prepend (*plist, branch); return TRUE; } GList * seaf_branch_manager_get_branch_list (SeafBranchManager *mgr, const char *repo_id) { GList *ret = NULL; char *sql; sql = "SELECT name, repo_id, commit_id FROM Branch WHERE repo_id=?"; if (seaf_db_statement_foreach_row (mgr->seaf->db, sql, get_branches, &ret, 1, "string", repo_id) < 0) { seaf_warning ("[branch mgr] DB error when get branch list.\n"); return NULL; } return ret; } #endif seafile-6.1.5/common/branch-mgr.h000066400000000000000000000046501323477647300166410ustar00rootroot00000000000000#ifndef SEAF_BRANCH_MGR_H #define SEAF_BRANCH_MGR_H #include "commit-mgr.h" #define NO_BRANCH "-" typedef struct _SeafBranch SeafBranch; struct _SeafBranch { int ref; char *name; char repo_id[37]; char commit_id[41]; }; SeafBranch *seaf_branch_new (const char *name, const char *repo_id, const char *commit_id); void seaf_branch_free (SeafBranch *branch); void seaf_branch_set_commit (SeafBranch *branch, const char *commit_id); void seaf_branch_ref (SeafBranch *branch); void seaf_branch_unref (SeafBranch *branch); typedef struct _SeafBranchManager SeafBranchManager; typedef struct _SeafBranchManagerPriv SeafBranchManagerPriv; struct _SeafileSession; struct _SeafBranchManager { struct _SeafileSession *seaf; SeafBranchManagerPriv *priv; }; SeafBranchManager *seaf_branch_manager_new (struct _SeafileSession *seaf); int seaf_branch_manager_init (SeafBranchManager *mgr); int seaf_branch_manager_add_branch (SeafBranchManager *mgr, SeafBranch *branch); int seaf_branch_manager_del_branch (SeafBranchManager *mgr, const char *repo_id, const char *name); void seaf_branch_list_free (GList *blist); int seaf_branch_manager_update_branch (SeafBranchManager *mgr, SeafBranch *branch); #ifdef SEAFILE_SERVER /** * Atomically test whether the current head commit id on @branch * is the same as @old_commit_id and update branch in db. */ int seaf_branch_manager_test_and_update_branch (SeafBranchManager *mgr, SeafBranch *branch, const char *old_commit_id); #endif SeafBranch * seaf_branch_manager_get_branch (SeafBranchManager *mgr, const char *repo_id, const char *name); gboolean seaf_branch_manager_branch_exists (SeafBranchManager *mgr, const char *repo_id, const char *name); GList * seaf_branch_manager_get_branch_list (SeafBranchManager *mgr, const char *repo_id); gint64 seaf_branch_manager_calculate_branch_size (SeafBranchManager *mgr, const char *repo_id, const char *commit_id); #endif /* SEAF_BRANCH_MGR_H */ seafile-6.1.5/common/cdc/000077500000000000000000000000001323477647300151745ustar00rootroot00000000000000seafile-6.1.5/common/cdc/Makefile.am000066400000000000000000000005031323477647300172260ustar00rootroot00000000000000AM_CFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/lib \ -Wall @GLIB2_CFLAGS@ @MSVC_CFLAGS@ noinst_LTLIBRARIES = libcdc.la noinst_HEADERS = cdc.h rabin-checksum.h libcdc_la_SOURCES = cdc.c rabin-checksum.c libcdc_la_LDFLAGS = -Wl,-z -Wl,defs libcdc_la_LIBADD = @GLIB2_LIBS@ \ $(top_builddir)/lib/libseafile_common.la seafile-6.1.5/common/cdc/cdc.c000066400000000000000000000176721323477647300161060ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "log.h" #include #include #include #include #include #include #include #include #include "utils.h" #include "cdc.h" #include "../seafile-crypt.h" #include "rabin-checksum.h" #define finger rabin_checksum #define rolling_finger rabin_rolling_checksum #define BLOCK_SZ (1024*1024*1) #define BLOCK_MIN_SZ (1024*256) #define BLOCK_MAX_SZ (1024*1024*4) #define BLOCK_WIN_SZ 48 #define NAME_MAX_SZ 4096 #define BREAK_VALUE 0x0013 ///0x0513 #define READ_SIZE 1024 * 4 #define BYTE_TO_HEX(b) (((b)>=10)?('a'+b-10):('0'+b)) static int default_write_chunk (CDCDescriptor *chunk_descr) { char filename[NAME_MAX_SZ]; char chksum_str[CHECKSUM_LENGTH *2 + 1]; int fd_chunk, ret; memset(chksum_str, 0, sizeof(chksum_str)); rawdata_to_hex (chunk_descr->checksum, chksum_str, CHECKSUM_LENGTH); snprintf (filename, NAME_MAX_SZ, "./%s", chksum_str); fd_chunk = g_open (filename, O_RDWR | O_CREAT | O_BINARY, 0644); if (fd_chunk < 0) return -1; ret = writen (fd_chunk, chunk_descr->block_buf, chunk_descr->len); close (fd_chunk); return ret; } static int init_cdc_file_descriptor (int fd, uint64_t file_size, CDCFileDescriptor *file_descr) { int max_block_nr = 0; int block_min_sz = 0; file_descr->block_nr = 0; if (file_descr->block_min_sz <= 0) file_descr->block_min_sz = BLOCK_MIN_SZ; if (file_descr->block_max_sz <= 0) file_descr->block_max_sz = BLOCK_MAX_SZ; if (file_descr->block_sz <= 0) file_descr->block_sz = BLOCK_SZ; if (file_descr->write_block == NULL) file_descr->write_block = (WriteblockFunc)default_write_chunk; block_min_sz = file_descr->block_min_sz; max_block_nr = ((file_size + block_min_sz - 1) / block_min_sz); file_descr->blk_sha1s = (uint8_t *)calloc (sizeof(uint8_t), max_block_nr * CHECKSUM_LENGTH); file_descr->max_block_nr = max_block_nr; return 0; } #define WRITE_CDC_BLOCK(block_sz, write_data) \ do { \ int _block_sz = (block_sz); \ chunk_descr.len = _block_sz; \ chunk_descr.offset = offset; \ ret = file_descr->write_block (file_descr->repo_id, \ file_descr->version, \ &chunk_descr, \ crypt, chunk_descr.checksum, \ (write_data)); \ if (ret < 0) { \ free (buf); \ g_warning ("CDC: failed to write chunk.\n"); \ return -1; \ } \ memcpy (file_descr->blk_sha1s + \ file_descr->block_nr * CHECKSUM_LENGTH, \ chunk_descr.checksum, CHECKSUM_LENGTH); \ g_checksum_update (file_ctx, chunk_descr.checksum, 20); \ file_descr->block_nr++; \ offset += _block_sz; \ \ memmove (buf, buf + _block_sz, tail - _block_sz); \ tail = tail - _block_sz; \ cur = 0; \ }while(0); /* content-defined chunking */ int file_chunk_cdc(int fd_src, CDCFileDescriptor *file_descr, SeafileCrypt *crypt, gboolean write_data) { char *buf = NULL; uint32_t buf_sz; GChecksum *file_ctx = g_checksum_new (G_CHECKSUM_SHA1); CDCDescriptor chunk_descr; int ret = 0; SeafStat sb; if (seaf_fstat (fd_src, &sb) < 0) { seaf_warning ("CDC: failed to stat: %s.\n", strerror(errno)); ret = -1; goto out; } uint64_t expected_size = sb.st_size; init_cdc_file_descriptor (fd_src, expected_size, file_descr); uint32_t block_min_sz = file_descr->block_min_sz; uint32_t block_mask = file_descr->block_sz - 1; int fingerprint = 0; int offset = 0; int tail, cur, rsize; buf_sz = file_descr->block_max_sz; buf = chunk_descr.block_buf = malloc (buf_sz); if (!buf) { ret = -1; goto out; } /* buf: a fix-sized buffer. * cur: data behind (inclusive) this offset has been scanned. * cur + 1 is the bytes that has been scanned. * tail: length of data loaded into memory. buf[tail] is invalid. */ tail = cur = 0; while (1) { if (tail < block_min_sz) { rsize = block_min_sz - tail + READ_SIZE; } else { rsize = (buf_sz - tail < READ_SIZE) ? (buf_sz - tail) : READ_SIZE; } ret = readn (fd_src, buf + tail, rsize); if (ret < 0) { seaf_warning ("CDC: failed to read: %s.\n", strerror(errno)); ret = -1; goto out; } tail += ret; file_descr->file_size += ret; if (file_descr->file_size > expected_size) { seaf_warning ("File size changed while chunking.\n"); ret = -1; goto out; } /* We've read all the data in this file. Output the block immediately * in two cases: * 1. The data left in the file is less than block_min_sz; * 2. We cannot find the break value until the end of this file. */ if (tail < block_min_sz || cur >= tail) { if (tail > 0) { if (file_descr->block_nr == file_descr->max_block_nr) { seaf_warning ("Block id array is not large enough, bail out.\n"); ret = -1; goto out; } WRITE_CDC_BLOCK (tail, write_data); } break; } /* * A block is at least of size block_min_sz. */ if (cur < block_min_sz - 1) cur = block_min_sz - 1; while (cur < tail) { fingerprint = (cur == block_min_sz - 1) ? finger(buf + cur - BLOCK_WIN_SZ + 1, BLOCK_WIN_SZ) : rolling_finger (fingerprint, BLOCK_WIN_SZ, *(buf+cur-BLOCK_WIN_SZ), *(buf + cur)); /* get a chunk, write block info to chunk file */ if (((fingerprint & block_mask) == ((BREAK_VALUE & block_mask))) || cur + 1 >= file_descr->block_max_sz) { if (file_descr->block_nr == file_descr->max_block_nr) { seaf_warning ("Block id array is not large enough, bail out.\n"); ret = -1; goto out; } WRITE_CDC_BLOCK (cur + 1, write_data); break; } else { cur ++; } } } gsize chk_sum_len = CHECKSUM_LENGTH; g_checksum_get_digest (file_ctx, file_descr->file_sum, &chk_sum_len); out: free (buf); g_checksum_free (file_ctx); return ret; } int filename_chunk_cdc(const char *filename, CDCFileDescriptor *file_descr, SeafileCrypt *crypt, gboolean write_data) { int fd_src = seaf_util_open (filename, O_RDONLY | O_BINARY); if (fd_src < 0) { seaf_warning ("CDC: failed to open %s.\n", filename); return -1; } int ret = file_chunk_cdc (fd_src, file_descr, crypt, write_data); close (fd_src); return ret; } void cdc_init () { rabin_init (BLOCK_WIN_SZ); } seafile-6.1.5/common/cdc/cdc.h000066400000000000000000000030331323477647300160750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef _CDC_H #define _CDC_H #include #include #define CHECKSUM_LENGTH 20 #ifndef O_BINARY #define O_BINARY 0 #endif struct _CDCFileDescriptor; struct _CDCDescriptor; struct SeafileCrypt; typedef int (*WriteblockFunc)(const char *repo_id, int version, struct _CDCDescriptor *chunk_descr, struct SeafileCrypt *crypt, uint8_t *checksum, gboolean write_data); /* define chunk file header and block entry */ typedef struct _CDCFileDescriptor { uint32_t block_min_sz; uint32_t block_max_sz; uint32_t block_sz; uint64_t file_size; uint32_t block_nr; uint8_t *blk_sha1s; int max_block_nr; uint8_t file_sum[CHECKSUM_LENGTH]; WriteblockFunc write_block; char repo_id[37]; int version; } CDCFileDescriptor; typedef struct _CDCDescriptor { uint64_t offset; uint32_t len; uint8_t checksum[CHECKSUM_LENGTH]; char *block_buf; int result; } CDCDescriptor; int file_chunk_cdc(int fd_src, CDCFileDescriptor *file_descr, struct SeafileCrypt *crypt, gboolean write_data); int filename_chunk_cdc(const char *filename, CDCFileDescriptor *file_descr, struct SeafileCrypt *crypt, gboolean write_data); void cdc_init (); #endif seafile-6.1.5/common/cdc/rabin-checksum.c000066400000000000000000000077741323477647300202520ustar00rootroot00000000000000#include #include "rabin-checksum.h" #ifdef WIN32 #include #ifndef u_int typedef unsigned int u_int; #endif #ifndef u_char typedef unsigned char u_char; #endif #ifndef u_short typedef unsigned short u_short; #endif #ifndef u_long typedef unsigned long u_long; #endif #ifndef u_int16_t typedef uint16_t u_int16_t; #endif #ifndef u_int32_t typedef uint32_t u_int32_t; #endif #ifndef u_int64_t typedef uint64_t u_int64_t; #endif #endif #define INT64(n) n##LL #define MSB64 INT64(0x8000000000000000) static u_int64_t poly = 0xbfe6b8a5bf378d83LL; static u_int64_t T[256]; static u_int64_t U[256]; static int shift; /* Highest bit set in a byte */ static const char bytemsb[0x100] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, }; /* Find last set (most significant bit) */ static inline u_int fls32 (u_int32_t v) { if (v & 0xffff0000) { if (v & 0xff000000) return 24 + bytemsb[v>>24]; else return 16 + bytemsb[v>>16]; } if (v & 0x0000ff00) return 8 + bytemsb[v>>8]; else return bytemsb[v]; } static inline char fls64 (u_int64_t v) { u_int32_t h; if ((h = v >> 32)) return 32 + fls32 (h); else return fls32 ((u_int32_t) v); } u_int64_t polymod (u_int64_t nh, u_int64_t nl, u_int64_t d) { int i = 0; int k = fls64 (d) - 1; d <<= 63 - k; if (nh) { if (nh & MSB64) nh ^= d; for (i = 62; i >= 0; i--) if (nh & ((u_int64_t) 1) << i) { nh ^= d >> (63 - i); nl ^= d << (i + 1); } } for (i = 63; i >= k; i--) { if (nl & INT64 (1) << i) nl ^= d >> (63 - i); } return nl; } void polymult (u_int64_t *php, u_int64_t *plp, u_int64_t x, u_int64_t y) { int i; u_int64_t ph = 0, pl = 0; if (x & 1) pl = y; for (i = 1; i < 64; i++) if (x & (INT64 (1) << i)) { ph ^= y >> (64 - i); pl ^= y << i; } if (php) *php = ph; if (plp) *plp = pl; } u_int64_t polymmult (u_int64_t x, u_int64_t y, u_int64_t d) { u_int64_t h, l; polymult (&h, &l, x, y); return polymod (h, l, d); } static u_int64_t append8 (u_int64_t p, u_char m) { return ((p << 8) | m) ^ T[p >> shift]; } static void calcT (u_int64_t poly) { int j = 0; int xshift = fls64 (poly) - 1; shift = xshift - 8; u_int64_t T1 = polymod (0, INT64 (1) << xshift, poly); for (j = 0; j < 256; j++) { T[j] = polymmult (j, T1, poly) | ((u_int64_t) j << xshift); } } static void calcU(int size) { int i; u_int64_t sizeshift = 1; for (i = 1; i < size; i++) sizeshift = append8 (sizeshift, 0); for (i = 0; i < 256; i++) U[i] = polymmult (i, sizeshift, poly); } void rabin_init(int len) { calcT(poly); calcU(len); } /* * a simple 32 bit checksum that can be upadted from end */ unsigned int rabin_checksum(char *buf, int len) { int i; unsigned int sum = 0; for (i = 0; i < len; ++i) { sum = rabin_rolling_checksum (sum, len, 0, buf[i]); } return sum; } unsigned int rabin_rolling_checksum(unsigned int csum, int len, char c1, char c2) { return append8(csum ^ U[(unsigned char)c1], c2); } seafile-6.1.5/common/cdc/rabin-checksum.h000066400000000000000000000003361323477647300202420ustar00rootroot00000000000000#ifndef _RABIN_CHECKSUM_H #define _RABIN_CHECKSUM_H unsigned int rabin_checksum(char *buf, int len); unsigned int rabin_rolling_checksum(unsigned int csum, int len, char c1, char c2); void rabin_init (int len); #endif seafile-6.1.5/common/commit-mgr.c000066400000000000000000000651571323477647300167000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "log.h" #include #include "utils.h" #include "db.h" #include "searpc-utils.h" #include "seafile-session.h" #include "commit-mgr.h" #include "seaf-utils.h" #define MAX_TIME_SKEW 259200 /* 3 days */ struct _SeafCommitManagerPriv { int dummy; }; static SeafCommit * load_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *commit_id); static int save_commit (SeafCommitManager *manager, const char *repo_id, int version, SeafCommit *commit); static void delete_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id); static json_t * commit_to_json_object (SeafCommit *commit); static SeafCommit * commit_from_json_object (const char *id, json_t *object); static void compute_commit_id (SeafCommit* commit) { GChecksum *ctx = g_checksum_new(G_CHECKSUM_SHA1); uint8_t sha1[20]; gint64 ctime_n; g_checksum_update (ctx, (guchar *)commit->root_id, 41); g_checksum_update (ctx, (guchar *)commit->creator_id, 41); if (commit->creator_name) g_checksum_update (ctx, (guchar *)commit->creator_name, strlen(commit->creator_name)+1); g_checksum_update (ctx, (guchar *)commit->desc, strlen(commit->desc)+1); /* convert to network byte order */ ctime_n = hton64 (commit->ctime); g_checksum_update (ctx, (guchar *)&ctime_n, sizeof(ctime_n)); gsize len = 20; g_checksum_get_digest (ctx, sha1, &len); rawdata_to_hex (sha1, commit->commit_id, 20); g_checksum_free (ctx); } SeafCommit* seaf_commit_new (const char *commit_id, const char *repo_id, const char *root_id, const char *creator_name, const char *creator_id, const char *desc, guint64 ctime) { SeafCommit *commit; g_return_val_if_fail (repo_id != NULL, NULL); g_return_val_if_fail (root_id != NULL && creator_id != NULL, NULL); commit = g_new0 (SeafCommit, 1); memcpy (commit->repo_id, repo_id, 36); commit->repo_id[36] = '\0'; memcpy (commit->root_id, root_id, 40); commit->root_id[40] = '\0'; commit->creator_name = g_strdup (creator_name); memcpy (commit->creator_id, creator_id, 40); commit->creator_id[40] = '\0'; commit->desc = g_strdup (desc); if (ctime == 0) { /* TODO: use more precise timer */ commit->ctime = (gint64)time(NULL); } else commit->ctime = ctime; if (commit_id == NULL) compute_commit_id (commit); else { memcpy (commit->commit_id, commit_id, 40); commit->commit_id[40] = '\0'; } commit->ref = 1; return commit; } char * seaf_commit_to_data (SeafCommit *commit, gsize *len) { json_t *object; char *json_data; char *ret; object = commit_to_json_object (commit); json_data = json_dumps (object, 0); *len = strlen (json_data); json_decref (object); ret = g_strdup (json_data); free (json_data); return ret; } SeafCommit * seaf_commit_from_data (const char *id, char *data, gsize len) { json_t *object; SeafCommit *commit; json_error_t jerror; object = json_loadb (data, len, 0, &jerror); if (!object) { /* Perhaps the commit object contains invalid UTF-8 character. */ if (data[len-1] == 0) clean_utf8_data (data, len - 1); else clean_utf8_data (data, len); object = json_loadb (data, len, 0, &jerror); if (!object) { seaf_warning ("Failed to load commit json: %s.\n", jerror.text); return NULL; } } commit = commit_from_json_object (id, object); json_decref (object); return commit; } static void seaf_commit_free (SeafCommit *commit) { g_free (commit->desc); g_free (commit->creator_name); if (commit->parent_id) g_free (commit->parent_id); if (commit->second_parent_id) g_free (commit->second_parent_id); if (commit->repo_name) g_free (commit->repo_name); if (commit->repo_desc) g_free (commit->repo_desc); if (commit->device_name) g_free (commit->device_name); g_free (commit->client_version); g_free (commit->magic); g_free (commit->random_key); g_free (commit); } void seaf_commit_ref (SeafCommit *commit) { commit->ref++; } void seaf_commit_unref (SeafCommit *commit) { if (!commit) return; if (--commit->ref <= 0) seaf_commit_free (commit); } SeafCommitManager* seaf_commit_manager_new (SeafileSession *seaf) { SeafCommitManager *mgr = g_new0 (SeafCommitManager, 1); mgr->priv = g_new0 (SeafCommitManagerPriv, 1); mgr->seaf = seaf; mgr->obj_store = seaf_obj_store_new (mgr->seaf, "commits"); return mgr; } int seaf_commit_manager_init (SeafCommitManager *mgr) { #ifdef SEAFILE_SERVER #ifdef FULL_FEATURE if (seaf_obj_store_init (mgr->obj_store, TRUE, seaf->ev_mgr) < 0) { seaf_warning ("[commit mgr] Failed to init commit object store.\n"); return -1; } #else if (seaf_obj_store_init (mgr->obj_store, FALSE, NULL) < 0) { seaf_warning ("[commit mgr] Failed to init commit object store.\n"); return -1; } #endif #else if (seaf_obj_store_init (mgr->obj_store, TRUE, seaf->ev_mgr) < 0) { seaf_warning ("[commit mgr] Failed to init commit object store.\n"); return -1; } #endif return 0; } #if 0 inline static void add_commit_to_cache (SeafCommitManager *mgr, SeafCommit *commit) { g_hash_table_insert (mgr->priv->commit_cache, g_strdup(commit->commit_id), commit); seaf_commit_ref (commit); } inline static void remove_commit_from_cache (SeafCommitManager *mgr, SeafCommit *commit) { g_hash_table_remove (mgr->priv->commit_cache, commit->commit_id); seaf_commit_unref (commit); } #endif int seaf_commit_manager_add_commit (SeafCommitManager *mgr, SeafCommit *commit) { int ret; /* add_commit_to_cache (mgr, commit); */ if ((ret = save_commit (mgr, commit->repo_id, commit->version, commit)) < 0) return -1; return 0; } void seaf_commit_manager_del_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id) { g_return_if_fail (id != NULL); #if 0 commit = g_hash_table_lookup(mgr->priv->commit_cache, id); if (!commit) goto delete; /* * Catch ref count bug here. We have bug in commit ref, the * following assert can't pass. TODO: fix the commit ref bug */ /* g_assert (commit->ref <= 1); */ remove_commit_from_cache (mgr, commit); delete: #endif delete_commit (mgr, repo_id, version, id); } SeafCommit* seaf_commit_manager_get_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id) { SeafCommit *commit; #if 0 commit = g_hash_table_lookup (mgr->priv->commit_cache, id); if (commit != NULL) { seaf_commit_ref (commit); return commit; } #endif commit = load_commit (mgr, repo_id, version, id); if (!commit) return NULL; /* add_commit_to_cache (mgr, commit); */ return commit; } SeafCommit * seaf_commit_manager_get_commit_compatible (SeafCommitManager *mgr, const char *repo_id, const char *id) { SeafCommit *commit = NULL; /* First try version 1 layout. */ commit = seaf_commit_manager_get_commit (mgr, repo_id, 1, id); if (commit) return commit; #if defined MIGRATION || defined SEAFILE_CLIENT /* For compatibility with version 0. */ commit = seaf_commit_manager_get_commit (mgr, repo_id, 0, id); #endif return commit; } static gint compare_commit_by_time (gconstpointer a, gconstpointer b, gpointer unused) { const SeafCommit *commit_a = a; const SeafCommit *commit_b = b; /* Latest commit comes first in the list. */ return (commit_b->ctime - commit_a->ctime); } inline static int insert_parent_commit (GList **list, GHashTable *hash, const char *repo_id, int version, const char *parent_id, gboolean allow_truncate) { SeafCommit *p; char *key; if (g_hash_table_lookup (hash, parent_id) != NULL) return 0; p = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, parent_id); if (!p) { if (allow_truncate) return 0; seaf_warning ("Failed to find commit %s\n", parent_id); return -1; } *list = g_list_insert_sorted_with_data (*list, p, compare_commit_by_time, NULL); key = g_strdup (parent_id); g_hash_table_replace (hash, key, key); return 0; } gboolean seaf_commit_manager_traverse_commit_tree_with_limit (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, int limit, void *data, gboolean skip_errors) { SeafCommit *commit; GList *list = NULL; GHashTable *commit_hash; gboolean ret = TRUE; /* A hash table for recording id of traversed commits. */ commit_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); commit = seaf_commit_manager_get_commit (mgr, repo_id, version, head); if (!commit) { seaf_warning ("Failed to find commit %s.\n", head); return FALSE; } list = g_list_insert_sorted_with_data (list, commit, compare_commit_by_time, NULL); char *key = g_strdup (commit->commit_id); g_hash_table_replace (commit_hash, key, key); int count = 0; while (list) { gboolean stop = FALSE; commit = list->data; list = g_list_delete_link (list, list); if (!func (commit, data, &stop)) { if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } /* Stop when limit is reached. If limit < 0, there is no limit; */ if (limit > 0 && ++count == limit) { seaf_commit_unref (commit); break; } if (stop) { seaf_commit_unref (commit); /* stop traverse down from this commit, * but not stop traversing the tree */ continue; } if (commit->parent_id) { if (insert_parent_commit (&list, commit_hash, repo_id, version, commit->parent_id, FALSE) < 0) { if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } } if (commit->second_parent_id) { if (insert_parent_commit (&list, commit_hash, repo_id, version, commit->second_parent_id, FALSE) < 0) { if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } } seaf_commit_unref (commit); } out: g_hash_table_destroy (commit_hash); while (list) { commit = list->data; seaf_commit_unref (commit); list = g_list_delete_link (list, list); } return ret; } static gboolean traverse_commit_tree_common (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, void *data, gboolean skip_errors, gboolean allow_truncate) { SeafCommit *commit; GList *list = NULL; GHashTable *commit_hash; gboolean ret = TRUE; commit = seaf_commit_manager_get_commit (mgr, repo_id, version, head); if (!commit) { seaf_warning ("Failed to find commit %s.\n", head); // For head commit corrupted, directly return FALSE // user can repair head by fsck then retraverse the tree return FALSE; } /* A hash table for recording id of traversed commits. */ commit_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); list = g_list_insert_sorted_with_data (list, commit, compare_commit_by_time, NULL); char *key = g_strdup (commit->commit_id); g_hash_table_replace (commit_hash, key, key); while (list) { gboolean stop = FALSE; commit = list->data; list = g_list_delete_link (list, list); if (!func (commit, data, &stop)) { seaf_warning("[comit-mgr] CommitTraverseFunc failed\n"); /* If skip errors, continue to traverse parents. */ if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } if (stop) { seaf_commit_unref (commit); /* stop traverse down from this commit, * but not stop traversing the tree */ continue; } if (commit->parent_id) { if (insert_parent_commit (&list, commit_hash, repo_id, version, commit->parent_id, allow_truncate) < 0) { seaf_warning("[comit-mgr] insert parent commit failed\n"); /* If skip errors, try insert second parent. */ if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } } if (commit->second_parent_id) { if (insert_parent_commit (&list, commit_hash, repo_id, version, commit->second_parent_id, allow_truncate) < 0) { seaf_warning("[comit-mgr]insert second parent commit failed\n"); if (!skip_errors) { seaf_commit_unref (commit); ret = FALSE; goto out; } } } seaf_commit_unref (commit); } out: g_hash_table_destroy (commit_hash); while (list) { commit = list->data; seaf_commit_unref (commit); list = g_list_delete_link (list, list); } return ret; } gboolean seaf_commit_manager_traverse_commit_tree (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, void *data, gboolean skip_errors) { return traverse_commit_tree_common (mgr, repo_id, version, head, func, data, skip_errors, FALSE); } gboolean seaf_commit_manager_traverse_commit_tree_truncated (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, void *data, gboolean skip_errors) { return traverse_commit_tree_common (mgr, repo_id, version, head, func, data, skip_errors, TRUE); } gboolean seaf_commit_manager_commit_exists (SeafCommitManager *mgr, const char *repo_id, int version, const char *id) { #if 0 commit = g_hash_table_lookup (mgr->priv->commit_cache, id); if (commit != NULL) return TRUE; #endif return seaf_obj_store_obj_exists (mgr->obj_store, repo_id, version, id); } static json_t * commit_to_json_object (SeafCommit *commit) { json_t *object; object = json_object (); json_object_set_string_member (object, "commit_id", commit->commit_id); json_object_set_string_member (object, "root_id", commit->root_id); json_object_set_string_member (object, "repo_id", commit->repo_id); if (commit->creator_name) json_object_set_string_member (object, "creator_name", commit->creator_name); json_object_set_string_member (object, "creator", commit->creator_id); json_object_set_string_member (object, "description", commit->desc); json_object_set_int_member (object, "ctime", (gint64)commit->ctime); json_object_set_string_or_null_member (object, "parent_id", commit->parent_id); json_object_set_string_or_null_member (object, "second_parent_id", commit->second_parent_id); /* * also save repo's properties to commit file, for easy sharing of * repo info */ json_object_set_string_member (object, "repo_name", commit->repo_name); json_object_set_string_member (object, "repo_desc", commit->repo_desc); json_object_set_string_or_null_member (object, "repo_category", commit->repo_category); if (commit->device_name) json_object_set_string_member (object, "device_name", commit->device_name); if (commit->client_version) json_object_set_string_member (object, "client_version", commit->client_version); if (commit->encrypted) json_object_set_string_member (object, "encrypted", "true"); if (commit->encrypted) { json_object_set_int_member (object, "enc_version", commit->enc_version); if (commit->enc_version >= 1) json_object_set_string_member (object, "magic", commit->magic); if (commit->enc_version == 2) json_object_set_string_member (object, "key", commit->random_key); } if (commit->no_local_history) json_object_set_int_member (object, "no_local_history", 1); if (commit->version != 0) json_object_set_int_member (object, "version", commit->version); if (commit->conflict) json_object_set_int_member (object, "conflict", 1); if (commit->new_merge) json_object_set_int_member (object, "new_merge", 1); if (commit->repaired) json_object_set_int_member (object, "repaired", 1); return object; } static SeafCommit * commit_from_json_object (const char *commit_id, json_t *object) { SeafCommit *commit = NULL; const char *root_id; const char *repo_id; const char *creator_name = NULL; const char *creator; const char *desc; gint64 ctime; const char *parent_id, *second_parent_id; const char *repo_name; const char *repo_desc; const char *repo_category; const char *device_name; const char *client_version; const char *encrypted = NULL; int enc_version = 0; const char *magic = NULL; const char *random_key = NULL; int no_local_history = 0; int version = 0; int conflict = 0, new_merge = 0; int repaired = 0; root_id = json_object_get_string_member (object, "root_id"); repo_id = json_object_get_string_member (object, "repo_id"); if (json_object_has_member (object, "creator_name")) creator_name = json_object_get_string_or_null_member (object, "creator_name"); creator = json_object_get_string_member (object, "creator"); desc = json_object_get_string_member (object, "description"); if (!desc) desc = ""; ctime = (guint64) json_object_get_int_member (object, "ctime"); parent_id = json_object_get_string_or_null_member (object, "parent_id"); second_parent_id = json_object_get_string_or_null_member (object, "second_parent_id"); repo_name = json_object_get_string_member (object, "repo_name"); if (!repo_name) repo_name = ""; repo_desc = json_object_get_string_member (object, "repo_desc"); if (!repo_desc) repo_desc = ""; repo_category = json_object_get_string_or_null_member (object, "repo_category"); device_name = json_object_get_string_or_null_member (object, "device_name"); client_version = json_object_get_string_or_null_member (object, "client_version"); if (json_object_has_member (object, "encrypted")) encrypted = json_object_get_string_or_null_member (object, "encrypted"); if (encrypted && strcmp(encrypted, "true") == 0 && json_object_has_member (object, "enc_version")) { enc_version = json_object_get_int_member (object, "enc_version"); magic = json_object_get_string_member (object, "magic"); } if (enc_version == 2) random_key = json_object_get_string_member (object, "key"); if (json_object_has_member (object, "no_local_history")) no_local_history = json_object_get_int_member (object, "no_local_history"); if (json_object_has_member (object, "version")) version = json_object_get_int_member (object, "version"); if (json_object_has_member (object, "new_merge")) new_merge = json_object_get_int_member (object, "new_merge"); if (json_object_has_member (object, "conflict")) conflict = json_object_get_int_member (object, "conflict"); if (json_object_has_member (object, "repaired")) repaired = json_object_get_int_member (object, "repaired"); /* sanity check for incoming values. */ if (!repo_id || !is_uuid_valid(repo_id) || !root_id || !is_object_id_valid(root_id) || !creator || strlen(creator) != 40 || (parent_id && !is_object_id_valid(parent_id)) || (second_parent_id && !is_object_id_valid(second_parent_id))) return commit; switch (enc_version) { case 0: break; case 1: if (!magic || strlen(magic) != 32) return NULL; break; case 2: if (!magic || strlen(magic) != 64) return NULL; if (!random_key || strlen(random_key) != 96) return NULL; break; default: seaf_warning ("Unknown encryption version %d.\n", enc_version); return NULL; } char *creator_name_l = creator_name ? g_ascii_strdown (creator_name, -1) : NULL; commit = seaf_commit_new (commit_id, repo_id, root_id, creator_name_l, creator, desc, ctime); g_free (creator_name_l); commit->parent_id = parent_id ? g_strdup(parent_id) : NULL; commit->second_parent_id = second_parent_id ? g_strdup(second_parent_id) : NULL; commit->repo_name = g_strdup(repo_name); commit->repo_desc = g_strdup(repo_desc); if (encrypted && strcmp(encrypted, "true") == 0) commit->encrypted = TRUE; else commit->encrypted = FALSE; if (repo_category) commit->repo_category = g_strdup(repo_category); commit->device_name = g_strdup(device_name); commit->client_version = g_strdup(client_version); if (commit->encrypted) { commit->enc_version = enc_version; if (enc_version >= 1) commit->magic = g_strdup(magic); if (enc_version == 2) commit->random_key = g_strdup (random_key); } if (no_local_history) commit->no_local_history = TRUE; commit->version = version; if (new_merge) commit->new_merge = TRUE; if (conflict) commit->conflict = TRUE; if (repaired) commit->repaired = TRUE; return commit; } static SeafCommit * load_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *commit_id) { char *data = NULL; int len; SeafCommit *commit = NULL; json_t *object = NULL; json_error_t jerror; if (!commit_id || strlen(commit_id) != 40) return NULL; if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, commit_id, (void **)&data, &len) < 0) return NULL; object = json_loadb (data, len, 0, &jerror); if (!object) { /* Perhaps the commit object contains invalid UTF-8 character. */ if (data[len-1] == 0) clean_utf8_data (data, len - 1); else clean_utf8_data (data, len); object = json_loadb (data, len, 0, &jerror); if (!object) { seaf_warning ("Failed to load commit json object: %s.\n", jerror.text); goto out; } } commit = commit_from_json_object (commit_id, object); if (commit) commit->manager = mgr; out: if (object) json_decref (object); g_free (data); return commit; } static int save_commit (SeafCommitManager *manager, const char *repo_id, int version, SeafCommit *commit) { json_t *object = NULL; char *data; gsize len; object = commit_to_json_object (commit); data = json_dumps (object, 0); len = strlen (data); json_decref (object); #ifdef SEAFILE_SERVER if (seaf_obj_store_write_obj (manager->obj_store, repo_id, version, commit->commit_id, data, (int)len, TRUE) < 0) { g_free (data); return -1; } #else if (seaf_obj_store_write_obj (manager->obj_store, repo_id, version, commit->commit_id, data, (int)len, FALSE) < 0) { g_free (data); return -1; } #endif free (data); return 0; } static void delete_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id) { seaf_obj_store_delete_obj (mgr->obj_store, repo_id, version, id); } int seaf_commit_manager_remove_store (SeafCommitManager *mgr, const char *store_id) { return seaf_obj_store_remove_store (mgr->obj_store, store_id); } seafile-6.1.5/common/commit-mgr.h000066400000000000000000000143751323477647300167010ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_COMMIT_MGR_H #define SEAF_COMMIT_MGR_H struct _SeafCommitManager; typedef struct _SeafCommit SeafCommit; #include #include "db.h" #include "obj-store.h" struct _SeafCommit { struct _SeafCommitManager *manager; int ref; char commit_id[41]; char repo_id[37]; char root_id[41]; /* the fs root */ char *desc; char *creator_name; char creator_id[41]; guint64 ctime; /* creation time */ char *parent_id; char *second_parent_id; char *repo_name; char *repo_desc; char *repo_category; char *device_name; char *client_version; gboolean encrypted; int enc_version; char *magic; char *random_key; gboolean no_local_history; int version; gboolean new_merge; gboolean conflict; gboolean repaired; }; /** * @commit_id: if this is NULL, will create a new id. * @ctime: if this is 0, will use current time. * * Any new commit should be added to commit manager before used. */ SeafCommit * seaf_commit_new (const char *commit_id, const char *repo_id, const char *root_id, const char *author_name, const char *creator_id, const char *desc, guint64 ctime); char * seaf_commit_to_data (SeafCommit *commit, gsize *len); SeafCommit * seaf_commit_from_data (const char *id, char *data, gsize len); void seaf_commit_ref (SeafCommit *commit); void seaf_commit_unref (SeafCommit *commit); /* Set stop to TRUE if you want to stop traversing a branch in the history graph. Note, if currently there are multi branches, this function will be called again. So, set stop to TRUE not always stop traversing the history graph. */ typedef gboolean (*CommitTraverseFunc) (SeafCommit *commit, void *data, gboolean *stop); struct _SeafileSession; typedef struct _SeafCommitManager SeafCommitManager; typedef struct _SeafCommitManagerPriv SeafCommitManagerPriv; struct _SeafCommitManager { struct _SeafileSession *seaf; sqlite3 *db; struct SeafObjStore *obj_store; SeafCommitManagerPriv *priv; }; SeafCommitManager * seaf_commit_manager_new (struct _SeafileSession *seaf); int seaf_commit_manager_init (SeafCommitManager *mgr); /** * Add a commit to commit manager and persist it to disk. * Any new commit should be added to commit manager before used. * This function increments ref count of the commit object. * Not MT safe. */ int seaf_commit_manager_add_commit (SeafCommitManager *mgr, SeafCommit *commit); /** * Delete a commit from commit manager and permanently remove it from disk. * A commit object to be deleted should have ref cournt <= 1. * Not MT safe. */ void seaf_commit_manager_del_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id); /** * Find a commit object. * This function increments ref count of returned object. * Not MT safe. */ SeafCommit* seaf_commit_manager_get_commit (SeafCommitManager *mgr, const char *repo_id, int version, const char *id); /** * Get a commit object, with compatibility between version 0 and version 1. * It will first try to get commit with version 1 layout; if fails, will * try version 0 layout for compatibility. * This is useful for loading a repo. In that case, we don't know the version * of the repo before loading its head commit. */ SeafCommit * seaf_commit_manager_get_commit_compatible (SeafCommitManager *mgr, const char *repo_id, const char *id); /** * Traverse the commits DAG start from head in topological order. * The ordering is based on commit time. * return FALSE if some commits is missing, TRUE otherwise. */ gboolean seaf_commit_manager_traverse_commit_tree (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, void *data, gboolean skip_errors); /* * The same as the above function, but stops traverse down if parent commit * doesn't exists, instead of returning error. */ gboolean seaf_commit_manager_traverse_commit_tree_truncated (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, void *data, gboolean skip_errors); /** * Works the same as seaf_commit_manager_traverse_commit_tree, but stops * traversing when a total number of _limit_ commits is reached. If * limit <= 0, there is no limit */ gboolean seaf_commit_manager_traverse_commit_tree_with_limit (SeafCommitManager *mgr, const char *repo_id, int version, const char *head, CommitTraverseFunc func, int limit, void *data, gboolean skip_errors); gboolean seaf_commit_manager_commit_exists (SeafCommitManager *mgr, const char *repo_id, int version, const char *id); int seaf_commit_manager_remove_store (SeafCommitManager *mgr, const char *store_id); #endif seafile-6.1.5/common/common.h000066400000000000000000000024601323477647300161060ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef COMMON_H #define COMMON_H #ifdef HAVE_CONFIG_H #include #endif #include #include #include /* uint32_t */ #include /* size_t */ #include #include #include #include #include #include #include #define EMPTY_SHA1 "0000000000000000000000000000000000000000" #define CURRENT_ENC_VERSION 2 #define DEFAULT_PROTO_VERSION 1 #define CURRENT_PROTO_VERSION 7 #define CURRENT_REPO_VERSION 1 #define CURRENT_SYNC_PROTO_VERSION 2 /* For compatibility with the old protocol, use an UUID for signature. * Listen manager on the server will use the new block tx protocol if it * receives this signature as "token". */ #define BLOCK_PROTOCOL_SIGNATURE "529319a0-577f-4d6b-a6c3-3c20f56f290c" #define SEAF_PATH_MAX 4096 #ifndef ccnet_warning #define ccnet_warning(fmt, ...) g_warning("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #ifndef ccnet_error #define ccnet_error(fmt, ...) g_error("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #ifndef ccnet_message #define ccnet_message(fmt, ...) g_message("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #endif seafile-6.1.5/common/curl-init.c000066400000000000000000000024171323477647300165210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #ifndef USE_GPL_CRYPTO #include #include #include #include "curl-init.h" pthread_mutex_t* curl_locks = NULL; void seafile_curl_locking_callback(int mode, int n, const char* file, int line) { if (mode & CRYPTO_LOCK) { pthread_mutex_lock (&curl_locks[n]); } else { pthread_mutex_unlock (&curl_locks[n]); } } void seafile_curl_init() { int i; curl_locks = malloc (sizeof(pthread_mutex_t) * CRYPTO_num_locks()); for (i = 0; i < CRYPTO_num_locks(); ++i) { pthread_mutex_init (&curl_locks[i], NULL); } #ifndef WIN32 /* On Windows it's better to use the default id_function. * As per http://linux.die.net/man/3/crypto_set_id_callback, * the default id_functioin uses system's default thread * identifying API. */ CRYPTO_set_id_callback (pthread_self); #endif CRYPTO_set_locking_callback (seafile_curl_locking_callback); } void seafile_curl_deinit() { int i; CRYPTO_set_id_callback (0); CRYPTO_set_locking_callback (0); for (i = 0; i < CRYPTO_num_locks(); ++i) { pthread_mutex_destroy (&curl_locks[i]); } free (curl_locks); } #endif seafile-6.1.5/common/curl-init.h000066400000000000000000000003061323477647300165210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef __CURL_INIT_H__ #define __CURL_INIT_H__ void seafile_curl_init(void); void seafile_curl_deinit(void); #endif seafile-6.1.5/common/diff-simple.c000066400000000000000000000647671323477647300170320ustar00rootroot00000000000000#include "common.h" #include "diff-simple.h" #include "utils.h" #include "log.h" #ifndef SEAFILE_SERVER #include "unpack-trees.h" #endif DiffEntry * diff_entry_new (char type, char status, unsigned char *sha1, const char *name) { DiffEntry *de = g_new0 (DiffEntry, 1); de->type = type; de->status = status; memcpy (de->sha1, sha1, 20); de->name = g_strdup(name); return de; } DiffEntry * diff_entry_new_from_dirent (char type, char status, SeafDirent *dent, const char *basedir) { DiffEntry *de = g_new0 (DiffEntry, 1); unsigned char sha1[20]; char *path; hex_to_rawdata (dent->id, sha1, 20); path = g_strconcat (basedir, dent->name, NULL); de->type = type; de->status = status; memcpy (de->sha1, sha1, 20); de->name = path; #ifdef SEAFILE_CLIENT if (type == DIFF_TYPE_COMMITS && (status == DIFF_STATUS_ADDED || status == DIFF_STATUS_MODIFIED || status == DIFF_STATUS_DIR_ADDED || status == DIFF_STATUS_DIR_DELETED)) { de->mtime = dent->mtime; de->mode = dent->mode; de->modifier = g_strdup(dent->modifier); de->size = dent->size; } #endif return de; } void diff_entry_free (DiffEntry *de) { g_free (de->name); if (de->new_name) g_free (de->new_name); #ifdef SEAFILE_CLIENT g_free (de->modifier); #endif g_free (de); } #ifndef SEAFILE_SERVER static void diff_two_cache_entries (struct cache_entry *tree1, struct cache_entry *tree2, int diff_type, GList **results) { DiffEntry *de; if (!tree1) { if (S_ISDIR(tree2->ce_mode)) { de = diff_entry_new (diff_type, DIFF_STATUS_DIR_ADDED, tree2->sha1, tree2->name); } else { de = diff_entry_new (diff_type, DIFF_STATUS_ADDED, tree2->sha1, tree2->name); } *results = g_list_prepend (*results, de); return; } if (!tree2) { if (S_ISDIR(tree1->ce_mode)) { de = diff_entry_new (diff_type, DIFF_STATUS_DIR_DELETED, tree1->sha1, tree1->name); } else { de = diff_entry_new (diff_type, DIFF_STATUS_DELETED, tree1->sha1, tree1->name); } *results = g_list_prepend (*results, de); return; } if (tree2->ce_mode != tree1->ce_mode || hashcmp(tree2->sha1, tree1->sha1) != 0) { if (S_ISDIR(tree2->ce_mode)) { de = diff_entry_new (diff_type, DIFF_STATUS_DELETED, tree1->sha1, tree1->name); *results = g_list_prepend (*results, de); de = diff_entry_new (diff_type, DIFF_STATUS_DIR_ADDED, tree2->sha1, tree2->name); *results = g_list_prepend (*results, de); } else if (S_ISDIR(tree1->ce_mode)) { de = diff_entry_new (diff_type, DIFF_STATUS_DIR_DELETED, tree1->sha1, tree1->name); *results = g_list_prepend (*results, de); de = diff_entry_new (diff_type, DIFF_STATUS_ADDED, tree2->sha1, tree2->name); *results = g_list_prepend (*results, de); } else { de = diff_entry_new (diff_type, DIFF_STATUS_MODIFIED, tree2->sha1, tree2->name); *results = g_list_prepend (*results, de); } } } static int oneway_diff(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *idx = src[0]; struct cache_entry *tree = src[1]; GList **results = o->unpack_data; if (idx == o->df_conflict_entry) idx = NULL; if (tree == o->df_conflict_entry) tree = NULL; diff_two_cache_entries (tree, idx, DIFF_TYPE_INDEX, results); return 0; } int diff_index(const char *repo_id, int version, struct index_state *istate, SeafDir *root, GList **results) { struct tree_desc t; struct unpack_trees_options opts; memset(&opts, 0, sizeof(opts)); memcpy (opts.repo_id, repo_id, 36); opts.version = version; opts.head_idx = 1; opts.index_only = 1; /* Unmerged entries are handled in diff worktree. */ opts.skip_unmerged = 1; opts.merge = 1; opts.fn = oneway_diff; opts.unpack_data = results; opts.src_index = istate; opts.dst_index = NULL; fill_tree_descriptor(repo_id, version, &t, root->dir_id); int ret = unpack_trees(1, &t, &opts); tree_desc_free (&t); return ret; } #endif /* not SEAFILE_SERVER */ inline static gboolean dirent_same (SeafDirent *denta, SeafDirent *dentb) { return (strcmp (dentb->id, denta->id) == 0 && denta->mode == dentb->mode && denta->mtime == dentb->mtime); } static int diff_files (int n, SeafDirent *dents[], const char *basedir, DiffOptions *opt) { SeafDirent *files[3]; int i, n_files = 0; memset (files, 0, sizeof(files[0])*n); for (i = 0; i < n; ++i) { if (dents[i] && S_ISREG(dents[i]->mode)) { files[i] = dents[i]; ++n_files; } } if (n_files == 0) return 0; return opt->file_cb (n, basedir, files, opt->data); } static int diff_trees_recursive (int n, SeafDir *trees[], const char *basedir, DiffOptions *opt); static int diff_directories (int n, SeafDirent *dents[], const char *basedir, DiffOptions *opt) { SeafDirent *dirs[3]; int i, n_dirs = 0; char *dirname = ""; int ret; SeafDir *sub_dirs[3], *dir; memset (dirs, 0, sizeof(dirs[0])*n); for (i = 0; i < n; ++i) { if (dents[i] && S_ISDIR(dents[i]->mode)) { dirs[i] = dents[i]; ++n_dirs; } } if (n_dirs == 0) return 0; gboolean recurse = TRUE; ret = opt->dir_cb (n, basedir, dirs, opt->data, &recurse); if (ret < 0) return ret; if (!recurse) return 0; memset (sub_dirs, 0, sizeof(sub_dirs[0])*n); for (i = 0; i < n; ++i) { if (dents[i] != NULL && S_ISDIR(dents[i]->mode)) { dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, opt->store_id, opt->version, dents[i]->id); if (!dir) { seaf_warning ("Failed to find dir %s:%s.\n", opt->store_id, dents[i]->id); ret = -1; goto free_sub_dirs; } sub_dirs[i] = dir; dirname = dents[i]->name; } } char *new_basedir = g_strconcat (basedir, dirname, "/", NULL); ret = diff_trees_recursive (n, sub_dirs, new_basedir, opt); g_free (new_basedir); free_sub_dirs: for (i = 0; i < n; ++i) seaf_dir_free (sub_dirs[i]); return ret; } static int diff_trees_recursive (int n, SeafDir *trees[], const char *basedir, DiffOptions *opt) { GList *ptrs[3]; SeafDirent *dents[3]; int i; SeafDirent *dent; char *first_name; gboolean done; int ret = 0; for (i = 0; i < n; ++i) { if (trees[i]) ptrs[i] = trees[i]->entries; else ptrs[i] = NULL; } while (1) { first_name = NULL; memset (dents, 0, sizeof(dents[0])*n); done = TRUE; /* Find the "largest" name, assuming dirents are sorted. */ for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { done = FALSE; dent = ptrs[i]->data; if (!first_name) first_name = dent->name; else if (strcmp(dent->name, first_name) > 0) first_name = dent->name; } } if (done) break; /* * Setup dir entries for all names that equal to first_name */ for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { dent = ptrs[i]->data; if (strcmp(first_name, dent->name) == 0) { dents[i] = dent; ptrs[i] = ptrs[i]->next; } } } if (n == 2 && dents[0] && dents[1] && dirent_same(dents[0], dents[1])) continue; if (n == 3 && dents[0] && dents[1] && dents[2] && dirent_same(dents[0], dents[1]) && dirent_same(dents[0], dents[2])) continue; /* Diff files of this level. */ ret = diff_files (n, dents, basedir, opt); if (ret < 0) return ret; /* Recurse into sub level. */ ret = diff_directories (n, dents, basedir, opt); if (ret < 0) return ret; } return ret; } int diff_trees (int n, const char *roots[], DiffOptions *opt) { SeafDir **trees, *root; int i, ret; g_return_val_if_fail (n == 2 || n == 3, -1); trees = g_new0 (SeafDir *, n); for (i = 0; i < n; ++i) { root = seaf_fs_manager_get_seafdir (seaf->fs_mgr, opt->store_id, opt->version, roots[i]); if (!root) { seaf_warning ("Failed to find dir %s:%s.\n", opt->store_id, roots[i]); g_free (trees); return -1; } trees[i] = root; } ret = diff_trees_recursive (n, trees, "", opt); for (i = 0; i < n; ++i) seaf_dir_free (trees[i]); g_free (trees); return ret; } typedef struct DiffData { GList **results; gboolean fold_dir_diff; } DiffData; static int twoway_diff_files (int n, const char *basedir, SeafDirent *files[], void *vdata) { DiffData *data = vdata; GList **results = data->results; DiffEntry *de; SeafDirent *tree1 = files[0]; SeafDirent *tree2 = files[1]; if (!tree1) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_ADDED, tree2, basedir); *results = g_list_prepend (*results, de); return 0; } if (!tree2) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_DELETED, tree1, basedir); *results = g_list_prepend (*results, de); return 0; } if (!dirent_same (tree1, tree2)) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_MODIFIED, tree2, basedir); *results = g_list_prepend (*results, de); } return 0; } static int twoway_diff_dirs (int n, const char *basedir, SeafDirent *dirs[], void *vdata, gboolean *recurse) { DiffData *data = vdata; GList **results = data->results; DiffEntry *de; SeafDirent *tree1 = dirs[0]; SeafDirent *tree2 = dirs[1]; if (!tree1) { if (strcmp (tree2->id, EMPTY_SHA1) == 0 || data->fold_dir_diff) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_DIR_ADDED, tree2, basedir); *results = g_list_prepend (*results, de); *recurse = FALSE; } else *recurse = TRUE; return 0; } if (!tree2) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_DIR_DELETED, tree1, basedir); *results = g_list_prepend (*results, de); if (data->fold_dir_diff) { *recurse = FALSE; } else *recurse = TRUE; return 0; } return 0; } int diff_commits (SeafCommit *commit1, SeafCommit *commit2, GList **results, gboolean fold_dir_diff) { SeafRepo *repo = NULL; DiffOptions opt; const char *roots[2]; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, commit1->repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", commit1->repo_id); return -1; } DiffData data; memset (&data, 0, sizeof(data)); data.results = results; data.fold_dir_diff = fold_dir_diff; memset (&opt, 0, sizeof(opt)); #ifdef SEAFILE_SERVER memcpy (opt.store_id, repo->store_id, 36); #else memcpy (opt.store_id, repo->id, 36); #endif opt.version = repo->version; opt.file_cb = twoway_diff_files; opt.dir_cb = twoway_diff_dirs; opt.data = &data; #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif roots[0] = commit1->root_id; roots[1] = commit2->root_id; diff_trees (2, roots, &opt); diff_resolve_renames (results); return 0; } int diff_commit_roots (const char *store_id, int version, const char *root1, const char *root2, GList **results, gboolean fold_dir_diff) { DiffOptions opt; const char *roots[2]; DiffData data; memset (&data, 0, sizeof(data)); data.results = results; data.fold_dir_diff = fold_dir_diff; memset (&opt, 0, sizeof(opt)); memcpy (opt.store_id, store_id, 36); opt.version = version; opt.file_cb = twoway_diff_files; opt.dir_cb = twoway_diff_dirs; opt.data = &data; roots[0] = root1; roots[1] = root2; diff_trees (2, roots, &opt); diff_resolve_renames (results); return 0; } static int threeway_diff_files (int n, const char *basedir, SeafDirent *files[], void *vdata) { DiffData *data = vdata; SeafDirent *m = files[0]; SeafDirent *p1 = files[1]; SeafDirent *p2 = files[2]; GList **results = data->results; DiffEntry *de; /* diff m with both p1 and p2. */ if (m && p1 && p2) { if (!dirent_same(m, p1) && !dirent_same (m, p2)) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_MODIFIED, m, basedir); *results = g_list_prepend (*results, de); } } else if (!m && p1 && p2) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_DELETED, p1, basedir); *results = g_list_prepend (*results, de); } else if (m && !p1 && p2) { if (!dirent_same (m, p2)) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_MODIFIED, m, basedir); *results = g_list_prepend (*results, de); } } else if (m && p1 && !p2) { if (!dirent_same (m, p1)) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_MODIFIED, m, basedir); *results = g_list_prepend (*results, de); } } else if (m && !p1 && !p2) { de = diff_entry_new_from_dirent (DIFF_TYPE_COMMITS, DIFF_STATUS_ADDED, m, basedir); *results = g_list_prepend (*results, de); } /* Nothing to do for: * 1. !m && p1 && !p2; * 2. !m && !p1 && p2; * 3. !m && !p1 && !p2 (should not happen) */ return 0; } static int threeway_diff_dirs (int n, const char *basedir, SeafDirent *dirs[], void *vdata, gboolean *recurse) { *recurse = TRUE; return 0; } int diff_merge (SeafCommit *merge, GList **results, gboolean fold_dir_diff) { SeafRepo *repo = NULL; DiffOptions opt; const char *roots[3]; SeafCommit *parent1, *parent2; g_return_val_if_fail (*results == NULL, -1); g_return_val_if_fail (merge->parent_id != NULL && merge->second_parent_id != NULL, -1); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, merge->repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", merge->repo_id); return -1; } parent1 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, merge->parent_id); if (!parent1) { seaf_warning ("failed to find commit %s:%s.\n", repo->id, merge->parent_id); return -1; } parent2 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, merge->second_parent_id); if (!parent2) { seaf_warning ("failed to find commit %s:%s.\n", repo->id, merge->second_parent_id); seaf_commit_unref (parent1); return -1; } DiffData data; memset (&data, 0, sizeof(data)); data.results = results; data.fold_dir_diff = fold_dir_diff; memset (&opt, 0, sizeof(opt)); #ifdef SEAFILE_SERVER memcpy (opt.store_id, repo->store_id, 36); #else memcpy (opt.store_id, repo->id, 36); #endif opt.version = repo->version; opt.file_cb = threeway_diff_files; opt.dir_cb = threeway_diff_dirs; opt.data = &data; #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif roots[0] = merge->root_id; roots[1] = parent1->root_id; roots[2] = parent2->root_id; int ret = diff_trees (3, roots, &opt); diff_resolve_renames (results); seaf_commit_unref (parent1); seaf_commit_unref (parent2); return ret; } int diff_merge_roots (const char *store_id, int version, const char *merged_root, const char *p1_root, const char *p2_root, GList **results, gboolean fold_dir_diff) { DiffOptions opt; const char *roots[3]; g_return_val_if_fail (*results == NULL, -1); DiffData data; memset (&data, 0, sizeof(data)); data.results = results; data.fold_dir_diff = fold_dir_diff; memset (&opt, 0, sizeof(opt)); memcpy (opt.store_id, store_id, 36); opt.version = version; opt.file_cb = threeway_diff_files; opt.dir_cb = threeway_diff_dirs; opt.data = &data; roots[0] = merged_root; roots[1] = p1_root; roots[2] = p2_root; diff_trees (3, roots, &opt); diff_resolve_renames (results); return 0; } /* This function only resolve "strict" rename, i.e. two files must be * exactly the same. * Don't detect rename of empty files and empty dirs. */ void diff_resolve_renames (GList **diff_entries) { GHashTable *deleted; GList *p; GList *added = NULL; DiffEntry *de; unsigned char empty_sha1[20]; memset (empty_sha1, 0, 20); /* Hash and equal functions for raw sha1. */ deleted = g_hash_table_new (ccnet_sha1_hash, ccnet_sha1_equal); /* Collect all "deleted" entries. */ for (p = *diff_entries; p != NULL; p = p->next) { de = p->data; if ((de->status == DIFF_STATUS_DELETED || de->status == DIFF_STATUS_DIR_DELETED) && memcmp (de->sha1, empty_sha1, 20) != 0) g_hash_table_insert (deleted, de->sha1, p); } /* Collect all "added" entries into a separate list. */ for (p = *diff_entries; p != NULL; p = p->next) { de = p->data; if ((de->status == DIFF_STATUS_ADDED || de->status == DIFF_STATUS_DIR_ADDED) && memcmp (de->sha1, empty_sha1, 20) != 0) added = g_list_prepend (added, p); } /* For each "added" entry, if we find a "deleted" entry with * the same content, we find a rename pair. */ p = added; while (p != NULL) { GList *p_add, *p_del; DiffEntry *de_add, *de_del, *de_rename; int rename_status; p_add = p->data; de_add = p_add->data; p_del = g_hash_table_lookup (deleted, de_add->sha1); if (p_del) { de_del = p_del->data; if (de_add->status == DIFF_STATUS_DIR_ADDED) rename_status = DIFF_STATUS_DIR_RENAMED; else rename_status = DIFF_STATUS_RENAMED; de_rename = diff_entry_new (de_del->type, rename_status, de_del->sha1, de_del->name); de_rename->new_name = g_strdup(de_add->name); *diff_entries = g_list_delete_link (*diff_entries, p_add); *diff_entries = g_list_delete_link (*diff_entries, p_del); *diff_entries = g_list_prepend (*diff_entries, de_rename); g_hash_table_remove (deleted, de_add->sha1); diff_entry_free (de_add); diff_entry_free (de_del); } p = g_list_delete_link (p, p); } g_hash_table_destroy (deleted); } static gboolean is_redundant_empty_dir (DiffEntry *de_dir, DiffEntry *de_file) { int dir_len; if (de_dir->status == DIFF_STATUS_DIR_ADDED && de_file->status == DIFF_STATUS_DELETED) { dir_len = strlen (de_dir->name); if (strlen (de_file->name) > dir_len && strncmp (de_dir->name, de_file->name, dir_len) == 0) return TRUE; } if (de_dir->status == DIFF_STATUS_DIR_DELETED && de_file->status == DIFF_STATUS_ADDED) { dir_len = strlen (de_dir->name); if (strlen (de_file->name) > dir_len && strncmp (de_dir->name, de_file->name, dir_len) == 0) return TRUE; } return FALSE; } /* * An empty dir entry may be added by deleting all the files under it. * Similarly, an empty dir entry may be deleted by adding some file in it. * In both cases, we don't want to include the empty dir entry in the * diff results. */ void diff_resolve_empty_dirs (GList **diff_entries) { GList *empty_dirs = NULL; GList *p, *dir, *file; DiffEntry *de, *de_dir, *de_file; for (p = *diff_entries; p != NULL; p = p->next) { de = p->data; if (de->status == DIFF_STATUS_DIR_ADDED || de->status == DIFF_STATUS_DIR_DELETED) empty_dirs = g_list_prepend (empty_dirs, p); } for (dir = empty_dirs; dir != NULL; dir = dir->next) { de_dir = ((GList *)dir->data)->data; for (file = *diff_entries; file != NULL; file = file->next) { de_file = file->data; if (is_redundant_empty_dir (de_dir, de_file)) { *diff_entries = g_list_delete_link (*diff_entries, dir->data); break; } } } g_list_free (empty_dirs); } int diff_unmerged_state(int mask) { mask >>= 1; switch (mask) { case 7: return STATUS_UNMERGED_BOTH_CHANGED; case 3: return STATUS_UNMERGED_OTHERS_REMOVED; case 5: return STATUS_UNMERGED_I_REMOVED; case 6: return STATUS_UNMERGED_BOTH_ADDED; case 2: return STATUS_UNMERGED_DFC_I_ADDED_FILE; case 4: return STATUS_UNMERGED_DFC_OTHERS_ADDED_FILE; default: seaf_warning ("Unexpected unmerged case\n"); } return 0; } char * format_diff_results(GList *results) { GList *ptr; GString *fmt_status; DiffEntry *de; fmt_status = g_string_new(""); for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status != DIFF_STATUS_RENAMED) g_string_append_printf(fmt_status, "%c %c %d %u %s\n", de->type, de->status, de->unmerge_state, (int)strlen(de->name), de->name); else g_string_append_printf(fmt_status, "%c %c %d %u %s %u %s\n", de->type, de->status, de->unmerge_state, (int)strlen(de->name), de->name, (int)strlen(de->new_name), de->new_name); } return g_string_free(fmt_status, FALSE); } inline static char * get_basename (char *path) { char *slash; slash = strrchr (path, '/'); if (!slash) return path; return (slash + 1); } char * diff_results_to_description (GList *results) { GList *p; DiffEntry *de; char *add_mod_file = NULL, *removed_file = NULL; char *renamed_file = NULL; char *new_dir = NULL, *removed_dir = NULL; int n_add_mod = 0, n_removed = 0, n_renamed = 0; int n_new_dir = 0, n_removed_dir = 0; GString *desc; if (results == NULL) return NULL; for (p = results; p != NULL; p = p->next) { de = p->data; switch (de->status) { case DIFF_STATUS_ADDED: if (n_add_mod == 0) add_mod_file = get_basename(de->name); n_add_mod++; break; case DIFF_STATUS_DELETED: if (n_removed == 0) removed_file = get_basename(de->name); n_removed++; break; case DIFF_STATUS_RENAMED: if (n_renamed == 0) renamed_file = get_basename(de->name); n_renamed++; break; case DIFF_STATUS_MODIFIED: if (n_add_mod == 0) add_mod_file = get_basename(de->name); n_add_mod++; break; case DIFF_STATUS_DIR_ADDED: if (n_new_dir == 0) new_dir = get_basename(de->name); n_new_dir++; break; case DIFF_STATUS_DIR_DELETED: if (n_removed_dir == 0) removed_dir = get_basename(de->name); n_removed_dir++; break; } } desc = g_string_new (""); if (n_add_mod == 1) g_string_append_printf (desc, "Added or modified \"%s\".\n", add_mod_file); else if (n_add_mod > 1) g_string_append_printf (desc, "Added or modified \"%s\" and %d more files.\n", add_mod_file, n_add_mod - 1); if (n_removed == 1) g_string_append_printf (desc, "Deleted \"%s\".\n", removed_file); else if (n_removed > 1) g_string_append_printf (desc, "Deleted \"%s\" and %d more files.\n", removed_file, n_removed - 1); if (n_renamed == 1) g_string_append_printf (desc, "Renamed \"%s\".\n", renamed_file); else if (n_renamed > 1) g_string_append_printf (desc, "Renamed \"%s\" and %d more files.\n", renamed_file, n_renamed - 1); if (n_new_dir == 1) g_string_append_printf (desc, "Added directory \"%s\".\n", new_dir); else if (n_new_dir > 1) g_string_append_printf (desc, "Added \"%s\" and %d more directories.\n", new_dir, n_new_dir - 1); if (n_removed_dir == 1) g_string_append_printf (desc, "Removed directory \"%s\".\n", removed_dir); else if (n_removed_dir > 1) g_string_append_printf (desc, "Removed \"%s\" and %d more directories.\n", removed_dir, n_removed_dir - 1); return g_string_free (desc, FALSE); } seafile-6.1.5/common/diff-simple.h000066400000000000000000000073651323477647300170260ustar00rootroot00000000000000#ifndef DIFF_SIMPLE_H #define DIFF_SIMPLE_H #include #ifndef SEAFILE_SERVER #include "index/index.h" #endif #include "seafile-session.h" #define DIFF_TYPE_WORKTREE 'W' /* diff from index to worktree */ #define DIFF_TYPE_INDEX 'I' /* diff from commit to index */ #define DIFF_TYPE_COMMITS 'C' /* diff between two commits*/ #define DIFF_STATUS_ADDED 'A' #define DIFF_STATUS_DELETED 'D' #define DIFF_STATUS_MODIFIED 'M' #define DIFF_STATUS_RENAMED 'R' #define DIFF_STATUS_UNMERGED 'U' #define DIFF_STATUS_DIR_ADDED 'B' #define DIFF_STATUS_DIR_DELETED 'C' #define DIFF_STATUS_DIR_RENAMED 'E' enum { STATUS_UNMERGED_NONE, /* I and others modified the same file differently. */ STATUS_UNMERGED_BOTH_CHANGED, /* I and others created the same file with different contents. */ STATUS_UNMERGED_BOTH_ADDED, /* I removed a file while others modified it. */ STATUS_UNMERGED_I_REMOVED, /* Others removed a file while I modified it. */ STATUS_UNMERGED_OTHERS_REMOVED, /* I replace a directory with a file while others modified files under the directory. */ STATUS_UNMERGED_DFC_I_ADDED_FILE, /* Others replace a directory with a file while I modified files under the directory. */ STATUS_UNMERGED_DFC_OTHERS_ADDED_FILE, }; typedef struct DiffEntry { char type; char status; int unmerge_state; unsigned char sha1[20]; /* used for resolve rename */ char *name; char *new_name; /* only used in rename. */ #ifdef SEAFILE_CLIENT /* Fields only used for ADDED, DIR_ADDED, MODIFIED types, * used in check out files/dirs.*/ gint64 mtime; unsigned int mode; char *modifier; gint64 size; #endif } DiffEntry; DiffEntry * diff_entry_new (char type, char status, unsigned char *sha1, const char *name); void diff_entry_free (DiffEntry *de); #ifndef SEAFILE_SERVER int diff_index (const char *repo_id, int version, struct index_state *istate, SeafDir *root, GList **results); #endif /* * @fold_dir_diff: if TRUE, only the top level directory will be included * in the diff result if a directory with files is added or removed. * Otherwise all the files in the direcotory will be recursively * included in the diff result. */ int diff_commits (SeafCommit *commit1, SeafCommit *commit2, GList **results, gboolean fold_dir_diff); int diff_commit_roots (const char *store_id, int version, const char *root1, const char *root2, GList **results, gboolean fold_dir_diff); int diff_merge (SeafCommit *merge, GList **results, gboolean fold_dir_diff); int diff_merge_roots (const char *store_id, int version, const char *merged_root, const char *p1_root, const char *p2_root, GList **results, gboolean fold_dir_diff); void diff_resolve_renames (GList **diff_entries); void diff_resolve_empty_dirs (GList **diff_entries); int diff_unmerged_state(int mask); char * format_diff_results(GList *results); char * diff_results_to_description (GList *results); typedef int (*DiffFileCB) (int n, const char *basedir, SeafDirent *files[], void *data); typedef int (*DiffDirCB) (int n, const char *basedir, SeafDirent *dirs[], void *data, gboolean *recurse); typedef struct DiffOptions { char store_id[37]; int version; DiffFileCB file_cb; DiffDirCB dir_cb; void *data; } DiffOptions; int diff_trees (int n, const char *roots[], DiffOptions *opt); #endif seafile-6.1.5/common/fs-mgr.c000066400000000000000000002171171323477647300160130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #ifndef WIN32 #include #endif #include #include "seafile-session.h" #include "seafile-error.h" #include "fs-mgr.h" #include "block-mgr.h" #include "utils.h" #include "seaf-utils.h" #define DEBUG_FLAG SEAFILE_DEBUG_OTHER #include "log.h" #include "../common/seafile-crypt.h" #ifndef SEAFILE_SERVER #include "../daemon/vc-utils.h" #include "vc-common.h" #endif /* SEAFILE_SERVER */ #include "db.h" struct _SeafFSManagerPriv { /* GHashTable *seafile_cache; */ GHashTable *bl_cache; }; typedef struct SeafileOndisk { guint32 type; guint64 file_size; unsigned char block_ids[0]; } __attribute__((gcc_struct, __packed__)) SeafileOndisk; typedef struct DirentOndisk { guint32 mode; char id[40]; guint32 name_len; char name[0]; } __attribute__((gcc_struct, __packed__)) DirentOndisk; typedef struct SeafdirOndisk { guint32 type; char dirents[0]; } __attribute__((gcc_struct, __packed__)) SeafdirOndisk; #ifndef SEAFILE_SERVER uint32_t calculate_chunk_size (uint64_t total_size); static int write_seafile (SeafFSManager *fs_mgr, const char *repo_id, int version, CDCFileDescriptor *cdc, unsigned char *obj_sha1); #endif /* SEAFILE_SERVER */ SeafFSManager * seaf_fs_manager_new (SeafileSession *seaf, const char *seaf_dir) { SeafFSManager *mgr = g_new0 (SeafFSManager, 1); mgr->seaf = seaf; mgr->obj_store = seaf_obj_store_new (seaf, "fs"); if (!mgr->obj_store) { g_free (mgr); return NULL; } mgr->priv = g_new0(SeafFSManagerPriv, 1); return mgr; } int seaf_fs_manager_init (SeafFSManager *mgr) { #ifdef SEAFILE_SERVER #ifdef FULL_FEATURE if (seaf_obj_store_init (mgr->obj_store, TRUE, seaf->ev_mgr) < 0) { seaf_warning ("[fs mgr] Failed to init fs object store.\n"); return -1; } #else if (seaf_obj_store_init (mgr->obj_store, FALSE, NULL) < 0) { seaf_warning ("[fs mgr] Failed to init fs object store.\n"); return -1; } #endif #else if (seaf_obj_store_init (mgr->obj_store, TRUE, seaf->ev_mgr) < 0) { seaf_warning ("[fs mgr] Failed to init fs object store.\n"); return -1; } #endif return 0; } #ifndef SEAFILE_SERVER static int checkout_block (const char *repo_id, int version, const char *block_id, int wfd, SeafileCrypt *crypt) { SeafBlockManager *block_mgr = seaf->block_mgr; BlockHandle *handle; BlockMetadata *bmd; char *dec_out = NULL; int dec_out_len = -1; char *blk_content = NULL; handle = seaf_block_manager_open_block (block_mgr, repo_id, version, block_id, BLOCK_READ); if (!handle) { seaf_warning ("Failed to open block %s\n", block_id); return -1; } /* first stat the block to get its size */ bmd = seaf_block_manager_stat_block_by_handle (block_mgr, handle); if (!bmd) { seaf_warning ("can't stat block %s.\n", block_id); goto checkout_blk_error; } /* empty file, skip it */ if (bmd->size == 0) { seaf_block_manager_close_block (block_mgr, handle); seaf_block_manager_block_handle_free (block_mgr, handle); return 0; } blk_content = (char *)malloc (bmd->size * sizeof(char)); /* read the block to prepare decryption */ if (seaf_block_manager_read_block (block_mgr, handle, blk_content, bmd->size) != bmd->size) { seaf_warning ("Error when reading from block %s.\n", block_id); goto checkout_blk_error; } if (crypt != NULL) { /* An encrypted block size must be a multiple of ENCRYPT_BLK_SIZE */ if (bmd->size % ENCRYPT_BLK_SIZE != 0) { seaf_warning ("Error: An invalid encrypted block, %s \n", block_id); goto checkout_blk_error; } /* decrypt the block */ int ret = seafile_decrypt (&dec_out, &dec_out_len, blk_content, bmd->size, crypt); if (ret != 0) { seaf_warning ("Decryt block %s failed. \n", block_id); goto checkout_blk_error; } /* write the decrypted content */ ret = writen (wfd, dec_out, dec_out_len); if (ret != dec_out_len) { seaf_warning ("Failed to write the decryted block %s.\n", block_id); goto checkout_blk_error; } g_free (blk_content); g_free (dec_out); } else { /* not an encrypted block */ if (writen(wfd, blk_content, bmd->size) != bmd->size) { seaf_warning ("Failed to write the decryted block %s.\n", block_id); goto checkout_blk_error; } g_free (blk_content); } g_free (bmd); seaf_block_manager_close_block (block_mgr, handle); seaf_block_manager_block_handle_free (block_mgr, handle); return 0; checkout_blk_error: if (blk_content) free (blk_content); if (dec_out) g_free (dec_out); if (bmd) g_free (bmd); seaf_block_manager_close_block (block_mgr, handle); seaf_block_manager_block_handle_free (block_mgr, handle); return -1; } #define SEAF_TMP_EXT "~" #define SEAF_BACKUP_EXT ".sbak" /* * File updating procedure: * 1. Checkout server versioin to tmp file. * 2. If there is a local version, move it to a backup file. * 3. Rename the tmp file to the destination path. * 4. Remove the backup file if exists. */ int seaf_fs_manager_checkout_file (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id, const char *file_path, guint32 mode, guint64 mtime, SeafileCrypt *crypt, const char *in_repo_path, const char *conflict_head_id, gboolean force_conflict, gboolean *conflicted, const char *email) { Seafile *seafile = NULL; char *blk_id; int wfd = -1; int i; char *tmp_path = NULL; char *backup_path = NULL; char *conflict_path = NULL; *conflicted = FALSE; /* Check out server version to tmp file. */ seafile = seaf_fs_manager_get_seafile (mgr, repo_id, version, file_id); if (!seafile) { seaf_warning ("File %s does not exist.\n", file_id); return -1; } tmp_path = g_strconcat (file_path, SEAF_TMP_EXT, NULL); mode_t rmode = mode & 0100 ? 0777 : 0666; wfd = seaf_util_create (tmp_path, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, rmode & ~S_IFMT); if (wfd < 0) { seaf_warning ("Failed to open file %s for checkout: %s.\n", tmp_path, strerror(errno)); goto bad; } for (i = 0; i < seafile->n_blocks; ++i) { blk_id = seafile->blk_sha1s[i]; if (checkout_block (repo_id, version, blk_id, wfd, crypt) < 0) goto bad; } close (wfd); wfd = -1; /* Move existing file to backup file. */ backup_path = g_strconcat (file_path, SEAF_BACKUP_EXT, NULL); if (seaf_util_exists (file_path) && seaf_util_rename (file_path, backup_path) < 0) { seaf_warning ("Failed to rename %s to %s: %s. " "Checkout server version as conflict file.\n", file_path, backup_path, strerror(errno)); *conflicted = TRUE; conflict_path = gen_conflict_path_wrapper (repo_id, version, conflict_head_id, in_repo_path, file_path); if (!conflict_path) goto bad; if (seaf_util_rename (tmp_path, conflict_path) < 0) { goto bad; } goto out; } /* Now that the old existing file has been renamed to backup file, * this rename operation usually succeeds. */ if (seaf_util_rename (tmp_path, file_path) < 0) { seaf_warning ("Failed to rename %s to %s: %s. " "Checkout server version as conflict file.\n", tmp_path, file_path, strerror(errno)); *conflicted = TRUE; /* Restore the existing file. */ if (seaf_util_rename (backup_path, file_path) < 0) { seaf_warning ("Failed to rename %s to %s: %s. " "Failed to restore backup file.\n", backup_path, file_path, strerror(errno)); } conflict_path = gen_conflict_path_wrapper (repo_id, version, conflict_head_id, in_repo_path, file_path); if (!conflict_path) goto bad; if (seaf_util_rename (tmp_path, conflict_path) < 0) { goto bad; } goto out; } if (force_conflict) { *conflicted = TRUE; /* XXX * In new syncing protocol and http sync, files are checked out before * the repo is created. So we can't get user email from repo at this point. * So a email parameter is needed. * For old syncing protocol, repo always exists when files are checked out. * This is a quick and dirty hack. A cleaner solution should modifiy the * code of old syncing protocol to pass in email too. But I don't want to * spend more time on the nearly obsoleted code. */ const char *suffix = NULL; if (email) { suffix = email; } else { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) goto bad; suffix = email; } conflict_path = gen_conflict_path (file_path, suffix, (gint64)time(NULL)); if (seaf_util_exists (backup_path) && seaf_util_rename (backup_path, conflict_path) < 0) { seaf_warning ("Failed to rename %s to %s: %s. " "Failed to move backup file to conflict file.\n", backup_path, conflict_path, strerror(errno)); } } if (mtime > 0) { /* * Set the checked out file mtime to what it has to be. */ if (seaf_set_file_time (file_path, mtime) < 0) { seaf_warning ("Failed to set mtime for %s.\n", file_path); } } seaf_util_unlink (backup_path); out: g_free (tmp_path); g_free (backup_path); g_free (conflict_path); seafile_unref (seafile); return 0; bad: if (wfd >= 0) close (wfd); /* Remove the tmp file if it still exists, in case that rename fails. */ seaf_util_unlink (tmp_path); g_free (tmp_path); g_free (backup_path); g_free (conflict_path); seafile_unref (seafile); return -1; } #endif /* SEAFILE_SERVER */ static void * create_seafile_v0 (CDCFileDescriptor *cdc, int *ondisk_size, char *seafile_id) { SeafileOndisk *ondisk; rawdata_to_hex (cdc->file_sum, seafile_id, 20); *ondisk_size = sizeof(SeafileOndisk) + cdc->block_nr * 20; ondisk = (SeafileOndisk *)g_new0 (char, *ondisk_size); ondisk->type = htonl(SEAF_METADATA_TYPE_FILE); ondisk->file_size = hton64 (cdc->file_size); memcpy (ondisk->block_ids, cdc->blk_sha1s, cdc->block_nr * 20); return ondisk; } static void * create_seafile_json (int repo_version, CDCFileDescriptor *cdc, int *ondisk_size, char *seafile_id) { json_t *object, *block_id_array; object = json_object (); json_object_set_int_member (object, "type", SEAF_METADATA_TYPE_FILE); json_object_set_int_member (object, "version", seafile_version_from_repo_version(repo_version)); json_object_set_int_member (object, "size", cdc->file_size); block_id_array = json_array (); int i; uint8_t *ptr = cdc->blk_sha1s; char block_id[41]; for (i = 0; i < cdc->block_nr; ++i) { rawdata_to_hex (ptr, block_id, 20); json_array_append_new (block_id_array, json_string(block_id)); ptr += 20; } json_object_set_new (object, "block_ids", block_id_array); char *data = json_dumps (object, JSON_SORT_KEYS); *ondisk_size = strlen(data); /* The seafile object id is sha1 hash of the json object. */ unsigned char sha1[20]; calculate_sha1 (sha1, data, *ondisk_size); rawdata_to_hex (sha1, seafile_id, 20); json_decref (object); return data; } void seaf_fs_manager_calculate_seafile_id_json (int repo_version, CDCFileDescriptor *cdc, guint8 *file_id_sha1) { json_t *object, *block_id_array; object = json_object (); json_object_set_int_member (object, "type", SEAF_METADATA_TYPE_FILE); json_object_set_int_member (object, "version", seafile_version_from_repo_version(repo_version)); json_object_set_int_member (object, "size", cdc->file_size); block_id_array = json_array (); int i; uint8_t *ptr = cdc->blk_sha1s; char block_id[41]; for (i = 0; i < cdc->block_nr; ++i) { rawdata_to_hex (ptr, block_id, 20); json_array_append_new (block_id_array, json_string(block_id)); ptr += 20; } json_object_set_new (object, "block_ids", block_id_array); char *data = json_dumps (object, JSON_SORT_KEYS); int ondisk_size = strlen(data); /* The seafile object id is sha1 hash of the json object. */ calculate_sha1 (file_id_sha1, data, ondisk_size); json_decref (object); free (data); } static int write_seafile (SeafFSManager *fs_mgr, const char *repo_id, int version, CDCFileDescriptor *cdc, unsigned char *obj_sha1) { int ret = 0; char seafile_id[41]; void *ondisk; int ondisk_size; if (version > 0) { ondisk = create_seafile_json (version, cdc, &ondisk_size, seafile_id); guint8 *compressed; int outlen; if (seaf_compress (ondisk, ondisk_size, &compressed, &outlen) < 0) { seaf_warning ("Failed to compress seafile obj %s:%s.\n", repo_id, seafile_id); ret = -1; free (ondisk); goto out; } if (seaf_obj_store_write_obj (fs_mgr->obj_store, repo_id, version, seafile_id, compressed, outlen, FALSE) < 0) ret = -1; g_free (compressed); free (ondisk); } else { ondisk = create_seafile_v0 (cdc, &ondisk_size, seafile_id); if (seaf_obj_store_write_obj (fs_mgr->obj_store, repo_id, version, seafile_id, ondisk, ondisk_size, FALSE) < 0) ret = -1; g_free (ondisk); } out: if (ret == 0) hex_to_rawdata (seafile_id, obj_sha1, 20); return ret; } uint32_t calculate_chunk_size (uint64_t total_size) { const uint64_t GiB = 1073741824; const uint64_t MiB = 1048576; if (total_size >= (8 * GiB)) return 8 * MiB; if (total_size >= (4 * GiB)) return 4 * MiB; if (total_size >= (2 * GiB)) return 2 * MiB; return 1 * MiB; } static int do_write_chunk (const char *repo_id, int version, uint8_t *checksum, const char *buf, int len) { SeafBlockManager *blk_mgr = seaf->block_mgr; char chksum_str[41]; BlockHandle *handle; int n; rawdata_to_hex (checksum, chksum_str, 20); /* Don't write if the block already exists. */ if (seaf_block_manager_block_exists (seaf->block_mgr, repo_id, version, chksum_str)) return 0; handle = seaf_block_manager_open_block (blk_mgr, repo_id, version, chksum_str, BLOCK_WRITE); if (!handle) { seaf_warning ("Failed to open block %s.\n", chksum_str); return -1; } n = seaf_block_manager_write_block (blk_mgr, handle, buf, len); if (n < 0) { seaf_warning ("Failed to write chunk %s.\n", chksum_str); seaf_block_manager_close_block (blk_mgr, handle); seaf_block_manager_block_handle_free (blk_mgr, handle); return -1; } if (seaf_block_manager_close_block (blk_mgr, handle) < 0) { seaf_warning ("failed to close block %s.\n", chksum_str); seaf_block_manager_block_handle_free (blk_mgr, handle); return -1; } if (seaf_block_manager_commit_block (blk_mgr, handle) < 0) { seaf_warning ("failed to commit chunk %s.\n", chksum_str); seaf_block_manager_block_handle_free (blk_mgr, handle); return -1; } seaf_block_manager_block_handle_free (blk_mgr, handle); return 0; } /* write the chunk and store its checksum */ int seafile_write_chunk (const char *repo_id, int version, CDCDescriptor *chunk, SeafileCrypt *crypt, uint8_t *checksum, gboolean write_data) { GChecksum *ctx = g_checksum_new (G_CHECKSUM_SHA1); gsize len = 20; int ret = 0; /* Encrypt before write to disk if needed, and we don't encrypt * empty files. */ if (crypt != NULL && chunk->len) { char *encrypted_buf = NULL; /* encrypted output */ int enc_len = -1; /* encrypted length */ ret = seafile_encrypt (&encrypted_buf, /* output */ &enc_len, /* output len */ chunk->block_buf, /* input */ chunk->len, /* input len */ crypt); if (ret != 0) { seaf_warning ("Error: failed to encrypt block\n"); g_checksum_free (ctx); return -1; } g_checksum_update (ctx, (unsigned char *)encrypted_buf, enc_len); g_checksum_get_digest (ctx, checksum, &len); if (write_data) ret = do_write_chunk (repo_id, version, checksum, encrypted_buf, enc_len); g_free (encrypted_buf); } else { /* not a encrypted repo, go ahead */ g_checksum_update (ctx, (unsigned char *)chunk->block_buf, chunk->len); g_checksum_get_digest (ctx, checksum, &len); if (write_data) ret = do_write_chunk (repo_id, version, checksum, chunk->block_buf, chunk->len); } g_checksum_free (ctx); return ret; } static void create_cdc_for_empty_file (CDCFileDescriptor *cdc) { memset (cdc, 0, sizeof(CDCFileDescriptor)); } int seaf_fs_manager_index_blocks (SeafFSManager *mgr, const char *repo_id, int version, const char *file_path, unsigned char sha1[], gint64 *size, SeafileCrypt *crypt, gboolean write_data, gboolean use_cdc) { SeafStat sb; CDCFileDescriptor cdc; if (seaf_stat (file_path, &sb) < 0) { seaf_warning ("Bad file %s: %s.\n", file_path, strerror(errno)); return -1; } g_return_val_if_fail (S_ISREG(sb.st_mode), -1); if (sb.st_size == 0) { /* handle empty file. */ memset (sha1, 0, 20); create_cdc_for_empty_file (&cdc); } else { memset (&cdc, 0, sizeof(cdc)); cdc.block_sz = CDC_AVERAGE_BLOCK_SIZE; cdc.block_min_sz = CDC_MIN_BLOCK_SIZE; cdc.block_max_sz = CDC_MAX_BLOCK_SIZE; cdc.write_block = seafile_write_chunk; memcpy (cdc.repo_id, repo_id, 36); cdc.version = version; if (filename_chunk_cdc (file_path, &cdc, crypt, write_data) < 0) { seaf_warning ("Failed to chunk file with CDC.\n"); return -1; } if (write_data && write_seafile (mgr, repo_id, version, &cdc, sha1) < 0) { g_free (cdc.blk_sha1s); seaf_warning ("Failed to write seafile for %s.\n", file_path); return -1; } } *size = (gint64)sb.st_size; if (cdc.blk_sha1s) free (cdc.blk_sha1s); return 0; } void seafile_ref (Seafile *seafile) { ++seafile->ref_count; } static void seafile_free (Seafile *seafile) { int i; if (seafile->blk_sha1s) { for (i = 0; i < seafile->n_blocks; ++i) g_free (seafile->blk_sha1s[i]); g_free (seafile->blk_sha1s); } g_free (seafile); } void seafile_unref (Seafile *seafile) { if (!seafile) return; if (--seafile->ref_count <= 0) seafile_free (seafile); } static Seafile * seafile_from_v0_data (const char *id, const void *data, int len) { const SeafileOndisk *ondisk = data; Seafile *seafile; int id_list_len, n_blocks; if (len < sizeof(SeafileOndisk)) { seaf_warning ("[fs mgr] Corrupt seafile object %s.\n", id); return NULL; } if (ntohl(ondisk->type) != SEAF_METADATA_TYPE_FILE) { seaf_warning ("[fd mgr] %s is not a file.\n", id); return NULL; } id_list_len = len - sizeof(SeafileOndisk); if (id_list_len % 20 != 0) { seaf_warning ("[fs mgr] Corrupt seafile object %s.\n", id); return NULL; } n_blocks = id_list_len / 20; seafile = g_new0 (Seafile, 1); seafile->object.type = SEAF_METADATA_TYPE_FILE; seafile->version = 0; memcpy (seafile->file_id, id, 41); seafile->file_size = ntoh64 (ondisk->file_size); seafile->n_blocks = n_blocks; seafile->blk_sha1s = g_new0 (char*, seafile->n_blocks); const unsigned char *blk_sha1_ptr = ondisk->block_ids; int i; for (i = 0; i < seafile->n_blocks; ++i) { char *blk_sha1 = g_new0 (char, 41); seafile->blk_sha1s[i] = blk_sha1; rawdata_to_hex (blk_sha1_ptr, blk_sha1, 20); blk_sha1_ptr += 20; } seafile->ref_count = 1; return seafile; } static Seafile * seafile_from_json_object (const char *id, json_t *object) { json_t *block_id_array = NULL; int type; int version; guint64 file_size; Seafile *seafile = NULL; /* Sanity checks. */ type = json_object_get_int_member (object, "type"); if (type != SEAF_METADATA_TYPE_FILE) { seaf_debug ("Object %s is not a file.\n", id); return NULL; } version = (int) json_object_get_int_member (object, "version"); if (version < 1) { seaf_debug ("Seafile object %s version should be > 0, version is %d.\n", id, version); return NULL; } file_size = (guint64) json_object_get_int_member (object, "size"); block_id_array = json_object_get (object, "block_ids"); if (!block_id_array) { seaf_debug ("No block id array in seafile object %s.\n", id); return NULL; } seafile = g_new0 (Seafile, 1); seafile->object.type = SEAF_METADATA_TYPE_FILE; memcpy (seafile->file_id, id, 40); seafile->version = version; seafile->file_size = file_size; seafile->n_blocks = json_array_size (block_id_array); seafile->blk_sha1s = g_new0 (char *, seafile->n_blocks); int i; json_t *block_id_obj; const char *block_id; for (i = 0; i < seafile->n_blocks; ++i) { block_id_obj = json_array_get (block_id_array, i); block_id = json_string_value (block_id_obj); if (!block_id || !is_object_id_valid(block_id)) { seafile_free (seafile); return NULL; } seafile->blk_sha1s[i] = g_strdup(block_id); } seafile->ref_count = 1; return seafile; } static Seafile * seafile_from_json (const char *id, void *data, int len) { guint8 *decompressed; int outlen; json_t *object = NULL; json_error_t error; Seafile *seafile; if (seaf_decompress (data, len, &decompressed, &outlen) < 0) { seaf_warning ("Failed to decompress seafile object %s.\n", id); return NULL; } object = json_loadb ((const char *)decompressed, outlen, 0, &error); g_free (decompressed); if (!object) { seaf_warning ("Failed to load seafile json object: %s.\n", error.text); return NULL; } seafile = seafile_from_json_object (id, object); json_decref (object); return seafile; } static Seafile * seafile_from_data (const char *id, void *data, int len, gboolean is_json) { if (is_json) return seafile_from_json (id, data, len); else return seafile_from_v0_data (id, data, len); } Seafile * seaf_fs_manager_get_seafile (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id) { void *data; int len; Seafile *seafile; #if 0 seafile = g_hash_table_lookup (mgr->priv->seafile_cache, file_id); if (seafile) { seafile_ref (seafile); return seafile; } #endif if (memcmp (file_id, EMPTY_SHA1, 40) == 0) { seafile = g_new0 (Seafile, 1); memset (seafile->file_id, '0', 40); seafile->ref_count = 1; return seafile; } if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, file_id, &data, &len) < 0) { seaf_warning ("[fs mgr] Failed to read file %s.\n", file_id); return NULL; } seafile = seafile_from_data (file_id, data, len, (version > 0)); g_free (data); #if 0 /* * Add to cache. Also increase ref count. */ seafile_ref (seafile); g_hash_table_insert (mgr->priv->seafile_cache, g_strdup(file_id), seafile); #endif return seafile; } static guint8 * seafile_to_v0_data (Seafile *file, int *len) { SeafileOndisk *ondisk; *len = sizeof(SeafileOndisk) + file->n_blocks * 20; ondisk = (SeafileOndisk *)g_new0 (char, *len); ondisk->type = htonl(SEAF_METADATA_TYPE_FILE); ondisk->file_size = hton64 (file->file_size); guint8 *ptr = ondisk->block_ids; int i; for (i = 0; i < file->n_blocks; ++i) { hex_to_rawdata (file->blk_sha1s[i], ptr, 20); ptr += 20; } return (guint8 *)ondisk; } static guint8 * seafile_to_json (Seafile *file, int *len) { json_t *object, *block_id_array; object = json_object (); json_object_set_int_member (object, "type", SEAF_METADATA_TYPE_FILE); json_object_set_int_member (object, "version", file->version); json_object_set_int_member (object, "size", file->file_size); block_id_array = json_array (); int i; for (i = 0; i < file->n_blocks; ++i) { json_array_append_new (block_id_array, json_string(file->blk_sha1s[i])); } json_object_set_new (object, "block_ids", block_id_array); char *data = json_dumps (object, JSON_SORT_KEYS); *len = strlen(data); unsigned char sha1[20]; calculate_sha1 (sha1, data, *len); rawdata_to_hex (sha1, file->file_id, 20); json_decref (object); return (guint8 *)data; } static guint8 * seafile_to_data (Seafile *file, int *len) { if (file->version > 0) { guint8 *data; int orig_len; guint8 *compressed; data = seafile_to_json (file, &orig_len); if (!data) return NULL; if (seaf_compress (data, orig_len, &compressed, len) < 0) { seaf_warning ("Failed to compress file object %s.\n", file->file_id); g_free (data); return NULL; } g_free (data); return compressed; } else return seafile_to_v0_data (file, len); } int seafile_save (SeafFSManager *fs_mgr, const char *repo_id, int version, Seafile *file) { guint8 *data; int len; int ret = 0; data = seafile_to_data (file, &len); if (!data) return -1; if (seaf_obj_store_write_obj (fs_mgr->obj_store, repo_id, version, file->file_id, data, len, FALSE) < 0) ret = -1; g_free (data); return ret; } static void compute_dir_id_v0 (SeafDir *dir, GList *entries) { GChecksum *ctx; GList *p; uint8_t sha1[20]; gsize len = 20; SeafDirent *dent; guint32 mode_le; /* ID for empty dirs is EMPTY_SHA1. */ if (entries == NULL) { memset (dir->dir_id, '0', 40); return; } ctx = g_checksum_new (G_CHECKSUM_SHA1); for (p = entries; p; p = p->next) { dent = (SeafDirent *)p->data; g_checksum_update (ctx, (unsigned char *)dent->id, 40); g_checksum_update (ctx, (unsigned char *)dent->name, dent->name_len); /* Convert mode to little endian before compute. */ if (G_BYTE_ORDER == G_BIG_ENDIAN) mode_le = GUINT32_SWAP_LE_BE (dent->mode); else mode_le = dent->mode; g_checksum_update (ctx, (unsigned char *)&mode_le, sizeof(mode_le)); } g_checksum_get_digest (ctx, sha1, &len); rawdata_to_hex (sha1, dir->dir_id, 20); } SeafDir * seaf_dir_new (const char *id, GList *entries, int version) { SeafDir *dir; dir = g_new0(SeafDir, 1); dir->version = version; if (id != NULL) { memcpy(dir->dir_id, id, 40); dir->dir_id[40] = '\0'; } else if (version == 0) { compute_dir_id_v0 (dir, entries); } dir->entries = entries; if (dir->entries != NULL) dir->ondisk = seaf_dir_to_data (dir, &dir->ondisk_size); else memcpy (dir->dir_id, EMPTY_SHA1, 40); return dir; } void seaf_dir_free (SeafDir *dir) { if (dir == NULL) return; GList *ptr = dir->entries; while (ptr) { seaf_dirent_free ((SeafDirent *)ptr->data); ptr = ptr->next; } g_list_free (dir->entries); g_free (dir->ondisk); g_free(dir); } SeafDirent * seaf_dirent_new (int version, const char *sha1, int mode, const char *name, gint64 mtime, const char *modifier, gint64 size) { SeafDirent *dent; dent = g_new0 (SeafDirent, 1); dent->version = version; memcpy(dent->id, sha1, 40); dent->id[40] = '\0'; /* Mode for files must have 0644 set. To prevent the caller from forgetting, * we set the bits here. */ if (S_ISREG(mode)) dent->mode = (mode | 0644); else dent->mode = mode; dent->name = g_strdup(name); dent->name_len = strlen(name); if (version > 0) { dent->mtime = mtime; if (S_ISREG(mode)) { dent->modifier = g_strdup(modifier); dent->size = size; } } return dent; } void seaf_dirent_free (SeafDirent *dent) { if (!dent) return; g_free (dent->name); g_free (dent->modifier); g_free (dent); } SeafDirent * seaf_dirent_dup (SeafDirent *dent) { SeafDirent *new_dent; new_dent = g_memdup (dent, sizeof(SeafDirent)); new_dent->name = g_strdup(dent->name); new_dent->modifier = g_strdup(dent->modifier); return new_dent; } static SeafDir * seaf_dir_from_v0_data (const char *dir_id, const uint8_t *data, int len) { SeafDir *root; SeafDirent *dent; const uint8_t *ptr; int remain; int dirent_base_size; guint32 meta_type; guint32 name_len; ptr = data; remain = len; meta_type = get32bit (&ptr); remain -= 4; if (meta_type != SEAF_METADATA_TYPE_DIR) { seaf_warning ("Data does not contain a directory.\n"); return NULL; } root = g_new0(SeafDir, 1); root->object.type = SEAF_METADATA_TYPE_DIR; root->version = 0; memcpy(root->dir_id, dir_id, 40); root->dir_id[40] = '\0'; dirent_base_size = 2 * sizeof(guint32) + 40; while (remain > dirent_base_size) { dent = g_new0(SeafDirent, 1); dent->version = 0; dent->mode = get32bit (&ptr); memcpy (dent->id, ptr, 40); dent->id[40] = '\0'; ptr += 40; name_len = get32bit (&ptr); remain -= dirent_base_size; if (remain >= name_len) { dent->name_len = MIN (name_len, SEAF_DIR_NAME_LEN - 1); dent->name = g_strndup((const char *)ptr, dent->name_len); ptr += dent->name_len; remain -= dent->name_len; } else { seaf_warning ("Bad data format for dir objcet %s.\n", dir_id); g_free (dent); goto bad; } root->entries = g_list_prepend (root->entries, dent); } root->entries = g_list_reverse (root->entries); return root; bad: seaf_dir_free (root); return NULL; } static SeafDirent * parse_dirent (const char *dir_id, int version, json_t *object) { guint32 mode; const char *id; const char *name; gint64 mtime; const char *modifier; gint64 size; mode = (guint32) json_object_get_int_member (object, "mode"); id = json_object_get_string_member (object, "id"); if (!id) { seaf_debug ("Dirent id not set for dir object %s.\n", dir_id); return NULL; } if (!is_object_id_valid (id)) { seaf_debug ("Dirent id is invalid for dir object %s.\n", dir_id); return NULL; } name = json_object_get_string_member (object, "name"); if (!name) { seaf_debug ("Dirent name not set for dir object %s.\n", dir_id); return NULL; } mtime = json_object_get_int_member (object, "mtime"); if (S_ISREG(mode)) { modifier = json_object_get_string_member (object, "modifier"); if (!modifier) { seaf_debug ("Dirent modifier not set for dir object %s.\n", dir_id); return NULL; } size = json_object_get_int_member (object, "size"); } SeafDirent *dirent = g_new0 (SeafDirent, 1); dirent->version = version; dirent->mode = mode; memcpy (dirent->id, id, 40); dirent->name_len = strlen(name); dirent->name = g_strdup(name); dirent->mtime = mtime; if (S_ISREG(mode)) { dirent->modifier = g_strdup(modifier); dirent->size = size; } return dirent; } static SeafDir * seaf_dir_from_json_object (const char *dir_id, json_t *object) { json_t *dirent_array = NULL; int type; int version; SeafDir *dir = NULL; /* Sanity checks. */ type = json_object_get_int_member (object, "type"); if (type != SEAF_METADATA_TYPE_DIR) { seaf_debug ("Object %s is not a dir.\n", dir_id); return NULL; } version = (int) json_object_get_int_member (object, "version"); if (version < 1) { seaf_debug ("Dir object %s version should be > 0, version is %d.\n", dir_id, version); return NULL; } dirent_array = json_object_get (object, "dirents"); if (!dirent_array) { seaf_debug ("No dirents in dir object %s.\n", dir_id); return NULL; } dir = g_new0 (SeafDir, 1); dir->object.type = SEAF_METADATA_TYPE_DIR; memcpy (dir->dir_id, dir_id, 40); dir->version = version; size_t n_dirents = json_array_size (dirent_array); int i; json_t *dirent_obj; SeafDirent *dirent; for (i = 0; i < n_dirents; ++i) { dirent_obj = json_array_get (dirent_array, i); dirent = parse_dirent (dir_id, version, dirent_obj); if (!dirent) { seaf_dir_free (dir); return NULL; } dir->entries = g_list_prepend (dir->entries, dirent); } dir->entries = g_list_reverse (dir->entries); return dir; } static SeafDir * seaf_dir_from_json (const char *dir_id, uint8_t *data, int len) { guint8 *decompressed; int outlen; json_t *object = NULL; json_error_t error; SeafDir *dir; if (seaf_decompress (data, len, &decompressed, &outlen) < 0) { seaf_warning ("Failed to decompress dir object %s.\n", dir_id); return NULL; } object = json_loadb ((const char *)decompressed, outlen, 0, &error); g_free (decompressed); if (!object) { seaf_warning ("Failed to load seafdir json object: %s.\n", error.text); return NULL; } dir = seaf_dir_from_json_object (dir_id, object); json_decref (object); return dir; } SeafDir * seaf_dir_from_data (const char *dir_id, uint8_t *data, int len, gboolean is_json) { if (is_json) return seaf_dir_from_json (dir_id, data, len); else return seaf_dir_from_v0_data (dir_id, data, len); } inline static int ondisk_dirent_size (SeafDirent *dirent) { return sizeof(DirentOndisk) + dirent->name_len; } static void * seaf_dir_to_v0_data (SeafDir *dir, int *len) { SeafdirOndisk *ondisk; int dir_ondisk_size = sizeof(SeafdirOndisk); GList *dirents = dir->entries; GList *ptr; SeafDirent *de; char *p; DirentOndisk *de_ondisk; for (ptr = dirents; ptr; ptr = ptr->next) { de = ptr->data; dir_ondisk_size += ondisk_dirent_size (de); } *len = dir_ondisk_size; ondisk = (SeafdirOndisk *) g_new0 (char, dir_ondisk_size); ondisk->type = htonl (SEAF_METADATA_TYPE_DIR); p = ondisk->dirents; for (ptr = dirents; ptr; ptr = ptr->next) { de = ptr->data; de_ondisk = (DirentOndisk *) p; de_ondisk->mode = htonl(de->mode); memcpy (de_ondisk->id, de->id, 40); de_ondisk->name_len = htonl (de->name_len); memcpy (de_ondisk->name, de->name, de->name_len); p += ondisk_dirent_size (de); } return (void *)ondisk; } static void add_to_dirent_array (json_t *array, SeafDirent *dirent) { json_t *object; object = json_object (); json_object_set_int_member (object, "mode", dirent->mode); json_object_set_string_member (object, "id", dirent->id); json_object_set_string_member (object, "name", dirent->name); json_object_set_int_member (object, "mtime", dirent->mtime); if (S_ISREG(dirent->mode)) { json_object_set_string_member (object, "modifier", dirent->modifier); json_object_set_int_member (object, "size", dirent->size); } json_array_append_new (array, object); } static void * seaf_dir_to_json (SeafDir *dir, int *len) { json_t *object, *dirent_array; GList *ptr; SeafDirent *dirent; object = json_object (); json_object_set_int_member (object, "type", SEAF_METADATA_TYPE_DIR); json_object_set_int_member (object, "version", dir->version); dirent_array = json_array (); for (ptr = dir->entries; ptr; ptr = ptr->next) { dirent = ptr->data; add_to_dirent_array (dirent_array, dirent); } json_object_set_new (object, "dirents", dirent_array); char *data = json_dumps (object, JSON_SORT_KEYS); *len = strlen(data); /* The dir object id is sha1 hash of the json object. */ unsigned char sha1[20]; calculate_sha1 (sha1, data, *len); rawdata_to_hex (sha1, dir->dir_id, 20); json_decref (object); return data; } void * seaf_dir_to_data (SeafDir *dir, int *len) { if (dir->version > 0) { guint8 *data; int orig_len; guint8 *compressed; data = seaf_dir_to_json (dir, &orig_len); if (!data) return NULL; if (seaf_compress (data, orig_len, &compressed, len) < 0) { seaf_warning ("Failed to compress dir object %s.\n", dir->dir_id); g_free (data); return NULL; } g_free (data); return compressed; } else return seaf_dir_to_v0_data (dir, len); } int seaf_dir_save (SeafFSManager *fs_mgr, const char *repo_id, int version, SeafDir *dir) { int ret = 0; /* Don't need to save empty dir on disk. */ if (memcmp (dir->dir_id, EMPTY_SHA1, 40) == 0) return 0; if (seaf_obj_store_write_obj (fs_mgr->obj_store, repo_id, version, dir->dir_id, dir->ondisk, dir->ondisk_size, FALSE) < 0) ret = -1; return ret; } SeafDir * seaf_fs_manager_get_seafdir (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id) { void *data; int len; SeafDir *dir; /* TODO: add hash cache */ if (memcmp (dir_id, EMPTY_SHA1, 40) == 0) { dir = g_new0 (SeafDir, 1); dir->version = version; memset (dir->dir_id, '0', 40); return dir; } if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, dir_id, &data, &len) < 0) { seaf_warning ("[fs mgr] Failed to read dir %s.\n", dir_id); return NULL; } dir = seaf_dir_from_data (dir_id, data, len, (version > 0)); g_free (data); return dir; } static gint compare_dirents (gconstpointer a, gconstpointer b) { const SeafDirent *denta = a, *dentb = b; return strcmp (dentb->name, denta->name); } static gboolean is_dirents_sorted (GList *dirents) { GList *ptr; SeafDirent *dent, *dent_n; gboolean ret = TRUE; for (ptr = dirents; ptr != NULL; ptr = ptr->next) { dent = ptr->data; if (!ptr->next) break; dent_n = ptr->next->data; /* If dirents are not sorted in descending order, return FALSE. */ if (strcmp (dent->name, dent_n->name) < 0) { ret = FALSE; break; } } return ret; } SeafDir * seaf_fs_manager_get_seafdir_sorted (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id) { SeafDir *dir = seaf_fs_manager_get_seafdir(mgr, repo_id, version, dir_id); if (!dir) return NULL; /* Only some very old dir objects are not sorted. */ if (version > 0) return dir; if (!is_dirents_sorted (dir->entries)) dir->entries = g_list_sort (dir->entries, compare_dirents); return dir; } SeafDir * seaf_fs_manager_get_seafdir_sorted_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path) { SeafDir *dir = seaf_fs_manager_get_seafdir_by_path (mgr, repo_id, version, root_id, path, NULL); if (!dir) return NULL; /* Only some very old dir objects are not sorted. */ if (version > 0) return dir; if (!is_dirents_sorted (dir->entries)) dir->entries = g_list_sort (dir->entries, compare_dirents); return dir; } static int parse_metadata_type_v0 (const uint8_t *data, int len) { const uint8_t *ptr = data; if (len < sizeof(guint32)) return SEAF_METADATA_TYPE_INVALID; return (int)(get32bit(&ptr)); } static int parse_metadata_type_json (const char *obj_id, uint8_t *data, int len) { guint8 *decompressed; int outlen; json_t *object; json_error_t error; int type; if (seaf_decompress (data, len, &decompressed, &outlen) < 0) { seaf_warning ("Failed to decompress fs object %s.\n", obj_id); return SEAF_METADATA_TYPE_INVALID; } object = json_loadb ((const char *)decompressed, outlen, 0, &error); g_free (decompressed); if (!object) { seaf_warning ("Failed to load fs json object: %s.\n", error.text); return SEAF_METADATA_TYPE_INVALID; } type = json_object_get_int_member (object, "type"); json_decref (object); return type; } int seaf_metadata_type_from_data (const char *obj_id, uint8_t *data, int len, gboolean is_json) { if (is_json) return parse_metadata_type_json (obj_id, data, len); else return parse_metadata_type_v0 (data, len); } SeafFSObject * fs_object_from_v0_data (const char *obj_id, const uint8_t *data, int len) { int type = parse_metadata_type_v0 (data, len); if (type == SEAF_METADATA_TYPE_FILE) return (SeafFSObject *)seafile_from_v0_data (obj_id, data, len); else if (type == SEAF_METADATA_TYPE_DIR) return (SeafFSObject *)seaf_dir_from_v0_data (obj_id, data, len); else { seaf_warning ("Invalid object type %d.\n", type); return NULL; } } SeafFSObject * fs_object_from_json (const char *obj_id, uint8_t *data, int len) { guint8 *decompressed; int outlen; json_t *object; json_error_t error; int type; SeafFSObject *fs_obj; if (seaf_decompress (data, len, &decompressed, &outlen) < 0) { seaf_warning ("Failed to decompress fs object %s.\n", obj_id); return NULL; } object = json_loadb ((const char *)decompressed, outlen, 0, &error); g_free (decompressed); if (!object) { seaf_warning ("Failed to load fs json object: %s.\n", error.text); return NULL; } type = json_object_get_int_member (object, "type"); if (type == SEAF_METADATA_TYPE_FILE) fs_obj = (SeafFSObject *)seafile_from_json_object (obj_id, object); else if (type == SEAF_METADATA_TYPE_DIR) fs_obj = (SeafFSObject *)seaf_dir_from_json_object (obj_id, object); else { seaf_warning ("Invalid fs type %d.\n", type); json_decref (object); return NULL; } json_decref (object); return fs_obj; } SeafFSObject * seaf_fs_object_from_data (const char *obj_id, uint8_t *data, int len, gboolean is_json) { if (is_json) return fs_object_from_json (obj_id, data, len); else return fs_object_from_v0_data (obj_id, data, len); } void seaf_fs_object_free (SeafFSObject *obj) { if (!obj) return; if (obj->type == SEAF_METADATA_TYPE_FILE) seafile_unref ((Seafile *)obj); else if (obj->type == SEAF_METADATA_TYPE_DIR) seaf_dir_free ((SeafDir *)obj); } BlockList * block_list_new () { BlockList *bl = g_new0 (BlockList, 1); bl->block_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); bl->block_ids = g_ptr_array_new_with_free_func (g_free); return bl; } void block_list_free (BlockList *bl) { if (bl->block_hash) g_hash_table_destroy (bl->block_hash); g_ptr_array_free (bl->block_ids, TRUE); g_free (bl); } void block_list_insert (BlockList *bl, const char *block_id) { if (g_hash_table_lookup (bl->block_hash, block_id)) return; char *key = g_strdup(block_id); g_hash_table_replace (bl->block_hash, key, key); g_ptr_array_add (bl->block_ids, g_strdup(block_id)); ++bl->n_blocks; } BlockList * block_list_difference (BlockList *bl1, BlockList *bl2) { BlockList *bl; int i; char *block_id; char *key; bl = block_list_new (); for (i = 0; i < bl1->block_ids->len; ++i) { block_id = g_ptr_array_index (bl1->block_ids, i); if (g_hash_table_lookup (bl2->block_hash, block_id) == NULL) { key = g_strdup(block_id); g_hash_table_replace (bl->block_hash, key, key); g_ptr_array_add (bl->block_ids, g_strdup(block_id)); ++bl->n_blocks; } } return bl; } static int traverse_file (SeafFSManager *mgr, const char *repo_id, int version, const char *id, TraverseFSTreeCallback callback, void *user_data, gboolean skip_errors) { gboolean stop = FALSE; if (memcmp (id, EMPTY_SHA1, 40) == 0) return 0; if (!callback (mgr, repo_id, version, id, SEAF_METADATA_TYPE_FILE, user_data, &stop) && !skip_errors) return -1; return 0; } static int traverse_dir (SeafFSManager *mgr, const char *repo_id, int version, const char *id, TraverseFSTreeCallback callback, void *user_data, gboolean skip_errors) { SeafDir *dir; GList *p; SeafDirent *seaf_dent; gboolean stop = FALSE; if (!callback (mgr, repo_id, version, id, SEAF_METADATA_TYPE_DIR, user_data, &stop) && !skip_errors) return -1; if (stop) return 0; dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, id); if (!dir) { seaf_warning ("[fs-mgr]get seafdir %s failed\n", id); if (skip_errors) return 0; return -1; } for (p = dir->entries; p; p = p->next) { seaf_dent = (SeafDirent *)p->data; if (S_ISREG(seaf_dent->mode)) { if (traverse_file (mgr, repo_id, version, seaf_dent->id, callback, user_data, skip_errors) < 0) { if (!skip_errors) { seaf_dir_free (dir); return -1; } } } else if (S_ISDIR(seaf_dent->mode)) { if (traverse_dir (mgr, repo_id, version, seaf_dent->id, callback, user_data, skip_errors) < 0) { if (!skip_errors) { seaf_dir_free (dir); return -1; } } } } seaf_dir_free (dir); return 0; } int seaf_fs_manager_traverse_tree (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, TraverseFSTreeCallback callback, void *user_data, gboolean skip_errors) { if (strcmp (root_id, EMPTY_SHA1) == 0) { return 0; } return traverse_dir (mgr, repo_id, version, root_id, callback, user_data, skip_errors); } static int traverse_dir_path (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_path, SeafDirent *dent, TraverseFSPathCallback callback, void *user_data) { SeafDir *dir; GList *p; SeafDirent *seaf_dent; gboolean stop = FALSE; char *sub_path; int ret = 0; if (!callback (mgr, dir_path, dent, user_data, &stop)) return -1; if (stop) return 0; dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, dent->id); if (!dir) { seaf_warning ("get seafdir %s:%s failed\n", repo_id, dent->id); return -1; } for (p = dir->entries; p; p = p->next) { seaf_dent = (SeafDirent *)p->data; sub_path = g_strconcat (dir_path, "/", seaf_dent->name, NULL); if (S_ISREG(seaf_dent->mode)) { if (!callback (mgr, sub_path, seaf_dent, user_data, &stop)) { g_free (sub_path); ret = -1; break; } } else if (S_ISDIR(seaf_dent->mode)) { if (traverse_dir_path (mgr, repo_id, version, sub_path, seaf_dent, callback, user_data) < 0) { g_free (sub_path); ret = -1; break; } } g_free (sub_path); } seaf_dir_free (dir); return ret; } int seaf_fs_manager_traverse_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *dir_path, TraverseFSPathCallback callback, void *user_data) { SeafDirent *dent; int ret = 0; dent = seaf_fs_manager_get_dirent_by_path (mgr, repo_id, version, root_id, dir_path, NULL); if (!dent) { seaf_warning ("Failed to get dirent for %.8s:%s.\n", repo_id, dir_path); return -1; } ret = traverse_dir_path (mgr, repo_id, version, dir_path, dent, callback, user_data); seaf_dirent_free (dent); return ret; } static gboolean fill_blocklist (SeafFSManager *mgr, const char *repo_id, int version, const char *obj_id, int type, void *user_data, gboolean *stop) { BlockList *bl = user_data; Seafile *seafile; int i; if (type == SEAF_METADATA_TYPE_FILE) { seafile = seaf_fs_manager_get_seafile (mgr, repo_id, version, obj_id); if (!seafile) { seaf_warning ("[fs mgr] Failed to find file %s.\n", obj_id); return FALSE; } for (i = 0; i < seafile->n_blocks; ++i) block_list_insert (bl, seafile->blk_sha1s[i]); seafile_unref (seafile); } return TRUE; } int seaf_fs_manager_populate_blocklist (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, BlockList *bl) { return seaf_fs_manager_traverse_tree (mgr, repo_id, version, root_id, fill_blocklist, bl, FALSE); } gboolean seaf_fs_manager_object_exists (SeafFSManager *mgr, const char *repo_id, int version, const char *id) { /* Empty file and dir always exists. */ if (memcmp (id, EMPTY_SHA1, 40) == 0) return TRUE; return seaf_obj_store_obj_exists (mgr->obj_store, repo_id, version, id); } void seaf_fs_manager_delete_object (SeafFSManager *mgr, const char *repo_id, int version, const char *id) { seaf_obj_store_delete_obj (mgr->obj_store, repo_id, version, id); } gint64 seaf_fs_manager_get_file_size (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id) { Seafile *file; gint64 file_size; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo_id, version, file_id); if (!file) { seaf_warning ("Couldn't get file %s:%s\n", repo_id, file_id); return -1; } file_size = file->file_size; seafile_unref (file); return file_size; } static gint64 get_dir_size (SeafFSManager *mgr, const char *repo_id, int version, const char *id) { SeafDir *dir; SeafDirent *seaf_dent; guint64 size = 0; gint64 result; GList *p; dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, id); if (!dir) return -1; for (p = dir->entries; p; p = p->next) { seaf_dent = (SeafDirent *)p->data; if (S_ISREG(seaf_dent->mode)) { if (dir->version > 0) result = seaf_dent->size; else { result = seaf_fs_manager_get_file_size (mgr, repo_id, version, seaf_dent->id); if (result < 0) { seaf_dir_free (dir); return result; } } size += result; } else if (S_ISDIR(seaf_dent->mode)) { result = get_dir_size (mgr, repo_id, version, seaf_dent->id); if (result < 0) { seaf_dir_free (dir); return result; } size += result; } } seaf_dir_free (dir); return size; } gint64 seaf_fs_manager_get_fs_size (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id) { if (strcmp (root_id, EMPTY_SHA1) == 0) return 0; return get_dir_size (mgr, repo_id, version, root_id); } static int count_dir_files (SeafFSManager *mgr, const char *repo_id, int version, const char *id) { SeafDir *dir; SeafDirent *seaf_dent; int count = 0; int result; GList *p; dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, id); if (!dir) return -1; for (p = dir->entries; p; p = p->next) { seaf_dent = (SeafDirent *)p->data; if (S_ISREG(seaf_dent->mode)) { count ++; } else if (S_ISDIR(seaf_dent->mode)) { result = count_dir_files (mgr, repo_id, version, seaf_dent->id); if (result < 0) { seaf_dir_free (dir); return result; } count += result; } } seaf_dir_free (dir); return count; } int seaf_fs_manager_count_fs_files (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id) { if (strcmp (root_id, EMPTY_SHA1) == 0) return 0; return count_dir_files (mgr, repo_id, version, root_id); } SeafDir * seaf_fs_manager_get_seafdir_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error) { SeafDir *dir; SeafDirent *dent; const char *dir_id = root_id; char *name, *saveptr; char *tmp_path = g_strdup(path); dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, dir_id); if (!dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_DIR_MISSING, "directory is missing"); g_free (tmp_path); return NULL; } name = strtok_r (tmp_path, "/", &saveptr); while (name != NULL) { GList *l; for (l = dir->entries; l != NULL; l = l->next) { dent = l->data; if (strcmp(dent->name, name) == 0 && S_ISDIR(dent->mode)) { dir_id = dent->id; break; } } if (!l) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_PATH_NO_EXIST, "Path does not exists %s", path); seaf_dir_free (dir); dir = NULL; break; } SeafDir *prev = dir; dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, dir_id); seaf_dir_free (prev); if (!dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_DIR_MISSING, "directory is missing"); break; } name = strtok_r (NULL, "/", &saveptr); } g_free (tmp_path); return dir; } char * seaf_fs_manager_path_to_obj_id (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, guint32 *mode, GError **error) { char *copy = g_strdup (path); int off = strlen(copy) - 1; char *slash, *name; SeafDir *base_dir = NULL; SeafDirent *dent; GList *p; char *obj_id = NULL; while (off >= 0 && copy[off] == '/') copy[off--] = 0; if (strlen(copy) == 0) { /* the path is root "/" */ if (mode) { *mode = S_IFDIR; } obj_id = g_strdup(root_id); goto out; } slash = strrchr (copy, '/'); if (!slash) { base_dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, root_id); if (!base_dir) { seaf_warning ("Failed to find root dir %s.\n", root_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, " "); goto out; } name = copy; } else { *slash = 0; name = slash + 1; GError *tmp_error = NULL; base_dir = seaf_fs_manager_get_seafdir_by_path (mgr, repo_id, version, root_id, copy, &tmp_error); if (tmp_error && !g_error_matches(tmp_error, SEAFILE_DOMAIN, SEAF_ERR_PATH_NO_EXIST)) { seaf_warning ("Failed to get dir for %s.\n", copy); g_propagate_error (error, tmp_error); goto out; } /* The path doesn't exist in this commit. */ if (!base_dir) { g_propagate_error (error, tmp_error); goto out; } } for (p = base_dir->entries; p != NULL; p = p->next) { dent = p->data; if (!is_object_id_valid (dent->id)) continue; if (strcmp (dent->name, name) == 0) { obj_id = g_strdup (dent->id); if (mode) { *mode = dent->mode; } break; } } out: if (base_dir) seaf_dir_free (base_dir); g_free (copy); return obj_id; } char * seaf_fs_manager_get_seafile_id_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error) { guint32 mode; char *file_id; file_id = seaf_fs_manager_path_to_obj_id (mgr, repo_id, version, root_id, path, &mode, error); if (!file_id) return NULL; if (file_id && S_ISDIR(mode)) { g_free (file_id); return NULL; } return file_id; } char * seaf_fs_manager_get_seafdir_id_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error) { guint32 mode = 0; char *dir_id; dir_id = seaf_fs_manager_path_to_obj_id (mgr, repo_id, version, root_id, path, &mode, error); if (!dir_id) return NULL; if (dir_id && !S_ISDIR(mode)) { g_free (dir_id); return NULL; } return dir_id; } SeafDirent * seaf_fs_manager_get_dirent_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error) { SeafDirent *dent = NULL; SeafDir *dir = NULL; char *parent_dir = NULL; char *file_name = NULL; parent_dir = g_path_get_dirname(path); file_name = g_path_get_basename(path); if (strcmp (parent_dir, ".") == 0) { dir = seaf_fs_manager_get_seafdir (mgr, repo_id, version, root_id); if (!dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_DIR_MISSING, "directory is missing"); } } else dir = seaf_fs_manager_get_seafdir_by_path (mgr, repo_id, version, root_id, parent_dir, error); if (!dir) { seaf_warning ("dir %s doesn't exist in repo %.8s.\n", parent_dir, repo_id); goto out; } GList *p; for (p = dir->entries; p; p = p->next) { SeafDirent *d = p->data; if (strcmp (d->name, file_name) == 0) { dent = seaf_dirent_dup(d); break; } } out: if (dir) seaf_dir_free (dir); g_free (parent_dir); g_free (file_name); return dent; } static gboolean verify_seafdir_v0 (const char *dir_id, const uint8_t *data, int len, gboolean verify_id) { guint32 meta_type; guint32 mode; char id[41]; guint32 name_len; char name[SEAF_DIR_NAME_LEN]; const uint8_t *ptr; int remain; int dirent_base_size; GChecksum *ctx; uint8_t sha1[20]; gsize cs_len = 20; char check_id[41]; if (len < sizeof(SeafdirOndisk)) { seaf_warning ("[fs mgr] Corrupt seafdir object %s.\n", dir_id); return FALSE; } ptr = data; remain = len; meta_type = get32bit (&ptr); remain -= 4; if (meta_type != SEAF_METADATA_TYPE_DIR) { seaf_warning ("Data does not contain a directory.\n"); return FALSE; } if (verify_id) ctx = g_checksum_new (G_CHECKSUM_SHA1); dirent_base_size = 2 * sizeof(guint32) + 40; while (remain > dirent_base_size) { mode = get32bit (&ptr); memcpy (id, ptr, 40); id[40] = '\0'; ptr += 40; name_len = get32bit (&ptr); remain -= dirent_base_size; if (remain >= name_len) { name_len = MIN (name_len, SEAF_DIR_NAME_LEN - 1); memcpy (name, ptr, name_len); ptr += name_len; remain -= name_len; } else { seaf_warning ("Bad data format for dir objcet %s.\n", dir_id); return FALSE; } if (verify_id) { /* Convert mode to little endian before compute. */ if (G_BYTE_ORDER == G_BIG_ENDIAN) mode = GUINT32_SWAP_LE_BE (mode); g_checksum_update (ctx, (unsigned char *)id, 40); g_checksum_update (ctx, (unsigned char *)name, name_len); g_checksum_update (ctx, (unsigned char *)&mode, sizeof(mode)); } } if (!verify_id) return TRUE; g_checksum_get_digest (ctx, sha1, &cs_len); rawdata_to_hex (sha1, check_id, 20); g_checksum_free (ctx); if (strcmp (check_id, dir_id) == 0) return TRUE; else return FALSE; } static gboolean verify_fs_object_json (const char *obj_id, uint8_t *data, int len) { guint8 *decompressed; int outlen; unsigned char sha1[20]; char hex[41]; if (seaf_decompress (data, len, &decompressed, &outlen) < 0) { seaf_warning ("Failed to decompress fs object %s.\n", obj_id); return FALSE; } calculate_sha1 (sha1, (const char *)decompressed, outlen); rawdata_to_hex (sha1, hex, 20); g_free (decompressed); return (strcmp(hex, obj_id) == 0); } static gboolean verify_seafdir (const char *dir_id, uint8_t *data, int len, gboolean verify_id, gboolean is_json) { if (is_json) return verify_fs_object_json (dir_id, data, len); else return verify_seafdir_v0 (dir_id, data, len, verify_id); } gboolean seaf_fs_manager_verify_seafdir (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id, gboolean verify_id, gboolean *io_error) { void *data; int len; if (memcmp (dir_id, EMPTY_SHA1, 40) == 0) { return TRUE; } if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, dir_id, &data, &len) < 0) { seaf_warning ("[fs mgr] Failed to read dir %s:%s.\n", repo_id, dir_id); *io_error = TRUE; return FALSE; } gboolean ret = verify_seafdir (dir_id, data, len, verify_id, (version > 0)); g_free (data); return ret; } static gboolean verify_seafile_v0 (const char *id, const void *data, int len, gboolean verify_id) { const SeafileOndisk *ondisk = data; GChecksum *ctx; uint8_t sha1[20]; gsize cs_len = 20; char check_id[41]; if (len < sizeof(SeafileOndisk)) { seaf_warning ("[fs mgr] Corrupt seafile object %s.\n", id); return FALSE; } if (ntohl(ondisk->type) != SEAF_METADATA_TYPE_FILE) { seaf_warning ("[fd mgr] %s is not a file.\n", id); return FALSE; } int id_list_length = len - sizeof(SeafileOndisk); if (id_list_length % 20 != 0) { seaf_warning ("[fs mgr] Bad seafile id list length %d.\n", id_list_length); return FALSE; } if (!verify_id) return TRUE; ctx = g_checksum_new (G_CHECKSUM_SHA1); g_checksum_update (ctx, ondisk->block_ids, len - sizeof(SeafileOndisk)); g_checksum_get_digest (ctx, sha1, &cs_len); g_checksum_free (ctx); rawdata_to_hex (sha1, check_id, 20); if (strcmp (check_id, id) == 0) return TRUE; else return FALSE; } static gboolean verify_seafile (const char *id, void *data, int len, gboolean verify_id, gboolean is_json) { if (is_json) return verify_fs_object_json (id, data, len); else return verify_seafile_v0 (id, data, len, verify_id); } gboolean seaf_fs_manager_verify_seafile (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id, gboolean verify_id, gboolean *io_error) { void *data; int len; if (memcmp (file_id, EMPTY_SHA1, 40) == 0) { return TRUE; } if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, file_id, &data, &len) < 0) { seaf_warning ("[fs mgr] Failed to read file %s:%s.\n", repo_id, file_id); *io_error = TRUE; return FALSE; } gboolean ret = verify_seafile (file_id, data, len, verify_id, (version > 0)); g_free (data); return ret; } static gboolean verify_fs_object_v0 (const char *obj_id, uint8_t *data, int len, gboolean verify_id) { gboolean ret = TRUE; int type = seaf_metadata_type_from_data (obj_id, data, len, FALSE); switch (type) { case SEAF_METADATA_TYPE_FILE: ret = verify_seafile_v0 (obj_id, data, len, verify_id); break; case SEAF_METADATA_TYPE_DIR: ret = verify_seafdir_v0 (obj_id, data, len, verify_id); break; default: seaf_warning ("Invalid meta data type: %d.\n", type); return FALSE; } return ret; } gboolean seaf_fs_manager_verify_object (SeafFSManager *mgr, const char *repo_id, int version, const char *obj_id, gboolean verify_id, gboolean *io_error) { void *data; int len; gboolean ret = TRUE; if (memcmp (obj_id, EMPTY_SHA1, 40) == 0) { return TRUE; } if (seaf_obj_store_read_obj (mgr->obj_store, repo_id, version, obj_id, &data, &len) < 0) { seaf_warning ("[fs mgr] Failed to read object %s:%s.\n", repo_id, obj_id); *io_error = TRUE; return FALSE; } if (version == 0) ret = verify_fs_object_v0 (obj_id, data, len, verify_id); else ret = verify_fs_object_json (obj_id, data, len); g_free (data); return ret; } int dir_version_from_repo_version (int repo_version) { if (repo_version == 0) return 0; else return CURRENT_DIR_OBJ_VERSION; } int seafile_version_from_repo_version (int repo_version) { if (repo_version == 0) return 0; else return CURRENT_SEAFILE_OBJ_VERSION; } int seaf_fs_manager_remove_store (SeafFSManager *mgr, const char *store_id) { return seaf_obj_store_remove_store (mgr->obj_store, store_id); } seafile-6.1.5/common/fs-mgr.h000066400000000000000000000326251323477647300160170ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_FILE_MGR_H #define SEAF_FILE_MGR_H #include #include "seafile-object.h" #include "obj-store.h" #include "cdc/cdc.h" #include "../common/seafile-crypt.h" #define CURRENT_DIR_OBJ_VERSION 1 #define CURRENT_SEAFILE_OBJ_VERSION 1 #define CDC_AVERAGE_BLOCK_SIZE (1 << 23) /* 8MB */ #define CDC_MIN_BLOCK_SIZE (6 * (1 << 20)) /* 6MB */ #define CDC_MAX_BLOCK_SIZE (10 * (1 << 20)) /* 10MB */ typedef struct _SeafFSManager SeafFSManager; typedef struct _SeafFSObject SeafFSObject; typedef struct _Seafile Seafile; typedef struct _SeafDir SeafDir; typedef struct _SeafDirent SeafDirent; typedef enum { SEAF_METADATA_TYPE_INVALID, SEAF_METADATA_TYPE_FILE, SEAF_METADATA_TYPE_LINK, SEAF_METADATA_TYPE_DIR, } SeafMetadataType; /* Common to seafile and seafdir objects. */ struct _SeafFSObject { int type; }; struct _Seafile { SeafFSObject object; int version; char file_id[41]; guint64 file_size; guint32 n_blocks; char **blk_sha1s; int ref_count; }; void seafile_ref (Seafile *seafile); void seafile_unref (Seafile *seafile); int seafile_save (SeafFSManager *fs_mgr, const char *repo_id, int version, Seafile *file); #define SEAF_DIR_NAME_LEN 256 struct _SeafDirent { int version; guint32 mode; char id[41]; guint32 name_len; char *name; /* attributes for version > 0 */ gint64 mtime; char *modifier; /* for files only */ gint64 size; /* for files only */ }; struct _SeafDir { SeafFSObject object; int version; char dir_id[41]; GList *entries; /* data in on-disk format. */ void *ondisk; int ondisk_size; }; SeafDir * seaf_dir_new (const char *id, GList *entries, int version); void seaf_dir_free (SeafDir *dir); SeafDir * seaf_dir_from_data (const char *dir_id, uint8_t *data, int len, gboolean is_json); void * seaf_dir_to_data (SeafDir *dir, int *len); int seaf_dir_save (SeafFSManager *fs_mgr, const char *repo_id, int version, SeafDir *dir); SeafDirent * seaf_dirent_new (int version, const char *sha1, int mode, const char *name, gint64 mtime, const char *modifier, gint64 size); void seaf_dirent_free (SeafDirent *dent); SeafDirent * seaf_dirent_dup (SeafDirent *dent); int seaf_metadata_type_from_data (const char *obj_id, uint8_t *data, int len, gboolean is_json); /* Parse an fs object without knowing its type. */ SeafFSObject * seaf_fs_object_from_data (const char *obj_id, uint8_t *data, int len, gboolean is_json); void seaf_fs_object_free (SeafFSObject *obj); typedef struct { /* TODO: GHashTable may be inefficient when we have large number of IDs. */ GHashTable *block_hash; GPtrArray *block_ids; uint32_t n_blocks; uint32_t n_valid_blocks; } BlockList; BlockList * block_list_new (); void block_list_free (BlockList *bl); void block_list_insert (BlockList *bl, const char *block_id); /* Return a blocklist containing block ids which are in @bl1 but * not in @bl2. */ BlockList * block_list_difference (BlockList *bl1, BlockList *bl2); struct _SeafileSession; typedef struct _SeafFSManagerPriv SeafFSManagerPriv; struct _SeafFSManager { struct _SeafileSession *seaf; struct SeafObjStore *obj_store; SeafFSManagerPriv *priv; }; SeafFSManager * seaf_fs_manager_new (struct _SeafileSession *seaf, const char *seaf_dir); int seaf_fs_manager_init (SeafFSManager *mgr); #ifndef SEAFILE_SERVER int seaf_fs_manager_checkout_file (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id, const char *file_path, guint32 mode, guint64 mtime, struct SeafileCrypt *crypt, const char *in_repo_path, const char *conflict_head_id, gboolean force_conflict, gboolean *conflicted, const char *email); #endif /* not SEAFILE_SERVER */ /** * Check in blocks and create seafile/symlink object. * Returns sha1 id for the seafile/symlink object in @sha1 parameter. */ int seaf_fs_manager_index_file_blocks (SeafFSManager *mgr, const char *repo_id, int version, GList *paths, GList *blockids, unsigned char sha1[], gint64 file_size); int seaf_fs_manager_index_raw_blocks (SeafFSManager *mgr, const char *repo_id, int version, GList *paths, GList *blockids); int seaf_fs_manager_index_existed_file_blocks (SeafFSManager *mgr, const char *repo_id, int version, GList *blockids, unsigned char sha1[], gint64 file_size); int seaf_fs_manager_index_blocks (SeafFSManager *mgr, const char *repo_id, int version, const char *file_path, unsigned char sha1[], gint64 *size, SeafileCrypt *crypt, gboolean write_data, gboolean use_cdc); Seafile * seaf_fs_manager_get_seafile (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id); SeafDir * seaf_fs_manager_get_seafdir (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id); /* Make sure entries in the returned dir is sorted in descending order. */ SeafDir * seaf_fs_manager_get_seafdir_sorted (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id); SeafDir * seaf_fs_manager_get_seafdir_sorted_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path); int seaf_fs_manager_populate_blocklist (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, BlockList *bl); /* * For dir object, set *stop to TRUE to stop traversing the subtree. */ typedef gboolean (*TraverseFSTreeCallback) (SeafFSManager *mgr, const char *repo_id, int version, const char *obj_id, int type, void *user_data, gboolean *stop); int seaf_fs_manager_traverse_tree (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, TraverseFSTreeCallback callback, void *user_data, gboolean skip_errors); typedef gboolean (*TraverseFSPathCallback) (SeafFSManager *mgr, const char *path, SeafDirent *dent, void *user_data, gboolean *stop); int seaf_fs_manager_traverse_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *dir_path, TraverseFSPathCallback callback, void *user_data); gboolean seaf_fs_manager_object_exists (SeafFSManager *mgr, const char *repo_id, int version, const char *id); void seaf_fs_manager_delete_object (SeafFSManager *mgr, const char *repo_id, int version, const char *id); gint64 seaf_fs_manager_get_file_size (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id); gint64 seaf_fs_manager_get_fs_size (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id); #ifndef SEAFILE_SERVER int seafile_write_chunk (const char *repo_id, int version, CDCDescriptor *chunk, SeafileCrypt *crypt, uint8_t *checksum, gboolean write_data); int seafile_check_write_chunk (CDCDescriptor *chunk, uint8_t *sha1, gboolean write_data); #endif /* SEAFILE_SERVER */ uint32_t calculate_chunk_size (uint64_t total_size); int seaf_fs_manager_count_fs_files (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id); SeafDir * seaf_fs_manager_get_seafdir_by_path(SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error); char * seaf_fs_manager_get_seafile_id_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error); char * seaf_fs_manager_path_to_obj_id (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, guint32 *mode, GError **error); char * seaf_fs_manager_get_seafdir_id_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error); SeafDirent * seaf_fs_manager_get_dirent_by_path (SeafFSManager *mgr, const char *repo_id, int version, const char *root_id, const char *path, GError **error); /* Check object integrity. */ gboolean seaf_fs_manager_verify_seafdir (SeafFSManager *mgr, const char *repo_id, int version, const char *dir_id, gboolean verify_id, gboolean *io_error); gboolean seaf_fs_manager_verify_seafile (SeafFSManager *mgr, const char *repo_id, int version, const char *file_id, gboolean verify_id, gboolean *io_error); gboolean seaf_fs_manager_verify_object (SeafFSManager *mgr, const char *repo_id, int version, const char *obj_id, gboolean verify_id, gboolean *io_error); int dir_version_from_repo_version (int repo_version); int seafile_version_from_repo_version (int repo_version); struct _CDCFileDescriptor; void seaf_fs_manager_calculate_seafile_id_json (int repo_version, struct _CDCFileDescriptor *cdc, guint8 *file_id_sha1); int seaf_fs_manager_remove_store (SeafFSManager *mgr, const char *store_id); #endif seafile-6.1.5/common/index/000077500000000000000000000000001323477647300155525ustar00rootroot00000000000000seafile-6.1.5/common/index/Makefile.am000066400000000000000000000005361323477647300176120ustar00rootroot00000000000000AM_CPPFLAGS = -Wall -I${top_srcdir}/common -I${top_srcdir}/lib \ @MSVC_CFLAGS@ noinst_LTLIBRARIES = libindex.la noinst_HEADERS = index.h cache-tree.h libindex_la_SOURCES = index.c cache-tree.c libindex_la_CFLAGS = @GLIB2_CFLAGS@ libindex_la_LDFLAGS = -Wl,-z -Wl,defs libindex_la_LIBADD = @GLIB2_LIBS@ \ $(top_builddir)/lib/libseafile_common.la seafile-6.1.5/common/index/cache-tree.c000066400000000000000000000433511323477647300177240ustar00rootroot00000000000000 #include "common.h" #include "log.h" #include "index.h" #if 0 #include "tree.h" #include "tree-walk.h" #endif #include "cache-tree.h" #include #ifndef DEBUG #define DEBUG 0 #endif struct cache_tree *cache_tree(void) { struct cache_tree *it = calloc(1, sizeof(struct cache_tree)); it->entry_count = -1; return it; } void cache_tree_free(struct cache_tree **it_p) { int i; struct cache_tree *it = *it_p; if (!it) return; for (i = 0; i < it->subtree_nr; i++) if (it->down[i]) { cache_tree_free(&it->down[i]->cache_tree); free(it->down[i]); } free(it->down); free(it); *it_p = NULL; } static int subtree_name_cmp(const char *one, int onelen, const char *two, int twolen) { if (onelen < twolen) return -1; if (twolen < onelen) return 1; return memcmp(one, two, onelen); } static int subtree_pos(struct cache_tree *it, const char *path, int pathlen) { struct cache_tree_sub **down = it->down; int lo, hi; lo = 0; hi = it->subtree_nr; while (lo < hi) { int mi = (lo + hi) / 2; struct cache_tree_sub *mdl = down[mi]; int cmp = subtree_name_cmp(path, pathlen, mdl->name, mdl->namelen); if (!cmp) return mi; if (cmp < 0) hi = mi; else lo = mi + 1; } return -lo-1; } static struct cache_tree_sub *find_subtree(struct cache_tree *it, const char *path, int pathlen, int create) { struct cache_tree_sub *down; int pos = subtree_pos(it, path, pathlen); if (0 <= pos) return it->down[pos]; if (!create) return NULL; pos = -pos-1; if (it->subtree_alloc <= it->subtree_nr) { it->subtree_alloc = alloc_nr(it->subtree_alloc); it->down = realloc(it->down, it->subtree_alloc * sizeof(*it->down)); } it->subtree_nr++; down = malloc(sizeof(*down) + pathlen + 1); down->cache_tree = NULL; down->namelen = pathlen; memcpy(down->name, path, pathlen); down->name[pathlen] = 0; if (pos < it->subtree_nr) memmove(it->down + pos + 1, it->down + pos, sizeof(down) * (it->subtree_nr - pos - 1)); it->down[pos] = down; return down; } struct cache_tree_sub *cache_tree_find_subtree(struct cache_tree *it, const char *path, int pathlen, int create) { return find_subtree(it, path, pathlen, create); } #if 0 struct cache_tree_sub *cache_tree_sub(struct cache_tree *it, const char *path) { int pathlen = strlen(path); return find_subtree(it, path, pathlen, 1); } void cache_tree_invalidate_path(struct cache_tree *it, const char *path) { /* a/b/c * ==> invalidate self * ==> find "a", have it invalidate "b/c" * a * ==> invalidate self * ==> if "a" exists as a subtree, remove it. */ const char *slash; int namelen; struct cache_tree_sub *down; #if DEBUG fprintf(stderr, "cache-tree invalidate <%s>\n", path); #endif if (!it) return; slash = strchr(path, '/'); it->entry_count = -1; if (!slash) { int pos; namelen = strlen(path); pos = subtree_pos(it, path, namelen); if (0 <= pos) { cache_tree_free(&it->down[pos]->cache_tree); free(it->down[pos]); /* 0 1 2 3 4 5 * ^ ^subtree_nr = 6 * pos * move 4 and 5 up one place (2 entries) * 2 = 6 - 3 - 1 = subtree_nr - pos - 1 */ memmove(it->down+pos, it->down+pos+1, sizeof(struct cache_tree_sub *) * (it->subtree_nr - pos - 1)); it->subtree_nr--; } return; } namelen = slash - path; down = find_subtree(it, path, namelen, 0); if (down) cache_tree_invalidate_path(down->cache_tree, slash + 1); } #endif static int verify_cache(struct cache_entry **cache, int entries) { int i, funny; /* Verify that the tree is merged */ funny = 0; for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; if (ce_stage(ce) || (ce->ce_flags & CE_INTENT_TO_ADD)) { if (10 < ++funny) { /*fprintf(stderr, "...\n");*/ break; } #if 0 if (ce_stage(ce)) fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1)); else fprintf(stderr, "%s: not added yet\n", ce->name); #endif } } if (funny) return -1; /* Also verify that the cache does not have path and path/file * at the same time. At this point we know the cache has only * stage 0 entries. */ funny = 0; for (i = 0; i < entries - 1; i++) { /* path/file always comes after path because of the way * the cache is sorted. Also path can appear only once, * which means conflicting one would immediately follow. */ const char *this_name = cache[i]->name; const char *next_name = cache[i+1]->name; int this_len = strlen(this_name); if (this_len < strlen(next_name) && strncmp(this_name, next_name, this_len) == 0 && next_name[this_len] == '/') { if (10 < ++funny) { fprintf(stderr, "...\n"); break; } seaf_warning("You have both %s and %s\n", this_name, next_name); } } if (funny) return -1; return 0; } static void discard_unused_subtrees(struct cache_tree *it) { struct cache_tree_sub **down = it->down; int nr = it->subtree_nr; int dst, src; for (dst = src = 0; src < nr; src++) { struct cache_tree_sub *s = down[src]; if (s->used) down[dst++] = s; else { cache_tree_free(&s->cache_tree); free(s); it->subtree_nr--; } } } #if 0 int cache_tree_fully_valid(struct cache_tree *it) { int i; if (!it) return 0; if (it->entry_count < 0 || !has_sha1_file(it->sha1)) return 0; for (i = 0; i < it->subtree_nr; i++) { if (!cache_tree_fully_valid(it->down[i]->cache_tree)) return 0; } return 1; } #endif static int update_one(const char *repo_id, int version, const char *worktree, struct cache_tree *it, struct cache_entry **cache, int entries, const char *base, int baselen, int missing_ok, int dryrun, CommitCB commit_cb) { int i; if (0 <= it->entry_count) return it->entry_count; /* * We first scan for subtrees and update them; we start by * marking existing subtrees -- the ones that are unmarked * should not be in the result. */ for (i = 0; i < it->subtree_nr; i++) it->down[i]->used = 0; /* * Find the subtrees and update them. */ for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, sublen, subcnt; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (!slash) continue; /* * a/bbb/c (base = a/, slash = /c) * ==> * path+baselen = bbb/c, sublen = 3 */ sublen = slash - (path + baselen); sub = find_subtree(it, path + baselen, sublen, 1); if (!sub->cache_tree) sub->cache_tree = cache_tree(); subcnt = update_one(repo_id, version, worktree, sub->cache_tree, cache + i, entries - i, path, baselen + sublen + 1, missing_ok, dryrun, commit_cb); if (subcnt < 0) return subcnt; i += subcnt - 1; sub->used = 1; } it->entry_count = i; discard_unused_subtrees(it); if (commit_cb (repo_id, version, worktree, it, cache, entries, base, baselen) < 0) { seaf_warning ("save seafile dirent failed"); return -1; } return i; } int cache_tree_update(const char *repo_id, int repo_version, const char *worktree, struct cache_tree *it, struct cache_entry **cache, int entries, int missing_ok, int dryrun, CommitCB commit_cb) { int i; i = verify_cache(cache, entries); if (i) return i; i = update_one(repo_id, repo_version, worktree, it, cache, entries, "", 0, missing_ok, dryrun, commit_cb); if (i < 0) return i; return 0; } #if 0 static void write_one(struct strbuf *buffer, struct cache_tree *it, const char *path, int pathlen) { int i; /* One "cache-tree" entry consists of the following: * path (NUL terminated) * entry_count, subtree_nr ("%d %d\n") * tree-sha1 (missing if invalid) * subtree_nr "cache-tree" entries for subtrees. */ strbuf_grow(buffer, pathlen + 100); strbuf_add(buffer, path, pathlen); strbuf_addf(buffer, "%c%d %d\n", 0, it->entry_count, it->subtree_nr); #if DEBUG if (0 <= it->entry_count) fprintf(stderr, "cache-tree <%.*s> (%d ent, %d subtree) %s\n", pathlen, path, it->entry_count, it->subtree_nr, sha1_to_hex(it->sha1)); else fprintf(stderr, "cache-tree <%.*s> (%d subtree) invalid\n", pathlen, path, it->subtree_nr); #endif if (0 <= it->entry_count) { strbuf_add(buffer, it->sha1, 20); } for (i = 0; i < it->subtree_nr; i++) { struct cache_tree_sub *down = it->down[i]; if (i) { struct cache_tree_sub *prev = it->down[i-1]; if (subtree_name_cmp(down->name, down->namelen, prev->name, prev->namelen) <= 0) die("fatal - unsorted cache subtree"); } write_one(buffer, down->cache_tree, down->name, down->namelen); } } void cache_tree_write(struct strbuf *sb, struct cache_tree *root) { write_one(sb, root, "", 0); } static struct cache_tree *read_one(const char **buffer, unsigned long *size_p) { const char *buf = *buffer; unsigned long size = *size_p; const char *cp; char *ep; struct cache_tree *it; int i, subtree_nr; it = NULL; /* skip name, but make sure name exists */ while (size && *buf) { size--; buf++; } if (!size) goto free_return; buf++; size--; it = cache_tree(); cp = buf; it->entry_count = strtol(cp, &ep, 10); if (cp == ep) goto free_return; cp = ep; subtree_nr = strtol(cp, &ep, 10); if (cp == ep) goto free_return; while (size && *buf && *buf != '\n') { size--; buf++; } if (!size) goto free_return; buf++; size--; if (0 <= it->entry_count) { if (size < 20) goto free_return; hashcpy(it->sha1, (const unsigned char*)buf); buf += 20; size -= 20; } #if DEBUG if (0 <= it->entry_count) fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n", *buffer, it->entry_count, subtree_nr, sha1_to_hex(it->sha1)); else fprintf(stderr, "cache-tree <%s> (%d subtrees) invalid\n", *buffer, subtree_nr); #endif /* * Just a heuristic -- we do not add directories that often but * we do not want to have to extend it immediately when we do, * hence +2. */ it->subtree_alloc = subtree_nr + 2; it->down = xcalloc(it->subtree_alloc, sizeof(struct cache_tree_sub *)); for (i = 0; i < subtree_nr; i++) { /* read each subtree */ struct cache_tree *sub; struct cache_tree_sub *subtree; const char *name = buf; sub = read_one(&buf, &size); if (!sub) goto free_return; subtree = cache_tree_sub(it, name); subtree->cache_tree = sub; } if (subtree_nr != it->subtree_nr) die("cache-tree: internal error"); *buffer = buf; *size_p = size; return it; free_return: cache_tree_free(&it); return NULL; } struct cache_tree *cache_tree_read(const char *buffer, unsigned long size) { if (buffer[0]) return NULL; /* not the whole tree */ return read_one(&buffer, &size); } static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *path) { if (!it) return NULL; while (*path) { const char *slash; struct cache_tree_sub *sub; slash = strchr(path, '/'); if (!slash) slash = path + strlen(path); /* between path and slash is the name of the * subtree to look for. */ sub = find_subtree(it, path, slash - path, 0); if (!sub) return NULL; it = sub->cache_tree; if (slash) while (*slash && *slash == '/') slash++; if (!slash || !*slash) return it; /* prefix ended with slashes */ path = slash; } return it; } #if 0 int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix) { int entries, was_valid, newfd; struct lock_file *lock_file; /* * We can't free this memory, it becomes part of a linked list * parsed atexit() */ lock_file = xcalloc(1, sizeof(struct lock_file)); newfd = hold_locked_index(lock_file, 1); entries = read_cache(); if (entries < 0) return WRITE_TREE_UNREADABLE_INDEX; if (flags & WRITE_TREE_IGNORE_CACHE_TREE) cache_tree_free(&(active_cache_tree)); if (!active_cache_tree) active_cache_tree = cache_tree(); was_valid = cache_tree_fully_valid(active_cache_tree); if (!was_valid) { int missing_ok = flags & WRITE_TREE_MISSING_OK; if (cache_tree_update(active_cache_tree, active_cache, active_nr, missing_ok, 0) < 0) return WRITE_TREE_UNMERGED_INDEX; if (0 <= newfd) { if (!write_cache(newfd, active_cache, active_nr) && !commit_lock_file(lock_file)) newfd = -1; } /* Not being able to write is fine -- we are only interested * in updating the cache-tree part, and if the next caller * ends up using the old index with unupdated cache-tree part * it misses the work we did here, but that is just a * performance penalty and not a big deal. */ } if (prefix) { struct cache_tree *subtree = cache_tree_find(active_cache_tree, prefix); if (!subtree) return WRITE_TREE_PREFIX_ERROR; hashcpy(sha1, subtree->sha1); } else hashcpy(sha1, active_cache_tree->sha1); if (0 <= newfd) rollback_lock_file(lock_file); return 0; } #endif /* 0 */ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) { struct tree_desc desc; struct name_entry entry; int cnt; hashcpy(it->sha1, tree->object.sha1); init_tree_desc(&desc, tree->buffer, tree->size); cnt = 0; while (tree_entry(&desc, &entry)) { if (!S_ISDIR(entry.mode)) cnt++; else { struct cache_tree_sub *sub; struct tree *subtree = lookup_tree(entry.sha1); if (!subtree->object.parsed) parse_tree(subtree); sub = cache_tree_sub(it, entry.path); sub->cache_tree = cache_tree(); prime_cache_tree_rec(sub->cache_tree, subtree); cnt += sub->cache_tree->entry_count; } } it->entry_count = cnt; } void prime_cache_tree(struct cache_tree **it, struct tree *tree) { cache_tree_free(it); *it = cache_tree(); prime_cache_tree_rec(*it, tree); } /* * find the cache_tree that corresponds to the current level without * exploding the full path into textual form. The root of the * cache tree is given as "root", and our current level is "info". * (1) When at root level, info->prev is NULL, so it is "root" itself. * (2) Otherwise, find the cache_tree that corresponds to one level * above us, and find ourselves in there. */ static struct cache_tree *find_cache_tree_from_traversal(struct cache_tree *root, struct traverse_info *info) { struct cache_tree *our_parent; if (!info->prev) return root; our_parent = find_cache_tree_from_traversal(root, info->prev); return cache_tree_find(our_parent, info->name.path); } int cache_tree_matches_traversal(struct cache_tree *root, struct name_entry *ent, struct traverse_info *info) { struct cache_tree *it; it = find_cache_tree_from_traversal(root, info); it = cache_tree_find(it, ent->path); if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1)) return it->entry_count; return 0; } #endif seafile-6.1.5/common/index/cache-tree.h000066400000000000000000000035371323477647300177330ustar00rootroot00000000000000#ifndef CACHE_TREE_H #define CACHE_TREE_H #include struct cache_tree; struct cache_tree_sub { struct cache_tree *cache_tree; int namelen; int used; char name[0]; }; struct cache_tree { int entry_count; /* negative means "invalid" */ unsigned char sha1[20]; int subtree_nr; int subtree_alloc; guint64 mtime; struct cache_tree_sub **down; }; typedef int (*CommitCB) (const char *, int, const char *, struct cache_tree *, struct cache_entry **, int, const char *, int); struct cache_tree_sub *cache_tree_find_subtree(struct cache_tree *, const char *, int, int); struct cache_tree *cache_tree(void); void cache_tree_free(struct cache_tree **); void cache_tree_invalidate_path(struct cache_tree *, const char *); struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *); /* void cache_tree_write(struct strbuf *, struct cache_tree *root); */ /* struct cache_tree *cache_tree_read(const char *buffer, unsigned long size); */ int cache_tree_fully_valid(struct cache_tree *); int cache_tree_update(const char *repo_id, int version, const char *worktree, struct cache_tree *, struct cache_entry **, int, int, int, CommitCB); /* bitmasks to write_cache_as_tree flags */ #define WRITE_TREE_MISSING_OK 1 #define WRITE_TREE_IGNORE_CACHE_TREE 2 /* error return codes */ #define WRITE_TREE_UNREADABLE_INDEX (-1) #define WRITE_TREE_UNMERGED_INDEX (-2) #define WRITE_TREE_PREFIX_ERROR (-3) int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix); /* void prime_cache_tree(struct cache_tree **, struct tree *); */ /* extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info); */ #endif seafile-6.1.5/common/index/hash.c000066400000000000000000000054161323477647300166470ustar00rootroot00000000000000/* * Some generic hashing helpers. */ #include "index.h" #include "hash.h" /* * Look up a hash entry in the hash table. Return the pointer to * the existing entry, or the empty slot if none existed. The caller * can then look at the (*ptr) to see whether it existed or not. */ static struct hash_table_entry *lookup_hash_entry(unsigned int hash, const struct hash_table *table) { unsigned int size = table->size, nr = hash % size; struct hash_table_entry *array = table->array; while (array[nr].ptr) { if (array[nr].hash == hash) break; nr++; if (nr >= size) nr = 0; } return array + nr; } /* * Insert a new hash entry pointer into the table. * * If that hash entry already existed, return the pointer to * the existing entry (and the caller can create a list of the * pointers or do anything else). If it didn't exist, return * NULL (and the caller knows the pointer has been inserted). */ static void **insert_hash_entry(unsigned int hash, void *ptr, struct hash_table *table) { struct hash_table_entry *entry = lookup_hash_entry(hash, table); if (!entry->ptr) { entry->ptr = ptr; entry->hash = hash; table->nr++; return NULL; } return &entry->ptr; } static void grow_hash_table(struct hash_table *table) { unsigned int i; unsigned int old_size = table->size, new_size; struct hash_table_entry *old_array = table->array, *new_array; new_size = alloc_nr(old_size); new_array = calloc(sizeof(struct hash_table_entry), new_size); table->size = new_size; table->array = new_array; table->nr = 0; for (i = 0; i < old_size; i++) { unsigned int hash = old_array[i].hash; void *ptr = old_array[i].ptr; if (ptr) insert_hash_entry(hash, ptr, table); } free(old_array); } void *lookup_hash(unsigned int hash, const struct hash_table *table) { if (!table->array) return NULL; return lookup_hash_entry(hash, table)->ptr; } void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table) { unsigned int nr = table->nr; if (nr >= table->size/2) grow_hash_table(table); return insert_hash_entry(hash, ptr, table); } int for_each_hash(const struct hash_table *table, int (*fn)(void *, void *), void *data) { int sum = 0; unsigned int i; unsigned int size = table->size; struct hash_table_entry *array = table->array; for (i = 0; i < size; i++) { void *ptr = array->ptr; array++; if (ptr) { int val = fn(ptr, data); if (val < 0) return val; sum += val; } } return sum; } void free_hash(struct hash_table *table) { free(table->array); table->array = NULL; table->size = 0; table->nr = 0; } seafile-6.1.5/common/index/hash.h000066400000000000000000000022531323477647300166500ustar00rootroot00000000000000#ifndef HASH_H #define HASH_H /* * These are some simple generic hash table helper functions. * Not necessarily suitable for all users, but good for things * where you want to just keep track of a list of things, and * have a good hash to use on them. * * It keeps the hash table at roughly 50-75% free, so the memory * cost of the hash table itself is roughly * * 3 * 2*sizeof(void *) * nr_of_objects * * bytes. * * FIXME: on 64-bit architectures, we waste memory. It would be * good to have just 32-bit pointers, requiring a special allocator * for hashed entries or something. */ struct hash_table_entry { unsigned int hash; void *ptr; }; struct hash_table { unsigned int size, nr; struct hash_table_entry *array; }; extern void *lookup_hash(unsigned int hash, const struct hash_table *table); extern void **insert_hash(unsigned int hash, void *ptr, struct hash_table *table); extern int for_each_hash(const struct hash_table *table, int (*fn)(void *, void *), void *data); extern void free_hash(struct hash_table *table); static inline void init_hash(struct hash_table *table) { table->size = 0; table->nr = 0; table->array = NULL; } #endif seafile-6.1.5/common/index/index.c000066400000000000000000001634641323477647300170430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * GIT - The information manager from hell * * Copyright (C) Linus Torvalds, 2005 */ #define NO_THE_INDEX_COMPATIBILITY_MACROS #ifdef HAVE_CONFIG_H #include #endif #include "common.h" #include "utils.h" #include "log.h" #include "index.h" #include "../seafile-crypt.h" /* #include "../vc-utils.h" */ /* #include "cache-tree.h" */ #include #include #ifdef WIN32 void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { HANDLE hmap; void *temp; uint64_t o = offset; uint32_t l = o & 0xFFFFFFFF; uint32_t h = (o >> 32) & 0xFFFFFFFF; hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), 0, PAGE_WRITECOPY, 0, 0, 0); if (!hmap) { seaf_warning ("CreateFileMapping error: %lu.\n", GetLastError()); return MAP_FAILED; } temp = MapViewOfFileEx(hmap, FILE_MAP_COPY, h, l, length, start); if (!temp) seaf_warning ("MapViewOfFileEx error: %lu.\n", GetLastError()); if (!CloseHandle(hmap)) seaf_warning ("unable to close file mapping handle\n"); return temp ? temp : MAP_FAILED; } int git_munmap(void *start, size_t length) { return !UnmapViewOfFile(start); } #endif //for WIN32 static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce) { istate->cache[nr] = ce; add_name_hash(istate, ce); } static void replace_index_entry(struct index_state *istate, int nr, struct cache_entry *ce) { struct cache_entry *old = istate->cache[nr]; remove_name_hash(istate, old); cache_entry_free (old); set_index_entry(istate, nr, ce); istate->cache_changed = 1; } static int verify_hdr(struct cache_header *hdr, unsigned long size) { GChecksum *c; unsigned char sha1[20]; gsize len = 20; if (hdr->hdr_signature != htonl(CACHE_SIGNATURE)) { g_critical("bad signature\n"); return -1; } if (hdr->hdr_version != htonl(2) && hdr->hdr_version != htonl(3) && hdr->hdr_version != htonl(4)) { g_critical("bad index version\n"); return -1; } c = g_checksum_new (G_CHECKSUM_SHA1); g_checksum_update(c, (unsigned char *)hdr, size - 20); g_checksum_get_digest (c, sha1, &len); g_checksum_free (c); if (hashcmp(sha1, (unsigned char *)hdr + size - 20)) { g_critical("bad index file sha1 signature\n"); return -1; } return 0; } static int convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry **ce) { size_t len; const char *name; unsigned int flags = 0; struct cache_entry *ret; flags = ntohs(ondisk->flags); len = flags & CE_NAMEMASK; /* if (flags & CE_EXTENDED) { */ /* struct ondisk_cache_entry_extended *ondisk2; */ /* int extended_flags; */ /* ondisk2 = (struct ondisk_cache_entry_extended *)ondisk; */ /* extended_flags = ntohs(ondisk2->flags2) << 16; */ /* /\* We do not yet understand any bit out of CE_EXTENDED_FLAGS *\/ */ /* if (extended_flags & ~CE_EXTENDED_FLAGS) { */ /* g_critical("Unknown index entry format %08x\n", extended_flags); */ /* return -1; */ /* } */ /* flags |= extended_flags; */ /* name = ondisk2->name; */ /* } */ /* else */ name = ondisk->name; if (len == CE_NAMEMASK) len = strlen(name); ret = calloc(1, cache_entry_size(len)); ret->ce_ctime.sec = ntohl(ondisk->ctime.sec); ret->ce_mtime.sec = ntohl(ondisk->mtime.sec); ret->ce_dev = ntohl(ondisk->dev); ret->ce_ino = ntohl(ondisk->ino); ret->ce_mode = ntohl(ondisk->mode); ret->ce_uid = ntohl(ondisk->uid); ret->ce_gid = ntohl(ondisk->gid); ret->ce_size = ntoh64(ondisk->size); /* On-disk flags are just 16 bits */ ret->ce_flags = flags; hashcpy(ret->sha1, ondisk->sha1); /* * NEEDSWORK: If the original index is crafted, this copy could * go unchecked. */ memcpy(ret->name, name, len + 1); *ce = ret; return 0; } static int convert_from_disk2(struct ondisk_cache_entry2 *ondisk, struct cache_entry **ce) { size_t len; const char *name; unsigned int flags = 0; struct cache_entry *ret; flags = ntohs(ondisk->flags); len = flags & CE_NAMEMASK; name = ondisk->name; if (len == CE_NAMEMASK) len = strlen(name); ret = calloc(1, cache_entry_size(len)); ret->ce_ctime.sec = ntoh64(ondisk->ctime.sec); ret->ce_mtime.sec = ntoh64(ondisk->mtime.sec); ret->ce_dev = ntohl(ondisk->dev); ret->ce_ino = ntohl(ondisk->ino); ret->ce_mode = ntohl(ondisk->mode); ret->ce_uid = ntohl(ondisk->uid); ret->ce_gid = ntohl(ondisk->gid); ret->ce_size = ntoh64(ondisk->size); /* On-disk flags are just 16 bits */ ret->ce_flags = flags; hashcpy(ret->sha1, ondisk->sha1); /* * NEEDSWORK: If the original index is crafted, this copy could * go unchecked. */ memcpy(ret->name, name, len + 1); *ce = ret; return 0; } static int read_modifiers (struct index_state *istate, void *data, unsigned int size) { char *p = data, *sep = data, *modifier; unsigned int i; unsigned int idx = 0; for (i = 0; i < size; ++i) { if (*sep == '\n') { while (idx < istate->cache_nr && S_ISDIR(istate->cache[idx]->ce_mode)) ++idx; if (idx >= istate->cache_nr) { seaf_warning ("More modifiers than cache entries.\n"); return -1; } modifier = g_strndup(p, sep - p); istate->cache[idx]->modifier = modifier; idx++; p = sep + 1; } ++sep; } while (idx < istate->cache_nr && S_ISDIR(istate->cache[idx]->ce_mode)) ++idx; if (idx != istate->cache_nr) { seaf_warning ("Less modifiers than cached entries.\n"); return -1; } istate->has_modifier = 1; return 0; } static int read_index_extension(struct index_state *istate, unsigned int ext, void *data, unsigned int sz) { switch (ext) { case CACHE_EXT_MODIFIER: return read_modifiers (istate, data, sz); default: g_critical("unknown extension %u.\n", ext); break; } return 0; } static void alloc_index (struct index_state *istate) { istate->cache_alloc = alloc_nr(istate->cache_nr); istate->cache = calloc(istate->cache_alloc, sizeof(struct cache_entry *)); istate->name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); #if defined WIN32 || defined __APPLE__ istate->i_name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); #endif istate->initialized = 1; istate->name_hash_initialized = 1; } /* remember to discard_cache() before reading a different cache! */ int read_index_from(struct index_state *istate, const char *path, int repo_version) { int fd, i; SeafStat st; unsigned long src_offset; struct cache_header *hdr; void *mm; size_t mmap_size; if (istate->initialized) return istate->cache_nr; /* All newly created index files are version 4. */ istate->version = 4; /* Index file stores modifier info if repo version > 0 */ if (repo_version > 0) istate->has_modifier = 1; istate->timestamp.sec = 0; istate->timestamp.nsec = 0; fd = seaf_util_open (path, O_RDONLY | O_BINARY); if (fd < 0) { if (errno == ENOENT) { alloc_index (istate); return 0; } g_critical("index file open failed\n"); return -1; } if (seaf_fstat(fd, &st)) { g_critical("cannot stat the open index\n"); close(fd); return -1; } mmap_size = (size_t)st.st_size; if (mmap_size < sizeof(struct cache_header) + 20) { g_critical("index file smaller than expected\n"); close(fd); return -1; } mm = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); close(fd); if (mm == MAP_FAILED) { g_critical("unable to map index file\n"); return -1; } hdr = mm; if (verify_hdr(hdr, mmap_size) < 0) goto unmap; /* Index version will be set to on-disk value here. * If the index is from an old repo, it will be set to 2. * But when we write the index, it'll be updated to version 4. */ istate->version = ntohl(hdr->hdr_version); istate->cache_nr = ntohl(hdr->hdr_entries); alloc_index (istate); /* * The disk format is actually larger than the in-memory format, * due to space for nsec etc, so even though the in-memory one * has room for a few more flags, we can allocate using the same * index size */ src_offset = sizeof(*hdr); for (i = 0; i < istate->cache_nr; i++) { struct ondisk_cache_entry *disk_ce; struct ondisk_cache_entry2 *disk_ce2; struct cache_entry *ce; if (istate->version < 4) { disk_ce = (struct ondisk_cache_entry *)((char *)mm + src_offset); /* allocate each ce separately so that we can free new * entries added by add_index_entry() later. */ if (convert_from_disk(disk_ce, &ce) < 0) return -1; src_offset += ondisk_ce_size(ce); } else { disk_ce2 = (struct ondisk_cache_entry2 *)((char *)mm + src_offset); /* allocate each ce separately so that we can free new * entries added by add_index_entry() later. */ if (convert_from_disk2(disk_ce2, &ce) < 0) return -1; src_offset += ondisk_ce_size2(ce); } set_index_entry(istate, i, ce); } istate->timestamp.sec = st.st_mtime; istate->timestamp.nsec = 0; while (src_offset <= mmap_size - 20 - sizeof(struct cache_ext_hdr)) { /* After an array of active_nr index entries, * there can be arbitrary number of extended * sections, each of which is prefixed with * extension name (4-byte) and section length * in 4-byte network byte order. */ struct cache_ext_hdr *exthdr; exthdr = (struct cache_ext_hdr *) ((char *)mm + src_offset); unsigned int name = ntohl(exthdr->ext_name); unsigned int size = ntohl(exthdr->ext_size); if (read_index_extension(istate, name, (char *) mm + src_offset + sizeof(struct cache_ext_hdr), size) < 0) goto unmap; src_offset += sizeof(struct cache_ext_hdr); src_offset += size; } munmap(mm, mmap_size); return istate->cache_nr; unmap: munmap(mm, mmap_size); g_critical("index file corrupt\n"); return -1; } int is_index_unborn(struct index_state *istate) { return (!istate->cache_nr && !istate->alloc && !istate->timestamp.sec); } int unmerged_index(const struct index_state *istate) { int i; for (i = 0; i < istate->cache_nr; i++) { if (ce_stage(istate->cache[i])) return 1; } return 0; } int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2) { int len1 = flags1 & CE_NAMEMASK; int len2 = flags2 & CE_NAMEMASK; int len = len1 < len2 ? len1 : len2; int cmp; cmp = memcmp(name1, name2, len); if (cmp) return cmp; if (len1 < len2) return -1; if (len1 > len2) return 1; /* Compare stages */ flags1 &= CE_STAGEMASK; flags2 &= CE_STAGEMASK; if (flags1 < flags2) return -1; if (flags1 > flags2) return 1; return 0; } /* * This only updates the "non-critical" parts of the directory * cache, ie the parts that aren't tracked by GIT, and only used * to validate the cache. */ void fill_stat_cache_info(struct cache_entry *ce, SeafStat *st) { ce->ce_ctime.sec = st->st_ctime; ce->ce_mtime.sec = st->st_mtime; ce->ce_ctime.nsec = 0; ce->ce_mtime.nsec = 0; ce->ce_dev = st->st_dev; ce->ce_ino = st->st_ino; ce->ce_uid = st->st_uid; ce->ce_gid = st->st_gid; ce->ce_size = st->st_size; /* if (assume_unchanged) */ /* ce->ce_flags |= CE_VALID; */ if (S_ISREG(st->st_mode)) ce_mark_uptodate(ce); } void mark_all_ce_unused(struct index_state *index) { int i; for (i = 0; i < index->cache_nr; i++) index->cache[i]->ce_flags &= ~(CE_UNPACKED | CE_ADDED | CE_NEW_SKIP_WORKTREE); } static gboolean is_eml_file (const char *path) { int len = strlen(path); const char *ext; if (len < 5) return FALSE; ext = &path[len-4]; return (strcasecmp (ext, ".eml") == 0); } static int ce_match_stat_basic(struct cache_entry *ce, SeafStat *st) { unsigned int changed = 0; if (ce->ce_flags & CE_REMOVE) return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED; switch (ce->ce_mode & S_IFMT) { case S_IFREG: changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0; /* We consider only the owner x bit to be relevant for * "mode changes" */ #ifndef WIN32 if ((0100 & (ce->ce_mode ^ st->st_mode))) changed |= MODE_CHANGED; #endif break; case S_IFLNK: if (!S_ISLNK(st->st_mode)) changed |= TYPE_CHANGED; break; case S_IFGITLINK: /* We ignore most of the st_xxx fields for gitlinks */ if (!S_ISDIR(st->st_mode)) changed |= TYPE_CHANGED; /* else if (ce_compare_gitlink(ce)) */ /* changed |= DATA_CHANGED; */ return changed; default: seaf_warning("internal error: ce_mode is %o\n", ce->ce_mode); return -1; } if (!is_eml_file (ce->name) && ce->ce_mtime.sec != st->st_mtime) changed |= MTIME_CHANGED; /* if (ce->ce_ctime.sec != st->st_ctime) */ /* changed |= CTIME_CHANGED; */ if (ce->ce_size != st->st_size) changed |= DATA_CHANGED; #if 0 if (ce->ce_uid != (unsigned int) st->st_uid || ce->ce_gid != (unsigned int) st->st_gid) changed |= OWNER_CHANGED; if (ce->ce_ino != (unsigned int) st->st_ino) changed |= INODE_CHANGED; /* Racily smudged entry? */ if (!ce->ce_size) { if (!is_empty_blob_sha1(ce->sha1)) changed |= DATA_CHANGED; } #endif return changed; } #if 0 static int is_racy_timestamp(const struct index_state *istate, struct cache_entry *ce) { return (!S_ISGITLINK(ce->ce_mode) && istate->timestamp.sec && #ifdef USE_NSEC /* nanosecond timestamped files can also be racy! */ (istate->timestamp.sec < ce->ce_mtime.sec || (istate->timestamp.sec == ce->ce_mtime.sec && istate->timestamp.nsec <= ce->ce_mtime.nsec)) #else istate->timestamp.sec <= ce->ce_mtime.sec #endif ); } #endif #if 0 static int ce_compare_data(struct cache_entry *ce, SeafStat *st) { int match = -1; int fd = g_open (ce->name, O_RDONLY | O_BINARY); if (fd >= 0) { unsigned char sha1[20]; if (!index_fd(sha1, fd, st, OBJ_BLOB, ce->name)) match = hashcmp(sha1, ce->sha1); /* index_fd() closed the file descriptor already */ } return match; } static int ce_compare_link(struct cache_entry *ce, SeafStat *st) { int match = -1; unsigned char sha1[20]; if (!index_path(sha1, ce->name, st)) match = hashcmp(sha1, ce->sha1); return match; } static int ce_modified_check_fs(struct cache_entry *ce, SeafStat *st) { switch (st->st_mode & S_IFMT) { case S_IFREG: if (ce_compare_data(ce, st)) return DATA_CHANGED; break; case S_IFLNK: if (ce_compare_link(ce, st)) return DATA_CHANGED; break; default: return TYPE_CHANGED; } return 0; } #endif int ie_match_stat(struct cache_entry *ce, SeafStat *st, unsigned int options) { unsigned int changed; int ignore_valid = options & CE_MATCH_IGNORE_VALID; int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE; /* int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY; */ /* * If it's marked as always valid in the index, it's * valid whatever the checked-out copy says. * * skip-worktree has the same effect with higher precedence */ if (!ignore_skip_worktree && ce_skip_worktree(ce)) return 0; if (!ignore_valid && (ce->ce_flags & CE_VALID)) return 0; /* * Intent-to-add entries have not been added, so the index entry * by definition never matches what is in the work tree until it * actually gets added. */ /* if (ce->ce_flags & CE_INTENT_TO_ADD) */ /* return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED; */ changed = ce_match_stat_basic(ce, st); /* * Within 1 second of this sequence: * echo xyzzy >file && git-update-index --add file * running this command: * echo frotz >file * would give a falsely clean cache entry. The mtime and * length match the cache, and other stat fields do not change. * * We could detect this at update-index time (the cache entry * being registered/updated records the same time as "now") * and delay the return from git-update-index, but that would * effectively mean we can make at most one commit per second, * which is not acceptable. Instead, we check cache entries * whose mtime are the same as the index file timestamp more * carefully than others. */ #if 0 if (!changed && is_racy_timestamp(istate, ce)) { /* if (assume_racy_is_modified) */ /* changed |= DATA_CHANGED; */ /* else */ /* changed |= ce_modified_check_fs(ce, st); */ changed = DATA_CHANGED; } #endif return changed; } /* * df_name_compare() is identical to base_name_compare(), except it * compares conflicting directory/file entries as equal. Note that * while a directory name compares as equal to a regular file, they * then individually compare _differently_ to a filename that has * a dot after the basename (because '\0' < '.' < '/'). * * This is used by routines that want to traverse the git namespace * but then handle conflicting entries together when possible. */ int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2) { int len = len1 < len2 ? len1 : len2, cmp; unsigned char c1, c2; cmp = memcmp(name1, name2, len); if (cmp) return cmp; /* Directories and files compare equal (same length, same name) */ if (len1 == len2) return 0; c1 = name1[len]; if (!c1 && S_ISDIR(mode1)) c1 = '/'; c2 = name2[len]; if (!c2 && S_ISDIR(mode2)) c2 = '/'; if (c1 == '/' && !c2) return 0; if (c2 == '/' && !c1) return 0; return c1 - c2; } int index_name_pos(const struct index_state *istate, const char *name, int namelen) { int first, last; first = 0; last = istate->cache_nr; while (last > first) { int next = (last + first) >> 1; struct cache_entry *ce = istate->cache[next]; int cmp = cache_name_compare(name, namelen, ce->name, ce->ce_flags); if (!cmp) return next; if (cmp < 0) { last = next; continue; } first = next+1; } return -first-1; } /* Remove entry, return true if there are more entries to go.. */ int remove_index_entry_at(struct index_state *istate, int pos) { struct cache_entry *ce = istate->cache[pos]; /* record_resolve_undo(istate, ce); */ remove_name_hash(istate, ce); cache_entry_free (ce); istate->cache_changed = 1; istate->cache_nr--; if (pos >= istate->cache_nr) return 0; memmove(istate->cache + pos, istate->cache + pos + 1, (istate->cache_nr - pos) * sizeof(struct cache_entry *)); return 1; } /* * Remove all cache ententries marked for removal, that is where * CE_REMOVE is set in ce_flags. This is much more effective than * calling remove_index_entry_at() for each entry to be removed. */ void remove_marked_cache_entries(struct index_state *istate) { struct cache_entry **ce_array = istate->cache; unsigned int i, j; gboolean removed = FALSE; for (i = j = 0; i < istate->cache_nr; i++) { if (ce_array[i]->ce_flags & CE_REMOVE) { remove_name_hash(istate, ce_array[i]); cache_entry_free (ce_array[i]); removed = TRUE; } else { ce_array[j++] = ce_array[i]; } } if (removed) { istate->cache_changed = 1; istate->cache_nr = j; } } int remove_file_from_index(struct index_state *istate, const char *path) { int pos = index_name_pos(istate, path, strlen(path)); if (pos < 0) pos = -pos-1; /* cache_tree_invalidate_path(istate->cache_tree, path); */ while (pos < istate->cache_nr && !strcmp(istate->cache[pos]->name, path)) remove_index_entry_at(istate, pos); return 0; } int ce_same_name(struct cache_entry *a, struct cache_entry *b) { int len = ce_namelen(a); return ce_namelen(b) == len && !memcmp(a->name, b->name, len); } int ce_path_match(const struct cache_entry *ce, const char **pathspec) { const char *match, *name; int len; if (!pathspec) return 1; len = ce_namelen(ce); name = ce->name; while ((match = *pathspec++) != NULL) { int matchlen = strlen(match); if (matchlen > len) continue; if (memcmp(name, match, matchlen)) continue; if (matchlen && name[matchlen-1] == '/') return 1; if (name[matchlen] == '/' || !name[matchlen]) return 1; if (!matchlen) return 1; } return 0; } /* * We fundamentally don't like some paths: we don't want * dot or dot-dot anywhere, and for obvious reasons don't * want to recurse into ".git" either. * * Also, we don't want double slashes or slashes at the * end that can make pathnames ambiguous. */ static int verify_dotfile(const char *rest) { /* * The first character was '.', but that * has already been discarded, we now test * the rest. */ switch (*rest) { /* "." is not allowed */ case '\0': case '/': return 0; /* * ".git" followed by NUL or slash is bad. This * shares the path end test with the ".." case. */ case 'g': if (rest[1] != 'i') break; if (rest[2] != 't') break; rest += 2; /* fallthrough */ case '.': if (rest[1] == '\0' || rest[1] == '/') return 0; } return 1; } int verify_path(const char *path) { char c; goto inside; for (;;) { if (!c) return 1; if (c == '/') { inside: c = *path++; switch (c) { default: continue; case '/': case '\0': break; case '.': if (verify_dotfile(path)) continue; } return 0; } c = *path++; } } void remove_empty_parent_dir_entry (struct index_state *istate, const char *path) { char *parent = g_strdup(path); char *slash; /* Find and remove empty dir entry from low level to top level. */ while (1) { slash = strrchr (parent, '/'); if (!slash) break; *slash = 0; if (index_name_exists (istate, parent, strlen(parent), 0) != NULL) { remove_file_from_index (istate, parent); break; } } g_free (parent); } static int add_index_entry_with_check(struct index_state *istate, struct cache_entry *ce, int option) { int pos; int ok_to_add = option & ADD_CACHE_OK_TO_ADD; /* int ok_to_replace = option & ADD_CACHE_OK_TO_REPLACE; */ /* int skip_df_check = option & ADD_CACHE_SKIP_DFCHECK; */ int new_only = option & ADD_CACHE_NEW_ONLY; remove_empty_parent_dir_entry (istate, ce->name); pos = index_name_pos(istate, ce->name, ce->ce_flags); /* existing match? Just replace it. */ if (pos >= 0) { if (!new_only) replace_index_entry(istate, pos, ce); return 0; } pos = -pos-1; /* * Inserting a merged entry ("stage 0") into the index * will always replace all non-merged entries.. */ if (pos < istate->cache_nr && ce_stage(ce) == 0) { while (ce_same_name(istate->cache[pos], ce)) { ok_to_add = 1; if (!remove_index_entry_at(istate, pos)) break; } } if (!ok_to_add) return -1; /* if (!verify_path(ce->name)) { */ /* seaf_warning("Invalid path '%s'\n", ce->name); */ /* return -1; */ /* } */ /* if (!skip_df_check && */ /* check_file_directory_conflict(istate, ce, pos, ok_to_replace)) { */ /* if (!ok_to_replace) */ /* return error("'%s' appears as both a file and as a directory", */ /* ce->name); */ /* pos = index_name_pos(istate, ce->name, ce->ce_flags); */ /* pos = -pos-1; */ /* } */ return pos + 1; } int add_index_entry(struct index_state *istate, struct cache_entry *ce, int option) { int pos; if (option & ADD_CACHE_JUST_APPEND) pos = istate->cache_nr; else { int ret; ret = add_index_entry_with_check(istate, ce, option); if (ret <= 0) return ret; pos = ret - 1; } /* Make sure the array is big enough .. */ if (istate->cache_nr == istate->cache_alloc) { istate->cache_alloc = alloc_nr(istate->cache_alloc); istate->cache = realloc(istate->cache, istate->cache_alloc * sizeof(struct cache_entry *)); } /* Add it in.. */ istate->cache_nr++; if (istate->cache_nr > pos + 1) memmove(istate->cache + pos + 1, istate->cache + pos, (istate->cache_nr - pos - 1) * sizeof(ce)); set_index_entry(istate, pos, ce); istate->cache_changed = 1; return 0; } int add_to_index(const char *repo_id, int version, struct index_state *istate, const char *path, const char *full_path, SeafStat *st, int flags, SeafileCrypt *crypt, IndexCB index_cb, const char *modifier, gboolean *added) { int size, namelen; mode_t st_mode = st->st_mode; struct cache_entry *ce, *alias; unsigned char sha1[20]; unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE|CE_MATCH_RACY_IS_DIRTY; int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); *added = FALSE; if (!S_ISREG(st_mode) && !S_ISLNK(st_mode) && !S_ISDIR(st_mode)) { seaf_warning("%s: can only add regular files, symbolic links or git-directories\n", path); return -1; } namelen = strlen(path); /* if (S_ISDIR(st_mode)) { */ /* while (namelen && path[namelen-1] == '/') */ /* namelen--; */ /* } */ size = cache_entry_size(namelen); ce = calloc(1, size); memcpy(ce->name, path, namelen); ce->ce_flags = namelen; fill_stat_cache_info(ce, st); ce->ce_mode = create_ce_mode(st_mode); alias = index_name_exists(istate, ce->name, ce_namelen(ce), 0); if (alias) { if (!ce_stage(alias) && !ie_match_stat(alias, st, ce_option)) { free(ce); return 0; } } else { #if defined WIN32 || defined __APPLE__ alias = index_name_exists (istate, ce->name, ce_namelen(ce), 1); /* If file exists case-insensitively but doesn't exist case-sensitively, * that file is actually being renamed. */ if (alias) { remove_file_from_index (istate, alias->name); alias = NULL; } #endif } #ifdef WIN32 /* On Windows, no 'x' bit in file mode. * To prevent overwriting 'x' bit, we directly use existing ce mode. */ if (alias) ce->ce_mode = alias->ce_mode; #endif #if 0 #ifdef WIN32 /* Fix daylight saving time bug on Windows. * See http://www.codeproject.com/Articles/1144/Beating-the-Daylight-Savings-Time-bug-and-getting * If ce and wt timestamp has a 1 hour gap, it may be affected by the bug. * We then compare the file's id with the id in ce. If they're the same, * we don't need to copy the blocks again. Only update the index. */ if (alias && !ce_stage(alias) && (ABS(alias->ce_mtime.sec - st->st_mtime) == 3600 || ABS(alias->ce_ctime.sec - st->st_ctime) == 3600)) { if (index_cb (repo_id, version, full_path, sha1, crypt, FALSE) < 0) { free (ce); return 0; } if (memcmp (alias->sha1, sha1, 20) == 0) goto update_index; } #endif #endif /* 0 */ if (index_cb (repo_id, version, full_path, sha1, crypt, TRUE) < 0) { free (ce); return -1; } memcpy (ce->sha1, sha1, 20); ce->ce_flags |= CE_ADDED; ce->modifier = g_strdup(modifier); if (add_index_entry(istate, ce, add_option)) { seaf_warning("unable to add %s to index\n",path); return -1; } /* As long as the timestamp or mode is changed, we consider the cache enrty as changed. This has been tested by ie_match_stat(). */ *added = TRUE; return 0; } /* * Check whether the empty dir conflicts with existing files */ static int is_garbage_empty_dir (struct index_state *istate, struct cache_entry *ce) { int ret = 0; int pos = index_name_pos (istate, ce->name, ce->ce_flags); /* Empty folder already exists in the index. */ if (pos >= 0) return 0; /* -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ pos = -pos-1; struct cache_entry *next; char *dir_name = g_strconcat (ce->name, "/", NULL); int this_len = strlen (ce->name) + 1; while (pos < istate->cache_nr) { next = istate->cache[pos]; int rc = strncmp (next->name, dir_name, this_len); if (rc == 0) { ret = 1; break; } else if (rc < 0) { ++pos; } else break; } g_free (dir_name); return ret; } static struct cache_entry * create_empty_dir_index_entry (const char *path, SeafStat *st) { int namelen, size; struct cache_entry *ce; namelen = strlen(path); size = cache_entry_size(namelen); ce = calloc(1, size); memcpy(ce->name, path, namelen); ce->ce_flags = namelen; ce->ce_mtime.sec = st->st_mtime; ce->ce_ctime.sec = st->st_ctime; ce->ce_mode = S_IFDIR; /* sha1 is all-zero. */ return ce; } int add_empty_dir_to_index (struct index_state *istate, const char *path, SeafStat *st) { struct cache_entry *ce, *alias; int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); ce = create_empty_dir_index_entry (path, st); if (is_garbage_empty_dir (istate, ce)) { free (ce); return 0; } alias = index_name_exists(istate, ce->name, ce_namelen(ce), 0); if (alias) { free (ce); return 0; } else { #if defined WIN32 || defined __APPLE__ alias = index_name_exists (istate, ce->name, ce_namelen(ce), 1); /* If file exists case-insensitively but doesn't exist case-sensitively, * that file is actually being renamed. */ if (alias) { remove_file_from_index (istate, alias->name); alias = NULL; } #endif } ce->ce_flags |= CE_ADDED; if (add_index_entry(istate, ce, add_option)) { seaf_warning("unable to add %s to index\n",path); free (ce); return -1; } return 1; } int remove_from_index_with_prefix (struct index_state *istate, const char *path_prefix, gboolean *not_found) { int pathlen = strlen(path_prefix); int pos = index_name_pos (istate, path_prefix, pathlen); struct cache_entry *ce; if (not_found) *not_found = FALSE; /* Exact match, remove that entry. */ if (pos >= 0) { remove_index_entry_at (istate, pos); return 0; } /* Otherwise it may be a prefix match, remove all entries begin with this prefix. */ /* -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ pos = -pos-1; /* Add '/' to the end of prefix so that we won't match a partial path component. * e.g. we don't want to match 'abc' with 'abcd/ef' */ char *full_path_prefix = g_strconcat (path_prefix, "/", NULL); ++pathlen; while (pos < istate->cache_nr) { ce = istate->cache[pos]; if (strncmp (ce->name, full_path_prefix, pathlen) < 0) { ++pos; } else break; } if (pos == istate->cache_nr) { g_free (full_path_prefix); if (not_found) *not_found = TRUE; return 0; } int i = pos; while (i < istate->cache_nr) { ce = istate->cache[i]; if (strncmp (ce->name, full_path_prefix, pathlen) == 0) { remove_name_hash(istate, ce); cache_entry_free (ce); ++i; } else break; } g_free (full_path_prefix); /* No match. */ if (i == pos) { if (not_found) *not_found = TRUE; return 0; } if (i < istate->cache_nr) memmove (istate->cache + pos, istate->cache + i, (istate->cache_nr - i) * sizeof(struct cache_entry *)); istate->cache_nr -= (i - pos); istate->cache_changed = 1; return 0; } static struct cache_entry * create_renamed_cache_entry (struct cache_entry *ce, const char *src_path, const char *dst_path) { struct cache_entry *new_ce; char *new_ce_name; int src_pathlen = strlen(src_path); new_ce_name = g_strconcat (dst_path, &ce->name[src_pathlen], NULL); int namelen = strlen(new_ce_name); int size = cache_entry_size (namelen); new_ce = calloc (size, 1); memcpy (new_ce, ce, sizeof(struct cache_entry)); new_ce->ce_flags = namelen; new_ce->current_mtime = 0; new_ce->modifier = g_strdup(ce->modifier); new_ce->next = NULL; memcpy (new_ce->name, new_ce_name, namelen); g_free (new_ce_name); return new_ce; } static struct cache_entry ** create_renamed_cache_entries (struct index_state *istate, const char *src_path, const char *dst_path, int *n_entries, CECallback cb_after_rename, void *user_data) { struct cache_entry *ce, **ret = NULL; int src_pathlen = strlen(src_path); int pos = index_name_pos (istate, src_path, src_pathlen); /* Exact match, rename that entry. */ if (pos >= 0) { ce = istate->cache[pos]; ret = calloc (1, sizeof(struct cache_entry *)); *ret = create_renamed_cache_entry (ce, src_path, dst_path); *n_entries = 1; remove_index_entry_at (istate, pos); return ret; } /* Otherwise it may be a prefix match, rename all entries begin with this prefix. */ /* -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ pos = -pos-1; /* Add '/' to the end of prefix so that we won't match a partial path component. * e.g. we don't want to match 'abc' with 'abcd/ef' */ char *full_src_path = g_strconcat (src_path, "/", NULL); ++src_pathlen; while (pos < istate->cache_nr) { ce = istate->cache[pos]; if (strncmp (ce->name, full_src_path, src_pathlen) < 0) { ++pos; } else break; } if (pos == istate->cache_nr) { g_free (full_src_path); *n_entries = 0; return NULL; } int i = pos; while (i < istate->cache_nr) { ce = istate->cache[i]; if (strncmp (ce->name, full_src_path, src_pathlen) == 0) { ++i; } else break; } g_free (full_src_path); if (i == pos) { *n_entries = 0; return NULL; } *n_entries = (i - pos); ret = calloc (*n_entries, sizeof(struct cache_entry *)); for (i = pos; i < pos + *n_entries; ++i) { ce = istate->cache[i]; ret[i - pos] = create_renamed_cache_entry (ce, src_path, dst_path); if (cb_after_rename) cb_after_rename (ret[i-pos], user_data); remove_name_hash(istate, ce); cache_entry_free (ce); } if (i < istate->cache_nr) memmove (istate->cache + pos, istate->cache + i, (istate->cache_nr - i) * sizeof(struct cache_entry *)); istate->cache_nr -= (i - pos); istate->cache_changed = 1; return ret; } int rename_index_entries (struct index_state *istate, const char *src_path, const char *dst_path, gboolean *not_found, CECallback cb_after_rename, void *cb_data) { struct cache_entry **new_ces; int n_entries; int ret = 0; int i; if (not_found) *not_found = FALSE; new_ces = create_renamed_cache_entries (istate, src_path, dst_path, &n_entries, cb_after_rename, cb_data); if (n_entries == 0) { if (not_found) *not_found = TRUE; return 0; } /* Remove entries under dst_path. It's necessary for the situation that * one file is renamed to overwrite another file. */ remove_from_index_with_prefix (istate, dst_path, NULL); remove_empty_parent_dir_entry (istate, dst_path); /* Insert the renamed entries to their position. */ int dst_pathlen = strlen(dst_path); int pos = index_name_pos (istate, dst_path, dst_pathlen); if (pos >= 0) { seaf_warning ("BUG: %s should not exist in index after remove.\n", dst_path); ret = -1; goto out; } pos = -pos-1; /* There should be at least n_entries free room in istate->cache array, * since we just removed n_entries from the index in * create_renamed_cache_entires(). */ if (istate->cache_alloc - istate->cache_nr < n_entries) { seaf_warning ("BUG: not enough room to insert renamed entries.\n" "cache_alloc: %u, cache_nr: %u, n_entries: %d.\n", istate->cache_alloc, istate->cache_nr, n_entries); ret = -1; goto out; } if (pos < istate->cache_nr) memmove (istate->cache + pos + n_entries, istate->cache + pos, (istate->cache_nr - pos) * sizeof(struct cache_entry *)); memcpy (istate->cache + pos, new_ces, n_entries * sizeof(struct cache_entry *)); for (i = 0; i < n_entries; ++i) add_name_hash (istate, new_ces[i]); istate->cache_nr += n_entries; istate->cache_changed = 1; out: if (ret < 0) { for (i = 0; i < n_entries; ++i) cache_entry_free (new_ces[i]); } free (new_ces); return ret; } /* * If there is no file under @path, add an empty dir entry for this @path. */ int add_empty_dir_to_index_with_check (struct index_state *istate, const char *path, SeafStat *st) { int pathlen = strlen(path); int pos = index_name_pos (istate, path, pathlen); struct cache_entry *ce; /* Exact match, empty dir entry already exists. */ if (pos >= 0) { return 0; } /* Otherwise it may be a prefix match, remove all entries begin with this prefix. */ /* -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ pos = -pos-1; /* Add '/' to the end of prefix so that we won't match a partial path component. * e.g. we don't want to match 'abc' with 'abcd/ef' */ char *full_path = g_strconcat (path, "/", NULL); ++pathlen; gboolean is_empty = TRUE; while (pos < istate->cache_nr) { ce = istate->cache[pos]; int rc = strncmp (ce->name, full_path, pathlen); if (rc < 0) { ++pos; } else if (rc == 0) { is_empty = FALSE; break; } else break; } g_free (full_path); if (is_empty) { ce = create_empty_dir_index_entry (path, st); /* Make sure the array is big enough .. */ if (istate->cache_nr == istate->cache_alloc) { istate->cache_alloc = alloc_nr(istate->cache_alloc); istate->cache = realloc(istate->cache, istate->cache_alloc * sizeof(struct cache_entry *)); } /* Add it in.. */ istate->cache_nr++; if (istate->cache_nr > pos + 1) memmove(istate->cache + pos + 1, istate->cache + pos, (istate->cache_nr - pos - 1) * sizeof(ce)); set_index_entry(istate, pos, ce); istate->cache_changed = 1; } return 0; } inline static gboolean is_duplicate_dirent (GList *dirents, const char *dname) { if (!dirents) return FALSE; IndexDirent *dent = dirents->data; return (strcmp(dent->dname, dname) == 0); } static IndexDirent * index_dirent_new (char *dname, gboolean is_dir, struct cache_entry *ce) { IndexDirent *dent = g_new0 (IndexDirent, 1); dent->dname = dname; dent->is_dir = is_dir; if (!is_dir) dent->ce = ce; return dent; } void index_dirent_free (IndexDirent *dent) { if (!dent) return; g_free (dent->dname); g_free (dent); } static gint compare_index_dents (gconstpointer a, gconstpointer b) { const IndexDirent *denta = a, *dentb = b; return (strcmp(denta->dname, dentb->dname)); } GList * list_dirents_from_index (struct index_state *istate, const char *dir) { char *full_dir; int pathlen; int pos; struct cache_entry *ce; GList *dirents = NULL; char *path, *slash, *dname; gboolean is_dir; IndexDirent *dirent; if (dir[0] == 0) { pos = 0; full_dir = g_strdup(dir); pathlen = 0; goto collect_dents; } else { pathlen = strlen(dir); pos = index_name_pos (istate, dir, pathlen); } /* Exact match, it's an empty dir. */ if (pos >= 0) { return NULL; } /* Otherwise it may be a prefix match, there may be dirents under the dir. */ /* -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ pos = -pos-1; /* Add '/' to the end of prefix so that we won't match a partial path component. * e.g. we don't want to match 'abc' with 'abcd/ef' */ full_dir = g_strconcat (dir, "/", NULL); ++pathlen; while (pos < istate->cache_nr) { ce = istate->cache[pos]; if (strncmp (ce->name, full_dir, pathlen) < 0) { ++pos; } else break; } /* The dir actually doesn't exist. */ if (pos == istate->cache_nr) { g_free (full_dir); return NULL; } collect_dents: for (; pos < istate->cache_nr; ++pos) { ce = istate->cache[pos]; if (strncmp (full_dir, ce->name, pathlen) != 0) break; path = ce->name + pathlen; slash = strchr(path, '/'); if (slash) { dname = g_strndup(path, slash - path); if (is_duplicate_dirent (dirents, dname)) { g_free (dname); continue; } dirent = index_dirent_new (dname, TRUE, NULL); dirents = g_list_prepend (dirents, dirent); } else { dname = g_strdup(path); is_dir = S_ISDIR(ce->ce_mode); dirent = index_dirent_new (dname, is_dir, ce); dirents = g_list_prepend (dirents, dirent); } } dirents = g_list_sort (dirents, compare_index_dents); g_free (full_dir); return dirents; } static struct cache_entry *refresh_cache_entry(struct cache_entry *ce, const char *full_path) { SeafStat st; if (seaf_stat (full_path, &st) < 0) { seaf_warning("Failed to stat %s.\n", full_path); return NULL; } fill_stat_cache_info(ce, &st); return ce; } struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, const char *full_path, int stage, int refresh) { int size, len; struct cache_entry *ce; /* if (!verify_path(path)) { */ /* seaf_warning("Invalid path '%s'", path); */ /* return NULL; */ /* } */ len = strlen(path); size = cache_entry_size(len); ce = calloc(1, size); hashcpy(ce->sha1, sha1); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(len, stage); ce->ce_mode = create_ce_mode(mode); if (refresh) return refresh_cache_entry(ce, full_path); return ce; } #if 0 int add_file_to_index(struct index_state *istate, const char *path, int flags) { SeafStat st; if (seaf_stat (path, &st)) { seaf_warning("unable to stat '%s'\n", path); return -1; } return add_to_index(istate, path, &st, flags); } #endif #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) static const char *object_type_strings[] = { NULL, /* OBJ_NONE = 0 */ "commit", /* OBJ_COMMIT = 1 */ "tree", /* OBJ_TREE = 2 */ "blob", /* OBJ_BLOB = 3 */ "tag", /* OBJ_TAG = 4 */ }; static const char *typename(unsigned int type) { if (type >= ARRAY_SIZE(object_type_strings)) return NULL; return object_type_strings[type]; } #if 0 static int type_from_string(const char *str) { int i; for (i = 1; i < ARRAY_SIZE(object_type_strings); i++) if (!strcmp(str, object_type_strings[i])) return i; seaf_warning("invalid object type \"%s\"\n", str); return -1; } #endif static void hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1) { GChecksum *c; gsize cs_len = 20; /* Sha1.. */ c = g_checksum_new (G_CHECKSUM_SHA1); g_checksum_update(c, buf, len); g_checksum_get_digest (c, sha1, &cs_len); g_checksum_free (c); } static int index_mem(unsigned char *sha1, void *buf, uint64_t size, enum object_type type, const char *path) { if (!type) type = OBJ_BLOB; hash_sha1_file(buf, size, typename(type), sha1); return 0; } #define SMALL_FILE_SIZE (32*1024) int index_fd(unsigned char *sha1, int fd, SeafStat *st, enum object_type type, const char *path) { int ret; uint64_t size = st->st_size; if (!size) { ret = index_mem(sha1, NULL, size, type, path); } else if (size <= SMALL_FILE_SIZE) { char *buf = malloc(size); if (size == readn(fd, buf, size)) { ret = index_mem(sha1, buf, size, type, path); } else { seaf_warning("short read %s\n", strerror(errno)); ret = -1; } free(buf); } else { void *buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); ret = index_mem(sha1, buf, size, type, path); munmap(buf, size); } close(fd); return ret; } int index_path(unsigned char *sha1, const char *path, SeafStat *st) { int fd; char buf[SEAF_PATH_MAX]; int pathlen; switch (st->st_mode & S_IFMT) { case S_IFREG: fd = seaf_util_open (path, O_RDONLY | O_BINARY); if (fd < 0) { seaf_warning("g_open (\"%s\"): %s\n", path, strerror(errno)); return -1; } if (index_fd(sha1, fd, st, OBJ_BLOB, path) < 0) { return -1; } break; #ifndef WIN32 case S_IFLNK: pathlen = readlink(path, buf, SEAF_PATH_MAX); if (pathlen != st->st_size) { char *errstr = strerror(errno); seaf_warning("readlink(\"%s\"): %s\n", path, errstr); return -1; } hash_sha1_file(buf, pathlen, typename(OBJ_BLOB), sha1); break; #endif default: seaf_warning("%s: unsupported file type\n", path); return -1; } return 0; } #if 0 static unsigned char write_buffer[WRITE_BUFFER_SIZE]; static unsigned long write_buffer_len; #endif #define WRITE_BUFFER_SIZE 8192 typedef struct { GChecksum *context; unsigned char write_buffer[WRITE_BUFFER_SIZE]; unsigned long write_buffer_len; } WriteIndexInfo; static int ce_write_flush(WriteIndexInfo *info, int fd) { unsigned int buffered = info->write_buffer_len; if (buffered) { g_checksum_update(info->context, info->write_buffer, buffered); if (writen(fd, info->write_buffer, buffered) != buffered) return -1; info->write_buffer_len = 0; } return 0; } static int ce_write(WriteIndexInfo *info, int fd, void *data, unsigned int len) { while (len) { unsigned int buffered = info->write_buffer_len; unsigned int partial = WRITE_BUFFER_SIZE - buffered; if (partial > len) partial = len; memcpy(info->write_buffer + buffered, data, partial); buffered += partial; if (buffered == WRITE_BUFFER_SIZE) { info->write_buffer_len = buffered; if (ce_write_flush(info, fd)) return -1; buffered = 0; } info->write_buffer_len = buffered; len -= partial; data = (char *) data + partial; } return 0; } static int write_index_ext_header(WriteIndexInfo *info, int fd, unsigned int ext, unsigned int sz) { ext = htonl(ext); sz = htonl(sz); return ((ce_write(info, fd, &ext, 4) < 0) || (ce_write(info, fd, &sz, 4) < 0)) ? -1 : 0; } static int ce_flush(WriteIndexInfo *info, int fd) { unsigned int left = info->write_buffer_len; gsize len = 20; if (left) { info->write_buffer_len = 0; g_checksum_update(info->context, info->write_buffer, left); } /* Flush first if not enough space for SHA1 signature */ if (left + 20 > WRITE_BUFFER_SIZE) { if (writen(fd, info->write_buffer, left) != left) return -1; left = 0; } /* Append the SHA1 signature at the end */ g_checksum_get_digest (info->context, info->write_buffer + left, &len); left += 20; return (writen(fd, info->write_buffer, left) != left) ? -1 : 0; } #if 0 static void ce_smudge_racily_clean_entry(struct cache_entry *ce) { /* * The only thing we care about in this function is to smudge the * falsely clean entry due to touch-update-touch race, so we leave * everything else as they are. We are called for entries whose * ce_mtime match the index file mtime. * * Note that this actually does not do much for gitlinks, for * which ce_match_stat_basic() always goes to the actual * contents. The caller checks with is_racy_timestamp() which * always says "no" for gitlinks, so we are not called for them ;-) */ SeafStat st; if (seaf_stat (ce->name, &st) < 0) return; if (ce_match_stat_basic(ce, &st)) return; /* This is "racily clean"; smudge it. Note that this * is a tricky code. At first glance, it may appear * that it can break with this sequence: * * $ echo xyzzy >frotz * $ git-update-index --add frotz * $ : >frotz * $ sleep 3 * $ echo filfre >nitfol * $ git-update-index --add nitfol * * but it does not. When the second update-index runs, * it notices that the entry "frotz" has the same timestamp * as index, and if we were to smudge it by resetting its * size to zero here, then the object name recorded * in index is the 6-byte file but the cached stat information * becomes zero --- which would then match what we would * obtain from the filesystem next time we stat("frotz"). * * However, the second update-index, before calling * this function, notices that the cached size is 6 * bytes and what is on the filesystem is an empty * file, and never calls us, so the cached size information * for "frotz" stays 6 which does not match the filesystem. */ ce->ce_size = 0; } #endif static int ce_write_entry2(WriteIndexInfo *info, int fd, struct cache_entry *ce) { int size = ondisk_ce_size2(ce); struct ondisk_cache_entry2 *ondisk = calloc(1, size); char *name; int result; ondisk->ctime.sec = hton64(ce->ce_ctime.sec); ondisk->mtime.sec = hton64(ce->ce_mtime.sec); ondisk->dev = htonl(ce->ce_dev); ondisk->ino = htonl(ce->ce_ino); ondisk->mode = htonl(ce->ce_mode); ondisk->uid = htonl(ce->ce_uid); ondisk->gid = htonl(ce->ce_gid); ondisk->size = hton64(ce->ce_size); hashcpy(ondisk->sha1, ce->sha1); ondisk->flags = htons(ce->ce_flags); name = ondisk->name; memcpy(name, ce->name, ce_namelen(ce)); result = ce_write(info, fd, ondisk, size); free(ondisk); return result; } static int modifiers_to_string (GString *buf, struct index_state *istate) { int i; struct cache_entry *ce; for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; if (S_ISDIR(ce->ce_mode) || (ce->ce_flags & CE_REMOVE)) continue; if (!ce->modifier) { seaf_warning ("BUG: index entry %s doesn't have modifier info.\n", ce->name); return -1; } g_string_append_printf (buf, "%s\n", ce->modifier); } return 0; } int write_index(struct index_state *istate, int newfd) { WriteIndexInfo info; struct cache_header hdr; int i, removed, extended; struct cache_entry **cache = istate->cache; int entries = istate->cache_nr; SeafStat st; int ret = 0; memset (&info, 0, sizeof(info)); for (i = removed = extended = 0; i < entries; i++) { if (cache[i]->ce_flags & CE_REMOVE) removed++; /* reduce extended entries if possible */ /* cache[i]->ce_flags &= ~CE_EXTENDED; */ /* if (cache[i]->ce_flags & CE_EXTENDED_FLAGS) { */ /* extended++; */ /* cache[i]->ce_flags |= CE_EXTENDED; */ /* } */ } hdr.hdr_signature = htonl(CACHE_SIGNATURE); /* Always use version 4 for newly created index files */ hdr.hdr_version = htonl(4); hdr.hdr_entries = htonl(entries - removed); info.context = g_checksum_new (G_CHECKSUM_SHA1); if (ce_write(&info, newfd, &hdr, sizeof(hdr)) < 0) { ret = -1; goto out; } for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; if (ce->ce_flags & CE_REMOVE) continue; /* if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce)) */ /* ce_smudge_racily_clean_entry(ce); */ if (ce_write_entry2(&info, newfd, ce) < 0) { ret = -1; goto out; } } /* Write extension data here */ if (istate->has_modifier) { GString *buf = g_string_new (""); int err; if (modifiers_to_string (buf, istate) < 0) { g_string_free (buf, TRUE); ret = -1; goto out; } err = write_index_ext_header(&info, newfd, CACHE_EXT_MODIFIER, buf->len) < 0 || ce_write(&info, newfd, buf->str, buf->len) < 0; g_string_free (buf, TRUE); if (err) { ret = -1; goto out; } } if (ce_flush(&info, newfd) || seaf_fstat(newfd, &st)) { ret = -1; goto out; } istate->timestamp.sec = (unsigned int)st.st_mtime; istate->timestamp.nsec = 0; out: g_checksum_free (info.context); return ret; } int discard_index(struct index_state *istate) { int i; for (i = 0; i < istate->cache_nr; ++i) cache_entry_free (istate->cache[i]); istate->cache_nr = 0; istate->cache_changed = 0; istate->timestamp.sec = 0; istate->timestamp.nsec = 0; istate->name_hash_initialized = 0; g_hash_table_destroy (istate->name_hash); #if defined WIN32 || defined __APPLE__ g_hash_table_destroy (istate->i_name_hash); #endif /* cache_tree_free(&(istate->cache_tree)); */ /* free(istate->alloc); */ free(istate->cache); istate->alloc = NULL; istate->initialized = 0; /* no need to throw away allocated active_cache */ return 0; } void cache_entry_free (struct cache_entry *ce) { g_free (ce->modifier); free (ce); } void remove_name_hash(struct index_state *istate, struct cache_entry *ce) { g_hash_table_remove (istate->name_hash, ce->name); #if defined WIN32 || defined __APPLE__ char *i_name = g_utf8_strdown (ce->name, -1); g_hash_table_remove (istate->i_name_hash, i_name); g_free (i_name); #endif } void add_name_hash(struct index_state *istate, struct cache_entry *ce) { g_hash_table_insert (istate->name_hash, g_strdup(ce->name), ce); #if defined WIN32 || defined __APPLE__ g_hash_table_insert (istate->i_name_hash, g_utf8_strdown(ce->name, -1), ce); #endif } struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase) { #if defined WIN32 || defined __APPLE__ if (!igncase) return g_hash_table_lookup (istate->name_hash, name); else { struct cache_entry *ce; char *i_name = g_utf8_strdown (name, -1); ce = g_hash_table_lookup (istate->i_name_hash, i_name); g_free (i_name); return ce; } #else return g_hash_table_lookup (istate->name_hash, name); #endif } seafile-6.1.5/common/index/index.h000066400000000000000000000372621323477647300170440ustar00rootroot00000000000000#ifndef INDEX_H #define INDEX_H #include "common.h" #include #include #include #include #include #include #include #include #include #ifndef __APPLE__ #include #endif #include #include #include #include #include #include "utils.h" #ifdef WIN32 #include #include #include #define DT_UNKNOWN 0 #define DT_DIR 1 #define DT_REG 2 #define DT_LNK 3 #define DTYPE(de) DT_UNKNOWN #define S_IFLNK 0120000 /* Symbolic link */ #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) #define S_ISSOCK(x) 0 #ifndef PROT_READ #define PROT_READ 1 #define PROT_WRITE 2 #define MAP_PRIVATE 1 #endif #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) #endif #define mmap git_mmap #define munmap git_munmap extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); extern int git_munmap(void *start, size_t length); #else #include #include #include #include #define DTYPE(de) ((de)->d_type) #endif #ifndef O_BINARY #define O_BINARY 0 #endif /* unknown mode (impossible combination S_IFIFO|S_IFCHR) */ #define S_IFINVALID 0030000 /* * A "directory link" is a link to another git directory. * * The value 0160000 is not normally a valid mode, and * also just happens to be S_IFDIR + S_IFLNK * * NOTE! We *really* shouldn't depend on the S_IFxxx macros * always having the same values everywhere. We should use * our internal git values for these things, and then we can * translate that to the OS-specific value. It just so * happens that everybody shares the same bit representation * in the UNIX world (and apparently wider too..) */ #define S_IFGITLINK 0160000 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK) struct SeafileCrypt; /* * Basic data structures for the directory cache */ #define CACHE_SIGNATURE 0x44495243 /* "DIRC" */ struct cache_header { unsigned int hdr_signature; unsigned int hdr_version; unsigned int hdr_entries; }; /* * The "cache_time" is just the low 32 bits of the * time. It doesn't matter if it overflows - we only * check it for equality in the 32 bits we save. */ struct cache_time { unsigned int sec; unsigned int nsec; }; /* * dev/ino/uid/gid/size are also just tracked to the low 32 bits * Again - this is just a (very strong in practice) heuristic that * the inode hasn't changed. * * We save the fields in big-endian order to allow using the * index file over NFS transparently. */ struct ondisk_cache_entry { struct cache_time ctime; struct cache_time mtime; unsigned int dev; unsigned int ino; unsigned int mode; unsigned int uid; unsigned int gid; uint64_t size; unsigned char sha1[20]; unsigned short flags; char name[0]; /* more */ } __attribute__ ((packed)); struct cache_time64 { guint64 sec; guint64 nsec; }; struct ondisk_cache_entry2 { struct cache_time64 ctime; struct cache_time64 mtime; unsigned int dev; unsigned int ino; unsigned int mode; unsigned int uid; unsigned int gid; uint64_t size; unsigned char sha1[20]; unsigned short flags; char name[0]; /* more */ } __attribute__ ((packed)); /* * This struct is used when CE_EXTENDED bit is 1 * The struct must match ondisk_cache_entry exactly from * ctime till flags */ struct ondisk_cache_entry_extended { struct cache_time ctime; struct cache_time mtime; unsigned int dev; unsigned int ino; unsigned int mode; unsigned int uid; unsigned int gid; uint64_t size; unsigned char sha1[20]; unsigned short flags; unsigned short flags2; char name[0]; /* more */ } __attribute__ ((packed)); #define CACHE_EXT_MODIFIER 1 struct cache_ext_hdr { unsigned int ext_name; unsigned int ext_size; } __attribute__ ((packed)); struct cache_entry { struct cache_time64 ce_ctime; struct cache_time64 ce_mtime; guint64 current_mtime; /* used in merge */ unsigned int ce_dev; unsigned int ce_ino; unsigned int ce_mode; unsigned int ce_uid; unsigned int ce_gid; uint64_t ce_size; unsigned int ce_flags; unsigned char sha1[20]; char *modifier; struct cache_entry *next; char name[0]; /* more */ }; #define CE_NAMEMASK (0x0fff) #define CE_STAGEMASK (0x3000) #define CE_EXTENDED (0x4000) #define CE_VALID (0x8000) #define CE_STAGESHIFT 12 /* * Range 0xFFFF0000 in ce_flags is divided into * two parts: in-memory flags and on-disk ones. * Flags in CE_EXTENDED_FLAGS will get saved on-disk * if you want to save a new flag, add it in * CE_EXTENDED_FLAGS * * In-memory only flags */ #define CE_UPDATE (1 << 16) #define CE_REMOVE (1 << 17) #define CE_UPTODATE (1 << 18) #define CE_ADDED (1 << 19) #define CE_HASHED (1 << 20) #define CE_UNHASHED (1 << 21) #define CE_WT_REMOVE (1 << 22) /* remove in work directory */ #define CE_CONFLICTED (1 << 23) #define CE_UNPACKED (1 << 24) #define CE_NEW_SKIP_WORKTREE (1 << 25) /* * Extended on-disk flags */ #define CE_INTENT_TO_ADD (1 << 29) #define CE_SKIP_WORKTREE (1 << 30) /* CE_EXTENDED2 is for future extension */ #define CE_EXTENDED2 (1 << 31) #define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD | CE_SKIP_WORKTREE) /* * Safeguard to avoid saving wrong flags: * - CE_EXTENDED2 won't get saved until its semantic is known * - Bits in 0x0000FFFF have been saved in ce_flags already * - Bits in 0x003F0000 are currently in-memory flags */ #if CE_EXTENDED_FLAGS & 0x803FFFFF #error "CE_EXTENDED_FLAGS out of range" #endif /* * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! */ #define CE_STATE_MASK (CE_HASHED | CE_UNHASHED) static inline void copy_cache_entry(struct cache_entry *dst, struct cache_entry *src) { unsigned int state = dst->ce_flags & CE_STATE_MASK; /* Don't copy modifier, hash chain and name */ memcpy(dst, src, offsetof(struct cache_entry, modifier)); /* Restore the hash state */ dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; } static inline unsigned create_ce_flags(size_t len, unsigned stage) { if (len >= CE_NAMEMASK) len = CE_NAMEMASK; return (len | (stage << CE_STAGESHIFT)); } static inline size_t ce_namelen(const struct cache_entry *ce) { size_t len = ce->ce_flags & CE_NAMEMASK; if (len < CE_NAMEMASK) return len; return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK; } #define ce_size(ce) cache_entry_size(ce_namelen(ce)) #define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce)) #define ondisk_ce_size2(ce) ondisk_cache_entry_size2(ce_namelen(ce)) #define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT) #define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE) #define ce_skip_worktree(ce) ((ce)->ce_flags & CE_SKIP_WORKTREE) #define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE) #define ce_permissions(mode) (((mode) & 0100) ? 0755 : 0644) static inline unsigned int create_ce_mode(unsigned int mode) { if (S_ISLNK(mode)) return S_IFLNK; if (S_ISDIR(mode)) return S_IFDIR; return S_IFREG | ce_permissions(mode); } static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode) { return create_ce_mode(mode); } static inline int ce_to_dtype(const struct cache_entry *ce) { unsigned ce_mode = ntohl(ce->ce_mode); if (S_ISREG(ce_mode)) return DT_REG; else if (S_ISDIR(ce_mode) || S_ISGITLINK(ce_mode)) return DT_DIR; else if (S_ISLNK(ce_mode)) return DT_LNK; else return DT_UNKNOWN; } static inline unsigned int canon_mode(unsigned int mode) { if (S_ISREG(mode)) return S_IFREG | ce_permissions(mode); if (S_ISLNK(mode)) return S_IFLNK; if (S_ISDIR(mode)) return S_IFDIR; return S_IFGITLINK; } #define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7) #define cache_entry_size(len) flexible_size(cache_entry,len) #define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len) #define ondisk_cache_entry_size2(len) flexible_size(ondisk_cache_entry2,len) #define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len) struct index_state { unsigned int version; struct cache_entry **cache; unsigned int cache_nr, cache_alloc, cache_changed; /* struct cache_tree *cache_tree; */ struct cache_time timestamp; void *alloc; unsigned name_hash_initialized : 1, initialized : 1; GHashTable *name_hash; #if defined WIN32 || defined __APPLE__ GHashTable *i_name_hash; /* ignore case */ #endif int has_modifier; }; extern struct index_state the_index; /* Name hashing */ extern unsigned int hash_name(const char *name, int namelen); enum object_type { OBJ_BAD = -1, OBJ_NONE = 0, OBJ_COMMIT = 1, OBJ_TREE = 2, OBJ_BLOB = 3, OBJ_TAG = 4, /* 5 for future expansion */ OBJ_OFS_DELTA = 6, OBJ_REF_DELTA = 7, OBJ_ANY, OBJ_MAX }; static inline enum object_type object_type(unsigned int mode) { return S_ISDIR(mode) ? OBJ_TREE : S_ISGITLINK(mode) ? OBJ_COMMIT : OBJ_BLOB; } #define alloc_nr(x) (((x)+16)*3/2) /* * Realloc the buffer pointed at by variable 'x' so that it can hold * at least 'nr' entries; the number of entries currently allocated * is 'alloc', using the standard growing factor alloc_nr() macro. * * DO NOT USE any expression with side-effect for 'x', 'nr', or 'alloc'. */ #define ALLOC_GROW(x, nr, alloc) \ do { \ if ((nr) > alloc) { \ if (alloc_nr(alloc) < (nr)) \ alloc = (nr); \ else \ alloc = alloc_nr(alloc); \ x = realloc((x), alloc * sizeof(*(x))); \ } \ } while (0) /* Initialize and use the cache information */ extern int read_index(struct index_state *); extern int read_index_preload(struct index_state *, const char **pathspec); extern int read_index_from(struct index_state *, const char *path, int repo_version); extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); extern int write_index(struct index_state *, int newfd); extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); extern int index_name_pos(const struct index_state *, const char *name, int namelen); #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */ #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ #define ADD_CACHE_SKIP_DFCHECK 4 /* Ok to skip DF conflict checks */ #define ADD_CACHE_JUST_APPEND 8 /* Append only; tree.c::read_tree() */ #define ADD_CACHE_NEW_ONLY 16 /* Do not replace existing ones */ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option); extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name); extern int remove_index_entry_at(struct index_state *, int pos); extern void remove_marked_cache_entries(struct index_state *istate); extern int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_VERBOSE 1 #define ADD_CACHE_PRETEND 2 #define ADD_CACHE_IGNORE_ERRORS 4 #define ADD_CACHE_IGNORE_REMOVAL 8 #define ADD_CACHE_INTENT 16 typedef int (*IndexCB) (const char *repo_id, int version, const char *path, unsigned char sha1[], struct SeafileCrypt *crypt, gboolean write_data); int add_to_index(const char *repo_id, int version, struct index_state *istate, const char *path, const char *full_path, SeafStat *st, int flags, struct SeafileCrypt *crypt, IndexCB index_cb, const char *modifier, gboolean *added); int add_empty_dir_to_index (struct index_state *istate, const char *path, SeafStat *st); typedef void (*CECallback) (struct cache_entry *ce, void *user_data); int remove_from_index_with_prefix (struct index_state *istate, const char *path_prefix, gboolean *not_found); int rename_index_entries (struct index_state *istate, const char *src_path, const char *dst_path, gboolean *not_found, CECallback cb_after_rename, void *cb_data); int add_empty_dir_to_index_with_check (struct index_state *istate, const char *path, SeafStat *st); void remove_empty_parent_dir_entry (struct index_state *istate, const char *path); struct _IndexDirent { char *dname; gboolean is_dir; struct cache_entry *ce; }; typedef struct _IndexDirent IndexDirent; void index_dirent_free (IndexDirent *dent); GList * list_dirents_from_index (struct index_state *istate, const char *dir); extern int add_file_to_index(struct index_state *, const char *path, int flags); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, const char *full_path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); extern int index_name_is_other(const struct index_state *, const char *, int); void cache_entry_free (struct cache_entry *ce); /* do stat comparison even if CE_VALID is true */ #define CE_MATCH_IGNORE_VALID 01 /* do not check the contents but report dirty on racily-clean entries */ #define CE_MATCH_RACY_IS_DIRTY 02 /* do stat comparison even if CE_SKIP_WORKTREE is true */ #define CE_MATCH_IGNORE_SKIP_WORKTREE 04 extern int ie_match_stat(struct cache_entry *, SeafStat *, unsigned int); extern int ie_modified(const struct index_state *, struct cache_entry *, SeafStat *, unsigned int); extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); extern int index_fd(unsigned char *sha1, int fd, SeafStat *st, enum object_type type, const char *path); extern int index_path(unsigned char *sha1, const char *path, SeafStat *st); extern void fill_stat_cache_info(struct cache_entry *ce, SeafStat *st); extern void mark_all_ce_unused(struct index_state *index); void remove_name_hash(struct index_state *istate, struct cache_entry *ce); void add_name_hash(struct index_state *istate, struct cache_entry *ce); struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase); #define MTIME_CHANGED 0x0001 #define CTIME_CHANGED 0x0002 #define OWNER_CHANGED 0x0004 #define MODE_CHANGED 0x0008 #define INODE_CHANGED 0x0010 #define DATA_CHANGED 0x0020 #define TYPE_CHANGED 0x0040 extern const unsigned char null_sha1[20]; static inline int is_null_sha1(const unsigned char *sha1) { return !memcmp(sha1, null_sha1, 20); } static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2) { return memcmp(sha1, sha2, 20); } static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src) { memcpy(sha_dst, sha_src, 20); } static inline void hashclr(unsigned char *hash) { memset(hash, 0, 20); } extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2); extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); #endif seafile-6.1.5/common/index/name-hash.c000066400000000000000000000124551323477647300175660ustar00rootroot00000000000000/* * name-hash.c * * Hashing names in the index state * * Copyright (C) 2008 Linus Torvalds */ #define NO_THE_INDEX_COMPATIBILITY_MACROS #include "index.h" /* * This removes bit 5 if bit 6 is set. * * That will make US-ASCII characters hash to their upper-case * equivalent. We could easily do this one whole word at a time, * but that's for future worries. */ static inline unsigned char icase_hash(unsigned char c) { return c & ~((c & 0x40) >> 1); } unsigned int hash_name(const char *name, int namelen) { unsigned int hash = 0x123; do { unsigned char c = *name++; c = icase_hash(c); hash = hash*101 + c; } while (--namelen); return hash; } #if 0 static void hash_index_entry_directories(struct index_state *istate, struct cache_entry *ce) { /* * Throw each directory component in the hash for quick lookup * during a git status. Directory components are stored with their * closing slash. Despite submodules being a directory, they never * reach this point, because they are stored without a closing slash * in the cache. * * Note that the cache_entry stored with the directory does not * represent the directory itself. It is a pointer to an existing * filename, and its only purpose is to represent existence of the * directory in the cache. It is very possible multiple directory * hash entries may point to the same cache_entry. */ unsigned int hash; void **pos; const char *ptr = ce->name; while (*ptr) { while (*ptr && *ptr != '/') ++ptr; if (*ptr == '/') { ++ptr; hash = hash_name(ce->name, ptr - ce->name); if (!lookup_hash(hash, &istate->name_hash)) { pos = insert_hash(hash, ce, &istate->name_hash); if (pos) { ce->next = *pos; *pos = ce; } } } } } #endif static void hash_index_entry(struct index_state *istate, struct cache_entry *ce) { void **pos; unsigned int hash; if (ce->ce_flags & CE_HASHED) return; ce->ce_flags |= CE_HASHED; ce->next = NULL; hash = hash_name(ce->name, ce_namelen(ce)); pos = insert_hash(hash, ce, &istate->name_hash); if (pos) { ce->next = *pos; *pos = ce; } /* if (ignore_case) */ /* hash_index_entry_directories(istate, ce); */ } static void lazy_init_name_hash(struct index_state *istate) { int nr; if (istate->name_hash_initialized) return; for (nr = 0; nr < istate->cache_nr; nr++) hash_index_entry(istate, istate->cache[nr]); istate->name_hash_initialized = 1; } void add_name_hash(struct index_state *istate, struct cache_entry *ce) { ce->ce_flags &= ~CE_UNHASHED; if (istate->name_hash_initialized) hash_index_entry(istate, ce); } #if 0 static int slow_same_name(const char *name1, int len1, const char *name2, int len2) { if (len1 != len2) return 0; while (len1) { unsigned char c1 = *name1++; unsigned char c2 = *name2++; len1--; if (c1 != c2) { c1 = toupper(c1); c2 = toupper(c2); if (c1 != c2) return 0; } } return 1; } #endif static int same_name(const struct cache_entry *ce, const char *name, int namelen, int icase) { int len = ce_namelen(ce); /* * Always do exact compare, even if we want a case-ignoring comparison; * we do the quick exact one first, because it will be the common case. */ if (len == namelen && !cache_name_compare(name, namelen, ce->name, len)) return 1; else return 0; /* if (!icase) */ /* return 0; */ /* * If the entry we're comparing is a filename (no trailing slash), then compare * the lengths exactly. */ /* if (name[namelen - 1] != '/') */ /* return slow_same_name(name, namelen, ce->name, len); */ /* * For a directory, we point to an arbitrary cache_entry filename. Just * make sure the directory portion matches. */ /* return slow_same_name(name, namelen, ce->name, namelen < len ? namelen : len); */ } struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int icase) { unsigned int hash = hash_name(name, namelen); struct cache_entry *ce; lazy_init_name_hash(istate); ce = lookup_hash(hash, &istate->name_hash); while (ce) { if (!(ce->ce_flags & CE_UNHASHED)) { if (same_name(ce, name, namelen, icase)) return ce; } ce = ce->next; } /* * Might be a submodule. Despite submodules being directories, * they are stored in the name hash without a closing slash. * When ignore_case is 1, directories are stored in the name hash * with their closing slash. * * The side effect of this storage technique is we have need to * remove the slash from name and perform the lookup again without * the slash. If a match is made, S_ISGITLINK(ce->mode) will be * true. */ /* if (icase && name[namelen - 1] == '/') { */ /* ce = index_name_exists(istate, name, namelen - 1, icase); */ /* if (ce && S_ISGITLINK(ce->ce_mode)) */ /* return ce; */ /* } */ return NULL; } seafile-6.1.5/common/log.c000066400000000000000000000125551323477647300154000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #ifndef WIN32 #ifdef SEAFILE_SERVER #include #endif #endif #include "log.h" #include "utils.h" /* message with greater log levels will be ignored */ static int ccnet_log_level; static int seafile_log_level; static char *logfile; static FILE *logfp; #ifndef WIN32 #ifdef SEAFILE_SERVER static gboolean enable_syslog; #endif #endif #ifndef WIN32 #ifdef SEAFILE_SERVER static int get_syslog_level (GLogLevelFlags level) { switch (level) { case G_LOG_LEVEL_DEBUG: return LOG_DEBUG; case G_LOG_LEVEL_INFO: return LOG_INFO; case G_LOG_LEVEL_WARNING: return LOG_WARNING; case G_LOG_LEVEL_ERROR: return LOG_ERR; default: return LOG_DEBUG; } } #endif #endif static void seafile_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { time_t t; struct tm *tm; char buf[1024]; int len; if (log_level > seafile_log_level) return; t = time(NULL); tm = localtime(&t); len = strftime (buf, 1024, "[%x %X] ", tm); g_return_if_fail (len < 1024); if (logfp != NULL) { fputs (buf, logfp); fputs (message, logfp); fflush (logfp); } else { // log file not available printf("%s %s", buf, message); } #ifndef WIN32 #ifdef SEAFILE_SERVER if (enable_syslog) syslog (get_syslog_level (log_level), "%s", message); #endif #endif } static void ccnet_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { time_t t; struct tm *tm; char buf[1024]; int len; if (log_level > ccnet_log_level) return; t = time(NULL); tm = localtime(&t); len = strftime (buf, 1024, "[%x %X] ", tm); g_return_if_fail (len < 1024); if (logfp != NULL) { fputs (buf, logfp); fputs (message, logfp); fflush (logfp); } else { // log file not available printf("%s %s", buf, message); } #ifndef WIN32 #ifdef SEAFILE_SERVER if (enable_syslog) syslog (get_syslog_level (log_level), "%s", message); #endif #endif } static int get_debug_level(const char *str, int default_level) { if (strcmp(str, "debug") == 0) return G_LOG_LEVEL_DEBUG; if (strcmp(str, "info") == 0) return G_LOG_LEVEL_INFO; if (strcmp(str, "warning") == 0) return G_LOG_LEVEL_WARNING; return default_level; } int seafile_log_init (const char *_logfile, const char *ccnet_debug_level_str, const char *seafile_debug_level_str) { g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, seafile_log, NULL); g_log_set_handler ("Ccnet", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, ccnet_log, NULL); /* record all log message */ ccnet_log_level = get_debug_level(ccnet_debug_level_str, G_LOG_LEVEL_INFO); seafile_log_level = get_debug_level(seafile_debug_level_str, G_LOG_LEVEL_DEBUG); if (strcmp(_logfile, "-") == 0) { logfp = stdout; logfile = g_strdup (_logfile); } else { logfile = ccnet_expand_path(_logfile); if ((logfp = g_fopen (logfile, "a+")) == NULL) { seaf_message ("Failed to open file %s\n", logfile); return -1; } } return 0; } int seafile_log_reopen () { FILE *fp, *oldfp; if (strcmp(logfile, "-") == 0) return 0; if ((fp = g_fopen (logfile, "a+")) == NULL) { seaf_message ("Failed to open file %s\n", logfile); return -1; } //TODO: check file's health oldfp = logfp; logfp = fp; if (fclose(oldfp) < 0) { seaf_message ("Failed to close file %s\n", logfile); return -1; } return 0; } static SeafileDebugFlags debug_flags = 0; static GDebugKey debug_keys[] = { { "Transfer", SEAFILE_DEBUG_TRANSFER }, { "Sync", SEAFILE_DEBUG_SYNC }, { "Watch", SEAFILE_DEBUG_WATCH }, { "Http", SEAFILE_DEBUG_HTTP }, { "Merge", SEAFILE_DEBUG_MERGE }, { "Other", SEAFILE_DEBUG_OTHER }, }; gboolean seafile_debug_flag_is_set (SeafileDebugFlags flag) { return (debug_flags & flag) != 0; } void seafile_debug_set_flags (SeafileDebugFlags flags) { g_message ("Set debug flags %#x\n", flags); debug_flags |= flags; } void seafile_debug_set_flags_string (const gchar *flags_string) { guint nkeys = G_N_ELEMENTS (debug_keys); if (flags_string) seafile_debug_set_flags ( g_parse_debug_string (flags_string, debug_keys, nkeys)); } void seafile_debug_impl (SeafileDebugFlags flag, const gchar *format, ...) { if (flag & debug_flags) { va_list args; va_start (args, format); g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args); va_end (args); } } #ifndef WIN32 #ifdef SEAFILE_SERVER void set_syslog_config (GKeyFile *config) { enable_syslog = g_key_file_get_boolean (config, "general", "enable_syslog", NULL); if (enable_syslog) openlog (NULL, LOG_NDELAY | LOG_PID, LOG_USER); } #endif #endif FILE * seafile_get_log_fp () { return logfp; } seafile-6.1.5/common/log.h000066400000000000000000000022611323477647300153760ustar00rootroot00000000000000#ifndef LOG_H #define LOG_H #define SEAFILE_DOMAIN g_quark_from_string("seafile") #ifndef seaf_warning #define seaf_warning(fmt, ...) g_warning("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #ifndef seaf_message #define seaf_message(fmt, ...) g_message("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif int seafile_log_init (const char *logfile, const char *ccnet_debug_level_str, const char *seafile_debug_level_str); int seafile_log_reopen (); #ifndef WIN32 #ifdef SEAFILE_SERVER void set_syslog_config (GKeyFile *config); #endif #endif void seafile_debug_set_flags_string (const gchar *flags_string); typedef enum { SEAFILE_DEBUG_TRANSFER = 1 << 1, SEAFILE_DEBUG_SYNC = 1 << 2, SEAFILE_DEBUG_WATCH = 1 << 3, /* wt-monitor */ SEAFILE_DEBUG_HTTP = 1 << 4, /* http server */ SEAFILE_DEBUG_MERGE = 1 << 5, SEAFILE_DEBUG_OTHER = 1 << 6, } SeafileDebugFlags; void seafile_debug_impl (SeafileDebugFlags flag, const gchar *format, ...); #ifdef DEBUG_FLAG #undef seaf_debug #define seaf_debug(fmt, ...) \ seafile_debug_impl (DEBUG_FLAG, "%.10s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif /* DEBUG_FLAG */ #endif seafile-6.1.5/common/merge-new.c000066400000000000000000000507401323477647300165030ustar00rootroot00000000000000#include "seafile-session.h" #include "merge-new.h" #include "vc-common.h" #define DEBUG_FLAG SEAFILE_DEBUG_MERGE #include "log.h" static int merge_trees_recursive (const char *store_id, int version, int n, SeafDir *trees[], const char *basedir, MergeOptions *opt); static char * merge_conflict_filename (const char *store_id, int version, MergeOptions *opt, const char *basedir, const char *filename) { char *path = NULL, *modifier = NULL, *conflict_name = NULL; gint64 mtime; SeafCommit *commit; path = g_strconcat (basedir, filename, NULL); int rc = get_file_modifier_mtime (opt->remote_repo_id, store_id, version, opt->remote_head, path, &modifier, &mtime); if (rc < 0) { commit = seaf_commit_manager_get_commit (seaf->commit_mgr, opt->remote_repo_id, version, opt->remote_head); if (!commit) { seaf_warning ("Failed to find remote head %s:%s.\n", opt->remote_repo_id, opt->remote_head); goto out; } modifier = g_strdup(commit->creator_name); mtime = (gint64)time(NULL); seaf_commit_unref (commit); } conflict_name = gen_conflict_path (filename, modifier, mtime); out: g_free (path); g_free (modifier); return conflict_name; } static char * merge_conflict_dirname (const char *store_id, int version, MergeOptions *opt, const char *basedir, const char *dirname) { char *modifier = NULL, *conflict_name = NULL; SeafCommit *commit; commit = seaf_commit_manager_get_commit (seaf->commit_mgr, opt->remote_repo_id, version, opt->remote_head); if (!commit) { seaf_warning ("Failed to find remote head %s:%s.\n", opt->remote_repo_id, opt->remote_head); goto out; } modifier = g_strdup(commit->creator_name); seaf_commit_unref (commit); conflict_name = gen_conflict_path (dirname, modifier, (gint64)time(NULL)); out: g_free (modifier); return conflict_name; } static int merge_entries (const char *store_id, int version, int n, SeafDirent *dents[], const char *basedir, GList **dents_out, MergeOptions *opt) { SeafDirent *files[3]; int i; memset (files, 0, sizeof(files[0])*n); for (i = 0; i < n; ++i) { if (dents[i] && S_ISREG(dents[i]->mode)) files[i] = dents[i]; } /* If we're running 2-way merge, or the caller requires not to * actually merge contents, just call the callback function. */ if (n == 2 || !opt->do_merge) return opt->callback (basedir, files, opt); /* Otherwise, we're doing a real 3-way merge of the trees. * It means merge files and handle any conflicts. */ SeafDirent *base, *head, *remote; char *conflict_name; base = files[0]; head = files[1]; remote = files[2]; if (head && remote) { if (strcmp (head->id, remote->id) == 0) { seaf_debug ("%s%s: files match\n", basedir, head->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); } else if (base && strcmp (base->id, head->id) == 0) { seaf_debug ("%s%s: unchanged in head, changed in remote\n", basedir, head->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); } else if (base && strcmp (base->id, remote->id) == 0) { seaf_debug ("%s%s: unchanged in remote, changed in head\n", basedir, head->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); } else { /* File content conflict. */ seaf_debug ("%s%s: files conflict\n", basedir, head->name); conflict_name = merge_conflict_filename(store_id, version, opt, basedir, head->name); if (!conflict_name) return -1; /* Change remote entry name in place. So opt->callback * will see the conflict name, not the original name. */ g_free (remote->name); remote->name = conflict_name; remote->name_len = strlen (remote->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); opt->conflict = TRUE; } } else if (base && !head && remote) { if (strcmp (base->id, remote->id) != 0) { if (dents[1] != NULL) { /* D/F conflict: * Head replaces file with dir, while remote change the file. */ seaf_debug ("%s%s: DFC, file -> dir, file\n", basedir, remote->name); conflict_name = merge_conflict_filename(store_id, version, opt, basedir, remote->name); if (!conflict_name) return -1; /* Change the name of remote, keep dir name in head unchanged. */ g_free (remote->name); remote->name = conflict_name; remote->name_len = strlen (remote->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); opt->conflict = TRUE; } else { /* Deleted in head and changed in remote. */ seaf_debug ("%s%s: deleted in head and changed in remote\n", basedir, remote->name); /* Keep version of remote. */ *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); } } else { /* If base and remote match, the file should not be added to * the merge result. */ seaf_debug ("%s%s: file deleted in head, unchanged in remote\n", basedir, remote->name); } } else if (base && head && !remote) { if (strcmp (base->id, head->id) != 0) { if (dents[2] != NULL) { /* D/F conflict: * Remote replaces file with dir, while head change the file. */ seaf_debug ("%s%s: DFC, file -> file, dir\n", basedir, head->name); /* We use remote head commit author name as conflict * suffix of a dir. */ conflict_name = merge_conflict_dirname (store_id, version, opt, basedir, dents[2]->name); if (!conflict_name) return -1; /* Change remote dir name to conflict name in place. */ g_free (dents[2]->name); dents[2]->name = conflict_name; dents[2]->name_len = strlen (dents[2]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); opt->conflict = TRUE; } else { /* Deleted in remote and changed in head. */ seaf_debug ("%s%s: deleted in remote and changed in head\n", basedir, head->name); /* Keep version of remote. */ *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); } } else { /* If base and head match, the file should not be added to * the merge result. */ seaf_debug ("%s%s: file deleted in remote, unchanged in head\n", basedir, head->name); } } else if (!base && !head && remote) { if (!dents[1]) { /* Added in remote. */ seaf_debug ("%s%s: added in remote\n", basedir, remote->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); } else if (dents[0] != NULL && strcmp(dents[0]->id, dents[1]->id) == 0) { /* Contents in the dir is not changed. * The dir will be deleted in merge_directories(). */ seaf_debug ("%s%s: dir in head will be replaced by file in remote\n", basedir, remote->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); } else { /* D/F conflict: * Contents of the dir is changed in head, while * remote replace the dir with a file. * * Or, head adds a new dir, while remote adds a new file, * with the same name. */ seaf_debug ("%s%s: DFC, dir -> dir, file\n", basedir, remote->name); conflict_name = merge_conflict_filename(store_id, version, opt, basedir, remote->name); if (!conflict_name) return -1; g_free (remote->name); remote->name = conflict_name; remote->name_len = strlen (remote->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(remote)); opt->conflict = TRUE; } } else if (!base && head && !remote) { if (!dents[2]) { /* Added in remote. */ seaf_debug ("%s%s: added in head\n", basedir, head->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); } else if (dents[0] != NULL && strcmp(dents[0]->id, dents[2]->id) == 0) { /* Contents in the dir is not changed. * The dir will be deleted in merge_directories(). */ seaf_debug ("%s%s: dir in remote will be replaced by file in head\n", basedir, head->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); } else { /* D/F conflict: * Contents of the dir is changed in remote, while * head replace the dir with a file. * * Or, remote adds a new dir, while head adds a new file, * with the same name. */ seaf_debug ("%s%s: DFC, dir -> file, dir\n", basedir, head->name); conflict_name = merge_conflict_dirname (store_id, version, opt, basedir, dents[2]->name); if (!conflict_name) return -1; g_free (dents[2]->name); dents[2]->name = conflict_name; dents[2]->name_len = strlen (dents[2]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(head)); opt->conflict = TRUE; } } else if (base && !head && !remote) { /* Don't need to add anything to dents_out. */ seaf_debug ("%s%s: deleted in head and remote\n", basedir, base->name); } return 0; } static int merge_directories (const char *store_id, int version, int n, SeafDirent *dents[], const char *basedir, GList **dents_out, MergeOptions *opt) { SeafDir *dir; SeafDir *sub_dirs[3]; char *dirname = NULL; char *new_basedir; int ret = 0; int dir_mask = 0, i; SeafDirent *merged_dent; for (i = 0; i < n; ++i) { if (dents[i] && S_ISDIR(dents[i]->mode)) dir_mask |= 1 << i; } seaf_debug ("dir_mask = %d\n", dir_mask); if (n == 3 && opt->do_merge) { switch (dir_mask) { case 0: g_return_val_if_reached (-1); case 1: /* head and remote are not dirs, nothing to merge. */ seaf_debug ("%s%s: no dir, no need to merge\n", basedir, dents[0]->name); return 0; case 2: /* only head is dir, add to result directly, no need to merge. */ seaf_debug ("%s%s: only head is dir\n", basedir, dents[1]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(dents[1])); return 0; case 3: if (strcmp (dents[0]->id, dents[1]->id) == 0) { /* Base and head are the same, but deleted in remote. */ seaf_debug ("%s%s: dir deleted in remote\n", basedir, dents[0]->name); return 0; } seaf_debug ("%s%s: dir changed in head but deleted in remote\n", basedir, dents[1]->name); break; case 4: /* only remote is dir, add to result directly, no need to merge. */ seaf_debug ("%s%s: only remote is dir\n", basedir, dents[2]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(dents[2])); return 0; case 5: if (strcmp (dents[0]->id, dents[2]->id) == 0) { /* Base and remote are the same, but deleted in head. */ seaf_debug ("%s%s: dir deleted in head\n", basedir, dents[0]->name); return 0; } seaf_debug ("%s%s: dir changed in remote but deleted in head\n", basedir, dents[2]->name); break; case 6: case 7: if (strcmp (dents[1]->id, dents[2]->id) == 0) { /* Head and remote match. */ seaf_debug ("%s%s: dir is the same in head and remote\n", basedir, dents[1]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(dents[1])); return 0; } else if (dents[0] && strcmp(dents[0]->id, dents[1]->id) == 0) { seaf_debug ("%s%s: dir changed in remote but unchanged in head\n", basedir, dents[1]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(dents[2])); return 0; } else if (dents[0] && strcmp(dents[0]->id, dents[2]->id) == 0) { seaf_debug ("%s%s: dir changed in head but unchanged in remote\n", basedir, dents[1]->name); *dents_out = g_list_prepend (*dents_out, seaf_dirent_dup(dents[1])); return 0; } seaf_debug ("%s%s: dir is changed in both head and remote, " "merge recursively\n", basedir, dents[1]->name); break; default: g_return_val_if_reached (-1); } } memset (sub_dirs, 0, sizeof(sub_dirs[0])*n); for (i = 0; i < n; ++i) { if (dents[i] != NULL && S_ISDIR(dents[i]->mode)) { dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, store_id, version, dents[i]->id); if (!dir) { seaf_warning ("Failed to find dir %s:%s.\n", store_id, dents[i]->id); ret = -1; goto free_sub_dirs; } opt->visit_dirs++; sub_dirs[i] = dir; dirname = dents[i]->name; } } new_basedir = g_strconcat (basedir, dirname, "/", NULL); ret = merge_trees_recursive (store_id, version, n, sub_dirs, new_basedir, opt); g_free (new_basedir); if (n == 3 && opt->do_merge) { if (dir_mask == 3 || dir_mask == 6 || dir_mask == 7) { merged_dent = seaf_dirent_dup (dents[1]); memcpy (merged_dent->id, opt->merged_tree_root, 40); *dents_out = g_list_prepend (*dents_out, merged_dent); } else if (dir_mask == 5) { merged_dent = seaf_dirent_dup (dents[2]); memcpy (merged_dent->id, opt->merged_tree_root, 40); *dents_out = g_list_prepend (*dents_out, merged_dent); } } free_sub_dirs: for (i = 0; i < n; ++i) seaf_dir_free (sub_dirs[i]); return ret; } static gint compare_dirents (gconstpointer a, gconstpointer b) { const SeafDirent *denta = a, *dentb = b; return strcmp (dentb->name, denta->name); } static int merge_trees_recursive (const char *store_id, int version, int n, SeafDir *trees[], const char *basedir, MergeOptions *opt) { GList *ptrs[3]; SeafDirent *dents[3]; int i; SeafDirent *dent; char *first_name; gboolean done; int ret = 0; SeafDir *merged_tree; GList *merged_dents = NULL; for (i = 0; i < n; ++i) { if (trees[i]) ptrs[i] = trees[i]->entries; else ptrs[i] = NULL; } while (1) { first_name = NULL; memset (dents, 0, sizeof(dents[0])*n); done = TRUE; /* Find the "largest" name, assuming dirents are sorted. */ for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { done = FALSE; dent = ptrs[i]->data; if (!first_name) first_name = dent->name; else if (strcmp(dent->name, first_name) > 0) first_name = dent->name; } } if (done) break; /* * Setup dir entries for all names that equal to first_name */ int n_files = 0, n_dirs = 0; for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { dent = ptrs[i]->data; if (strcmp(first_name, dent->name) == 0) { if (S_ISREG(dent->mode)) ++n_files; else if (S_ISDIR(dent->mode)) ++n_dirs; dents[i] = dent; ptrs[i] = ptrs[i]->next; } } } /* Merge entries of this level. */ if (n_files > 0) { ret = merge_entries (store_id, version, n, dents, basedir, &merged_dents, opt); if (ret < 0) return ret; } /* Recurse into sub level. */ if (n_dirs > 0) { ret = merge_directories (store_id, version, n, dents, basedir, &merged_dents, opt); if (ret < 0) return ret; } } if (n == 3 && opt->do_merge) { merged_dents = g_list_sort (merged_dents, compare_dirents); merged_tree = seaf_dir_new (NULL, merged_dents, dir_version_from_repo_version(version)); memcpy (opt->merged_tree_root, merged_tree->dir_id, 40); if ((trees[1] && strcmp (trees[1]->dir_id, merged_tree->dir_id) == 0) || (trees[2] && strcmp (trees[2]->dir_id, merged_tree->dir_id) == 0)) { seaf_dir_free (merged_tree); } else { ret = seaf_dir_save (seaf->fs_mgr, store_id, version, merged_tree); seaf_dir_free (merged_tree); if (ret < 0) { seaf_warning ("Failed to save merged tree %s:%s.\n", store_id, basedir); } } } return ret; } int seaf_merge_trees (const char *store_id, int version, int n, const char *roots[], MergeOptions *opt) { SeafDir **trees, *root; int i, ret; g_return_val_if_fail (n == 2 || n == 3, -1); trees = g_new0 (SeafDir *, n); for (i = 0; i < n; ++i) { root = seaf_fs_manager_get_seafdir (seaf->fs_mgr, store_id, version, roots[i]); if (!root) { seaf_warning ("Failed to find dir %s:%s.\n", store_id, roots[i]); g_free (trees); return -1; } trees[i] = root; } ret = merge_trees_recursive (store_id, version, n, trees, "", opt); for (i = 0; i < n; ++i) seaf_dir_free (trees[i]); g_free (trees); return ret; } seafile-6.1.5/common/merge-new.h000066400000000000000000000017261323477647300165100ustar00rootroot00000000000000#ifndef MERGE_NEW_H #define MERGE_NEW_H #include "common.h" #include "fs-mgr.h" struct MergeOptions; typedef int (*MergeCallback) (const char *basedir, SeafDirent *dirents[], struct MergeOptions *opt); typedef struct MergeOptions { int n_ways; /* only 2 and 3 way merges are supported. */ MergeCallback callback; void * data; /* options only used in 3-way merge. */ char remote_repo_id[37]; char remote_head[41]; gboolean do_merge; /* really merge the contents * and handle conflicts */ char merged_tree_root[41]; /* merge result */ int visit_dirs; gboolean conflict; } MergeOptions; int seaf_merge_trees (const char *store_id, int version, int n, const char *roots[], MergeOptions *opt); #endif seafile-6.1.5/common/mq-mgr.c000066400000000000000000000103111323477647300160030ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include #include "mq-mgr.h" #include "seafile-session.h" #include "log.h" typedef struct _SeafMqManagerPriv SeafMqManagerPriv; struct _SeafMqManagerPriv { CcnetMqclientProc *mqclient_proc; CcnetTimer *timer; /* keep it in memory since we always use the same message */ CcnetMessage *heartbeat_msg; }; #define HEARTBEAT_INTERVAL 2 /* 2s */ static int heartbeat_pulse (void *vmanager); SeafMqManager * seaf_mq_manager_new (SeafileSession *seaf) { CcnetClient *client = seaf->session; SeafMqManager *mgr; SeafMqManagerPriv *priv; mgr = g_new0 (SeafMqManager, 1); priv = g_new0 (SeafMqManagerPriv, 1); mgr->seaf = seaf; mgr->priv = priv; priv->mqclient_proc = (CcnetMqclientProc *) ccnet_proc_factory_create_master_processor (client->proc_factory, "mq-client"); if (!priv->mqclient_proc) { seaf_warning ("Failed to create mqclient proc.\n"); g_free (mgr); g_free(priv); return NULL; } return mgr; } static int start_mq_client (CcnetMqclientProc *mqclient) { if (ccnet_processor_startl ((CcnetProcessor *)mqclient, NULL) < 0) { ccnet_processor_done ((CcnetProcessor *)mqclient, FALSE); seaf_warning ("Failed to start mqclient proc\n"); return -1; } seaf_message ("[mq client] mq cilent is started\n"); return 0; } int seaf_mq_manager_init (SeafMqManager *mgr) { SeafMqManagerPriv *priv = mgr->priv; if (start_mq_client(priv->mqclient_proc) < 0) return -1; return 0; } int seaf_mq_manager_start (SeafMqManager *mgr) { SeafMqManagerPriv *priv = mgr->priv; priv->timer = ccnet_timer_new (heartbeat_pulse, mgr, HEARTBEAT_INTERVAL * 1000); return 0; } static inline CcnetMessage * create_message (SeafMqManager *mgr, const char *app, const char *body, int flags) { CcnetClient *client = mgr->seaf->session; CcnetMessage *msg; char *from = client->base.id; char *to = client->base.id; msg = ccnet_message_new (from, to, app, body, flags); return msg; } void seaf_mq_manager_set_heartbeat_name (SeafMqManager *mgr, const char *app) { if (!app) return; SeafMqManagerPriv *priv = mgr->priv; if (priv->heartbeat_msg) return; seaf_message ("[mq mgr] publish to heartbeat mq: %s\n", app); priv->heartbeat_msg = create_message (seaf->mq_mgr, app, "heartbeat", 0); } /* Wrap around ccnet_message_new since all messages we use are local. */ static inline void _send_message (SeafMqManager *mgr, CcnetMessage *msg) { CcnetMqclientProc *mqclient_proc = mgr->priv->mqclient_proc; ccnet_mqclient_proc_put_message (mqclient_proc, msg); } void seaf_mq_manager_publish_message (SeafMqManager *mgr, CcnetMessage *msg) { _send_message (mgr, msg); } void seaf_mq_manager_publish_message_full (SeafMqManager *mgr, const char *app, const char *body, int flags) { CcnetMessage *msg = create_message (mgr, app, body, flags); _send_message (mgr, msg); ccnet_message_free (msg); } void seaf_mq_manager_publish_notification (SeafMqManager *mgr, const char *type, const char *content) { static const char *app = "seafile.notification"; GString *buf = g_string_new(NULL); g_string_append_printf (buf, "%s\n%s", type, content); CcnetMessage *msg = create_message (mgr, app, buf->str, 0); _send_message (mgr, msg); g_string_free (buf, TRUE); ccnet_message_free (msg); } void seaf_mq_manager_publish_event (SeafMqManager *mgr, const char *content) { static const char *app = "seaf_server.event"; CcnetMessage *msg = create_message (mgr, app, content, 0); _send_message (mgr, msg); ccnet_message_free (msg); } static int heartbeat_pulse (void *vmanager) { SeafMqManager *mgr = vmanager; _send_message (mgr, mgr->priv->heartbeat_msg); return TRUE; } seafile-6.1.5/common/mq-mgr.h000066400000000000000000000033351323477647300160200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Mq-manager is responsible for: * * - Publishing heartbeat messages every HEARTBEAT_INTERVAL senconds to * indicate it's alive. If seafile-applet doesn't get the message, it would * check and try to restart seaf-daemon. * * - Provide API for other modules to publish their messages. * * Currently we publish these types of messages: * * - seafile.heartbeat <> * - seafile.transfer * - seafile.repo_sync_done * - seafile.promt_create_repo * - seafile.repo_created * * And subscribe to no messages. */ #ifndef SEAF_MQ_MANAGER_H #define SEAF_MQ_MANAGER_H struct _CcnetMessage; typedef struct _SeafMqManager SeafMqManager; struct _SeafMqManager { struct _SeafileSession *seaf; struct _SeafMqManagerPriv *priv; }; SeafMqManager *seaf_mq_manager_new (struct _SeafileSession *seaf); void seaf_mq_manager_set_heartbeat_name (SeafMqManager *mgr, const char *app); int seaf_mq_manager_init (SeafMqManager *mgr); int seaf_mq_manager_start (SeafMqManager *mgr); void seaf_mq_manager_publish_message (SeafMqManager *mgr, struct _CcnetMessage *msg); void seaf_mq_manager_publish_message_full (SeafMqManager *mgr, const char *app, const char *body, int flags); void seaf_mq_manager_publish_notification (SeafMqManager *mgr, const char *type, const char *content); void seaf_mq_manager_publish_event (SeafMqManager *mgr, const char *content); #endif seafile-6.1.5/common/obj-backend-fs.c000066400000000000000000000331041323477647300173550ustar00rootroot00000000000000#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #include "common.h" #include "utils.h" #include "obj-backend.h" #ifndef WIN32 #include #include #include #endif #ifdef WIN32 #include #include #endif #define DEBUG_FLAG SEAFILE_DEBUG_OTHER #include "log.h" typedef struct FsPriv { char *v0_obj_dir; int v0_dir_len; char *obj_dir; int dir_len; } FsPriv; static void id_to_path (FsPriv *priv, const char *obj_id, char path[], const char *repo_id, int version) { char *pos = path; int n; #if defined MIGRATION || defined SEAFILE_CLIENT if (version > 0) { n = snprintf (path, SEAF_PATH_MAX, "%s/%s/", priv->obj_dir, repo_id); pos += n; } else { memcpy (pos, priv->v0_obj_dir, priv->v0_dir_len); pos[priv->v0_dir_len] = '/'; pos += priv->v0_dir_len + 1; } #else n = snprintf (path, SEAF_PATH_MAX, "%s/%s/", priv->obj_dir, repo_id); pos += n; #endif memcpy (pos, obj_id, 2); pos[2] = '/'; pos += 3; memcpy (pos, obj_id + 2, 41 - 2); } static int obj_backend_fs_read (ObjBackend *bend, const char *repo_id, int version, const char *obj_id, void **data, int *len) { char path[SEAF_PATH_MAX]; gsize tmp_len; GError *error = NULL; id_to_path (bend->priv, obj_id, path, repo_id, version); /* seaf_debug ("object path: %s\n", path); */ g_file_get_contents (path, (gchar**)data, &tmp_len, &error); if (error) { #ifdef MIGRATION g_clear_error (&error); id_to_path (bend->priv, obj_id, path, repo_id, 1); g_file_get_contents (path, (gchar**)data, &tmp_len, &error); if (error) { seaf_debug ("[obj backend] Failed to read object %s: %s.\n", obj_id, error->message); g_clear_error (&error); return -1; } #else seaf_debug ("[obj backend] Failed to read object %s: %s.\n", obj_id, error->message); g_clear_error (&error); return -1; #endif } *len = (int)tmp_len; return 0; } /* * Flush operating system and disk caches for @fd. */ static int fsync_obj_contents (int fd) { #ifdef __linux__ /* Some file systems may not support fsync(). * In this case, just skip the error. */ if (fsync (fd) < 0) { if (errno == EINVAL) return 0; else { seaf_warning ("Failed to fsync: %s.\n", strerror(errno)); return -1; } } return 0; #endif #ifdef __APPLE__ /* OS X: fcntl() is required to flush disk cache, fsync() only * flushes operating system cache. */ if (fcntl (fd, F_FULLFSYNC, NULL) < 0) { seaf_warning ("Failed to fsync: %s.\n", strerror(errno)); return -1; } return 0; #endif #ifdef WIN32 HANDLE handle; handle = (HANDLE)_get_osfhandle (fd); if (handle == INVALID_HANDLE_VALUE) { seaf_warning ("Failed to get handle from fd.\n"); return -1; } if (!FlushFileBuffers (handle)) { seaf_warning ("FlushFileBuffer() failed: %lu.\n", GetLastError()); return -1; } return 0; #endif } /* * Rename file from @tmp_path to @obj_path. * This also makes sure the changes to @obj_path's parent folder * is flushed to disk. */ static int rename_and_sync (const char *tmp_path, const char *obj_path) { #ifdef __linux__ char *parent_dir; int ret = 0; if (rename (tmp_path, obj_path) < 0) { seaf_warning ("Failed to rename from %s to %s: %s.\n", tmp_path, obj_path, strerror(errno)); return -1; } parent_dir = g_path_get_dirname (obj_path); int dir_fd = open (parent_dir, O_RDONLY); if (dir_fd < 0) { seaf_warning ("Failed to open dir %s: %s.\n", parent_dir, strerror(errno)); goto out; } /* Some file systems don't support fsyncing a directory. Just ignore the error. */ if (fsync (dir_fd) < 0) { if (errno != EINVAL) { seaf_warning ("Failed to fsync dir %s: %s.\n", parent_dir, strerror(errno)); ret = -1; } goto out; } out: g_free (parent_dir); if (dir_fd >= 0) close (dir_fd); return ret; #endif #ifdef __APPLE__ /* * OS X garantees an existence of obj_path always exists, * even when the system crashes. */ if (rename (tmp_path, obj_path) < 0) { seaf_warning ("Failed to rename from %s to %s: %s.\n", tmp_path, obj_path, strerror(errno)); return -1; } return 0; #endif #ifdef WIN32 wchar_t *w_tmp_path = g_utf8_to_utf16 (tmp_path, -1, NULL, NULL, NULL); wchar_t *w_obj_path = g_utf8_to_utf16 (obj_path, -1, NULL, NULL, NULL); int ret = 0; if (!MoveFileExW (w_tmp_path, w_obj_path, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { seaf_warning ("MoveFilExW failed: %lu.\n", GetLastError()); ret = -1; goto out; } out: g_free (w_tmp_path); g_free (w_obj_path); return ret; #endif } static int save_obj_contents (const char *path, const void *data, int len, gboolean need_sync) { char tmp_path[SEAF_PATH_MAX]; int fd; snprintf (tmp_path, SEAF_PATH_MAX, "%s.XXXXXX", path); fd = g_mkstemp (tmp_path); if (fd < 0) { seaf_warning ("[obj backend] Failed to open tmp file %s: %s.\n", tmp_path, strerror(errno)); return -1; } if (writen (fd, data, len) < 0) { seaf_warning ("[obj backend] Failed to write obj %s: %s.\n", tmp_path, strerror(errno)); return -1; } if (need_sync && fsync_obj_contents (fd) < 0) return -1; /* Close may return error, especially in NFS. */ if (close (fd) < 0) { seaf_warning ("[obj backend Failed close obj %s: %s.\n", tmp_path, strerror(errno)); return -1; } if (need_sync) { if (rename_and_sync (tmp_path, path) < 0) return -1; } else { if (g_rename (tmp_path, path) < 0) { seaf_warning ("[obj backend] Failed to rename %s: %s.\n", path, strerror(errno)); return -1; } } return 0; } static int create_parent_path (const char *path) { char *dir = g_path_get_dirname (path); if (!dir) return -1; if (g_file_test (dir, G_FILE_TEST_EXISTS)) { g_free (dir); return 0; } if (g_mkdir_with_parents (dir, 0777) < 0) { seaf_warning ("Failed to create object parent path %s: %s.\n", dir, strerror(errno)); g_free (dir); return -1; } g_free (dir); return 0; } static int obj_backend_fs_write (ObjBackend *bend, const char *repo_id, int version, const char *obj_id, void *data, int len, gboolean need_sync) { char path[SEAF_PATH_MAX]; id_to_path (bend->priv, obj_id, path, repo_id, version); /* GTimeVal s, e; */ /* g_get_current_time (&s); */ if (create_parent_path (path) < 0) { seaf_warning ("[obj backend] Failed to create path for obj %s:%s.\n", repo_id, obj_id); return -1; } if (save_obj_contents (path, data, len, need_sync) < 0) { seaf_warning ("[obj backend] Failed to write obj %s:%s.\n", repo_id, obj_id); return -1; } /* g_get_current_time (&e); */ /* seaf_message ("write obj time: %ldus.\n", */ /* ((e.tv_sec*1000000+e.tv_usec) - (s.tv_sec*1000000+s.tv_usec))); */ return 0; } static gboolean obj_backend_fs_exists (ObjBackend *bend, const char *repo_id, int version, const char *obj_id) { char path[SEAF_PATH_MAX]; SeafStat st; id_to_path (bend->priv, obj_id, path, repo_id, version); if (seaf_stat (path, &st) == 0) return TRUE; return FALSE; } static void obj_backend_fs_delete (ObjBackend *bend, const char *repo_id, int version, const char *obj_id) { char path[SEAF_PATH_MAX]; id_to_path (bend->priv, obj_id, path, repo_id, version); g_unlink (path); } static int obj_backend_fs_foreach_obj (ObjBackend *bend, const char *repo_id, int version, SeafObjFunc process, void *user_data) { FsPriv *priv = bend->priv; char *obj_dir = NULL; int dir_len; GDir *dir1 = NULL, *dir2; const char *dname1, *dname2; char obj_id[128]; char path[SEAF_PATH_MAX], *pos; int ret = 0; #if defined MIGRATION || defined SEAFILE_CLIENT if (version > 0) obj_dir = g_build_filename (priv->obj_dir, repo_id, NULL); else obj_dir = g_strdup(priv->v0_obj_dir); #else obj_dir = g_build_filename (priv->obj_dir, repo_id, NULL); #endif dir_len = strlen (obj_dir); dir1 = g_dir_open (obj_dir, 0, NULL); if (!dir1) { goto out; } memcpy (path, obj_dir, dir_len); pos = path + dir_len; while ((dname1 = g_dir_read_name(dir1)) != NULL) { snprintf (pos, sizeof(path) - dir_len, "/%s", dname1); dir2 = g_dir_open (path, 0, NULL); if (!dir2) { seaf_warning ("Failed to open object dir %s.\n", path); continue; } while ((dname2 = g_dir_read_name(dir2)) != NULL) { snprintf (obj_id, sizeof(obj_id), "%s%s", dname1, dname2); if (!process (repo_id, version, obj_id, user_data)) { g_dir_close (dir2); goto out; } } g_dir_close (dir2); } out: if (dir1) g_dir_close (dir1); g_free (obj_dir); return ret; } static int obj_backend_fs_copy (ObjBackend *bend, const char *src_repo_id, int src_version, const char *dst_repo_id, int dst_version, const char *obj_id) { char src_path[SEAF_PATH_MAX]; char dst_path[SEAF_PATH_MAX]; id_to_path (bend->priv, obj_id, src_path, src_repo_id, src_version); id_to_path (bend->priv, obj_id, dst_path, dst_repo_id, dst_version); if (g_file_test (dst_path, G_FILE_TEST_EXISTS)) return 0; if (create_parent_path (dst_path) < 0) { seaf_warning ("Failed to create dst path %s for obj %s.\n", dst_path, obj_id); return -1; } #ifdef WIN32 if (!CreateHardLink (dst_path, src_path, NULL)) { seaf_warning ("Failed to link %s to %s: %lu.\n", src_path, dst_path, GetLastError()); return -1; } return 0; #else int ret = link (src_path, dst_path); if (ret < 0 && errno != EEXIST) { seaf_warning ("Failed to link %s to %s: %s.\n", src_path, dst_path, strerror(errno)); return -1; } return ret; #endif } static int obj_backend_fs_remove_store (ObjBackend *bend, const char *store_id) { FsPriv *priv = bend->priv; char *obj_dir = NULL; GDir *dir1, *dir2; const char *dname1, *dname2; char *path1, *path2; obj_dir = g_build_filename (priv->obj_dir, store_id, NULL); dir1 = g_dir_open (obj_dir, 0, NULL); if (!dir1) { g_free (obj_dir); return 0; } while ((dname1 = g_dir_read_name(dir1)) != NULL) { path1 = g_build_filename (obj_dir, dname1, NULL); dir2 = g_dir_open (path1, 0, NULL); if (!dir2) { seaf_warning ("Failed to open obj dir %s.\n", path1); g_dir_close (dir1); g_free (path1); g_free (obj_dir); return -1; } while ((dname2 = g_dir_read_name(dir2)) != NULL) { path2 = g_build_filename (path1, dname2, NULL); g_unlink (path2); g_free (path2); } g_dir_close (dir2); g_rmdir (path1); g_free (path1); } g_dir_close (dir1); g_rmdir (obj_dir); g_free (obj_dir); return 0; } ObjBackend * obj_backend_fs_new (const char *seaf_dir, const char *obj_type) { ObjBackend *bend; FsPriv *priv; bend = g_new0(ObjBackend, 1); priv = g_new0(FsPriv, 1); bend->priv = priv; priv->v0_obj_dir = g_build_filename (seaf_dir, obj_type, NULL); priv->v0_dir_len = strlen(priv->v0_obj_dir); priv->obj_dir = g_build_filename (seaf_dir, "storage", obj_type, NULL); priv->dir_len = strlen (priv->obj_dir); if (g_mkdir_with_parents (priv->v0_obj_dir, 0777) < 0) { seaf_warning ("[Obj Backend] Objects dir %s does not exist and" " is unable to create\n", priv->v0_obj_dir); goto onerror; } if (g_mkdir_with_parents (priv->obj_dir, 0777) < 0) { seaf_warning ("[Obj Backend] Objects dir %s does not exist and" " is unable to create\n", priv->obj_dir); goto onerror; } bend->read = obj_backend_fs_read; bend->write = obj_backend_fs_write; bend->exists = obj_backend_fs_exists; bend->delete = obj_backend_fs_delete; bend->foreach_obj = obj_backend_fs_foreach_obj; bend->copy = obj_backend_fs_copy; bend->remove_store = obj_backend_fs_remove_store; return bend; onerror: g_free (priv->v0_obj_dir); g_free (priv->obj_dir); g_free (priv); g_free (bend); return NULL; } seafile-6.1.5/common/obj-backend-riak.c000066400000000000000000000067251323477647300177040ustar00rootroot00000000000000#include "common.h" #include "log.h" #include "obj-backend.h" #ifdef RIAK_BACKEND #include "riak-client.h" #include typedef struct RiakPriv { const char *host; const char *port; const char *bucket; int n_write; GQueue *conn_pool; pthread_mutex_t lock; } RiakPriv; static SeafRiakClient * get_connection (RiakPriv *priv) { SeafRiakClient *connection; pthread_mutex_lock (&priv->lock); connection = g_queue_pop_head (priv->conn_pool); if (!connection) connection = seaf_riak_client_new (priv->host, priv->port); pthread_mutex_unlock (&priv->lock); return connection; } static void return_connection (RiakPriv *priv, SeafRiakClient *connection) { pthread_mutex_lock (&priv->lock); g_queue_push_tail (priv->conn_pool, connection); pthread_mutex_unlock (&priv->lock); } static int obj_backend_riak_read (ObjBackend *bend, const char *obj_id, void **data, int *len) { SeafRiakClient *conn = get_connection (bend->priv); RiakPriv *priv = bend->priv; int ret; ret = seaf_riak_client_get (conn, priv->bucket, obj_id, data, len); return_connection (priv, conn); return ret; } static int obj_backend_riak_write (ObjBackend *bend, const char *obj_id, void *data, int len) { SeafRiakClient *conn = get_connection (bend->priv); RiakPriv *priv = bend->priv; int ret; ret = seaf_riak_client_put (conn, priv->bucket, obj_id, data, len, priv->n_write); return_connection (priv, conn); return ret; } static gboolean obj_backend_riak_exists (ObjBackend *bend, const char *obj_id) { SeafRiakClient *conn = get_connection (bend->priv); RiakPriv *priv = bend->priv; gboolean ret; ret = seaf_riak_client_query (conn, priv->bucket, obj_id); return_connection (priv, conn); return ret; } static void obj_backend_riak_delete (ObjBackend *bend, const char *obj_id) { SeafRiakClient *conn = get_connection (bend->priv); RiakPriv *priv = bend->priv; seaf_riak_client_delete (conn, priv->bucket, obj_id, priv->n_write); return_connection (priv, conn); } ObjBackend * obj_backend_riak_new (const char *host, const char *port, const char *bucket, const char *write_policy) { ObjBackend *bend; RiakPriv *priv; bend = g_new0(ObjBackend, 1); priv = g_new0(RiakPriv, 1); bend->priv = priv; priv->host = g_strdup (host); priv->port = g_strdup (port); priv->bucket = g_strdup (bucket); if (strcmp (write_policy, "quorum") == 0) priv->n_write = RIAK_QUORUM; else if (strcmp (write_policy, "all") == 0) priv->n_write = RIAK_ALL; else g_return_val_if_reached (NULL); priv->conn_pool = g_queue_new (); pthread_mutex_init (&priv->lock, NULL); bend->read = obj_backend_riak_read; bend->write = obj_backend_riak_write; bend->exists = obj_backend_riak_exists; bend->delete = obj_backend_riak_delete; return bend; } #else ObjBackend * obj_backend_riak_new (const char *host, const char *port, const char *bucket, const char *write_policy) { seaf_warning ("Riak backend is not enabled.\n"); return NULL; } #endif /* RIAK_BACKEND */ seafile-6.1.5/common/obj-backend.h000066400000000000000000000032611323477647300167550ustar00rootroot00000000000000#ifndef OBJ_BACKEND_H #define OBJ_BACKEND_H #include #include "obj-store.h" typedef struct ObjBackend ObjBackend; struct ObjBackend { int (*read) (ObjBackend *bend, const char *repo_id, int version, const char *obj_id, void **data, int *len); int (*write) (ObjBackend *bend, const char *repo_id, int version, const char *obj_id, void *data, int len, gboolean need_sync); gboolean (*exists) (ObjBackend *bend, const char *repo_id, int version, const char *obj_id); void (*delete) (ObjBackend *bend, const char *repo_id, int version, const char *obj_id); int (*foreach_obj) (ObjBackend *bend, const char *repo_id, int version, SeafObjFunc process, void *user_data); int (*copy) (ObjBackend *bend, const char *src_repo_id, int src_version, const char *dst_repo_id, int dst_version, const char *obj_id); int (*remove_store) (ObjBackend *bend, const char *store_id); void *priv; }; #endif seafile-6.1.5/common/obj-store.c000066400000000000000000000365471323477647300165320ustar00rootroot00000000000000#include "common.h" #include "log.h" #include #include "seafile-session.h" #include "utils.h" #include "obj-backend.h" #include "obj-store.h" #define MAX_READER_THREADS 2 #define MAX_WRITER_THREADS 2 #define MAX_STAT_THREADS 2 typedef struct AsyncTask { guint32 rw_id; char obj_id[41]; void *data; int len; gboolean need_sync; gboolean success; } AsyncTask; typedef struct OSCallbackStruct { char repo_id[37]; int version; OSAsyncCallback cb; void *cb_data; } OSCallbackStruct; struct SeafObjStore { ObjBackend *bend; CEventManager *ev_mgr; /* For async read. */ guint32 next_rd_id; GThreadPool *read_tpool; GHashTable *readers; guint32 read_ev_id; /* For async write. */ guint32 next_wr_id; GThreadPool *write_tpool; GHashTable *writers; guint32 write_ev_id; /* For async stat. */ guint32 next_st_id; GThreadPool *stat_tpool; GHashTable *stats; guint32 stat_ev_id; }; typedef struct SeafObjStore SeafObjStore; static void reader_thread (void *data, void *user_data); static void writer_thread (void *data, void *user_data); static void stat_thread (void *data, void *user_data); static void on_read_done (CEvent *event, void *data); static void on_write_done (CEvent *event, void *data); static void on_stat_done (CEvent *event, void *data); extern ObjBackend * obj_backend_fs_new (const char *seaf_dir, const char *obj_type); struct SeafObjStore * seaf_obj_store_new (SeafileSession *seaf, const char *obj_type) { SeafObjStore *store = g_new0 (SeafObjStore, 1); if (!store) return NULL; store->bend = obj_backend_fs_new (seaf->seaf_dir, obj_type); if (!store->bend) { seaf_warning ("[Object store] Failed to load backend.\n"); g_free (store); return NULL; } return store; } static int async_init (SeafObjStore *obj_store, CEventManager *ev_mgr) { GError *error = NULL; obj_store->ev_mgr = ev_mgr; obj_store->read_tpool = g_thread_pool_new (reader_thread, obj_store, MAX_READER_THREADS, FALSE, &error); if (error) { seaf_warning ("Failed to start reader thread pool: %s.\n", error->message); g_clear_error (&error); return -1; } obj_store->readers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); obj_store->read_ev_id = cevent_manager_register (ev_mgr, on_read_done, obj_store); obj_store->write_tpool = g_thread_pool_new (writer_thread, obj_store, MAX_WRITER_THREADS, FALSE, &error); if (error) { seaf_warning ("Failed to start writer thread pool: %s.\n", error->message); g_clear_error (&error); return -1; } obj_store->writers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); obj_store->write_ev_id = cevent_manager_register (ev_mgr, on_write_done, obj_store); obj_store->stat_tpool = g_thread_pool_new (stat_thread, obj_store, MAX_STAT_THREADS, FALSE, &error); if (error) { seaf_warning ("Failed to start statr thread pool: %s.\n", error->message); g_clear_error (&error); return -1; } obj_store->stats = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); obj_store->stat_ev_id = cevent_manager_register (ev_mgr, on_stat_done, obj_store); return 0; } int seaf_obj_store_init (SeafObjStore *obj_store, gboolean enable_async, CEventManager *ev_mgr) { if (enable_async && async_init (obj_store, ev_mgr) < 0) return -1; return 0; } int seaf_obj_store_read_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id, void **data, int *len) { ObjBackend *bend = obj_store->bend; if (!repo_id || !is_uuid_valid(repo_id) || !obj_id || !is_object_id_valid(obj_id)) return -1; return bend->read (bend, repo_id, version, obj_id, data, len); } int seaf_obj_store_write_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id, void *data, int len, gboolean need_sync) { ObjBackend *bend = obj_store->bend; if (!repo_id || !is_uuid_valid(repo_id) || !obj_id || !is_object_id_valid(obj_id)) return -1; return bend->write (bend, repo_id, version, obj_id, data, len, need_sync); } gboolean seaf_obj_store_obj_exists (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id) { ObjBackend *bend = obj_store->bend; if (!repo_id || !is_uuid_valid(repo_id) || !obj_id || !is_object_id_valid(obj_id)) return FALSE; return bend->exists (bend, repo_id, version, obj_id); } void seaf_obj_store_delete_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id) { ObjBackend *bend = obj_store->bend; if (!repo_id || !is_uuid_valid(repo_id) || !obj_id || !is_object_id_valid(obj_id)) return; return bend->delete (bend, repo_id, version, obj_id); } int seaf_obj_store_foreach_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, SeafObjFunc process, void *user_data) { ObjBackend *bend = obj_store->bend; return bend->foreach_obj (bend, repo_id, version, process, user_data); } int seaf_obj_store_copy_obj (struct SeafObjStore *obj_store, const char *src_repo_id, int src_version, const char *dst_repo_id, int dst_version, const char *obj_id) { ObjBackend *bend = obj_store->bend; if (strcmp (obj_id, EMPTY_SHA1) == 0) return 0; return bend->copy (bend, src_repo_id, src_version, dst_repo_id, dst_version, obj_id); } static void reader_thread (void *data, void *user_data) { AsyncTask *task = data; SeafObjStore *obj_store = user_data; ObjBackend *bend = obj_store->bend; OSCallbackStruct *callback; callback = g_hash_table_lookup (obj_store->readers, (gpointer)(long)(task->rw_id)); if (callback) { task->success = TRUE; if (bend->read (bend, callback->repo_id, callback->version, task->obj_id, &task->data, &task->len) < 0) task->success = FALSE; } cevent_manager_add_event (obj_store->ev_mgr, obj_store->read_ev_id, task); } static void stat_thread (void *data, void *user_data) { AsyncTask *task = data; SeafObjStore *obj_store = user_data; ObjBackend *bend = obj_store->bend; OSCallbackStruct *callback; callback = g_hash_table_lookup (obj_store->stats, (gpointer)(long)(task->rw_id)); if (callback) { task->success = TRUE; if (!bend->exists (bend, callback->repo_id, callback->version, task->obj_id)) task->success = FALSE; } cevent_manager_add_event (obj_store->ev_mgr, obj_store->stat_ev_id, task); } static void writer_thread (void *data, void *user_data) { AsyncTask *task = data; SeafObjStore *obj_store = user_data; ObjBackend *bend = obj_store->bend; OSCallbackStruct *callback; callback = g_hash_table_lookup (obj_store->writers, (gpointer)(long)(task->rw_id)); if (callback) { task->success = TRUE; if (bend->write (bend, callback->repo_id, callback->version, task->obj_id, task->data, task->len, task->need_sync) < 0) task->success = FALSE; } cevent_manager_add_event (obj_store->ev_mgr, obj_store->write_ev_id, task); } static void on_read_done (CEvent *event, void *user_data) { AsyncTask *task = event->data; SeafObjStore *obj_store = user_data; OSCallbackStruct *callback; OSAsyncResult res; callback = g_hash_table_lookup (obj_store->readers, (gpointer)(long)(task->rw_id)); if (callback) { res.rw_id = task->rw_id; memcpy (res.obj_id, task->obj_id, 41); res.data = task->data; res.len = task->len; res.success = task->success; callback->cb (&res, callback->cb_data); } g_free (task->data); g_free (task); } static void on_stat_done (CEvent *event, void *user_data) { AsyncTask *task = event->data; SeafObjStore *obj_store = user_data; OSCallbackStruct *callback; OSAsyncResult res; callback = g_hash_table_lookup (obj_store->stats, (gpointer)(long)(task->rw_id)); if (callback) { res.rw_id = task->rw_id; memcpy (res.obj_id, task->obj_id, 41); res.data = NULL; res.len = task->len; res.success = task->success; callback->cb (&res, callback->cb_data); } g_free (task->data); g_free (task); } static void on_write_done (CEvent *event, void *user_data) { AsyncTask *task = event->data; SeafObjStore *obj_store = user_data; OSCallbackStruct *callback; OSAsyncResult res; callback = g_hash_table_lookup (obj_store->writers, (gpointer)(long)(task->rw_id)); if (callback) { res.rw_id = task->rw_id; memcpy (res.obj_id, task->obj_id, 41); res.data = task->data; res.len = task->len; res.success = task->success; callback->cb (&res, callback->cb_data); } g_free (task->data); g_free (task); } guint32 seaf_obj_store_register_async_read (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data) { guint32 id = obj_store->next_rd_id++; OSCallbackStruct *cb_struct = g_new0 (OSCallbackStruct, 1); memcpy (cb_struct->repo_id, repo_id, 36); cb_struct->version = version; cb_struct->cb = callback; cb_struct->cb_data = cb_data; g_hash_table_insert (obj_store->readers, (gpointer)(long)id, cb_struct); return id; } void seaf_obj_store_unregister_async_read (struct SeafObjStore *obj_store, guint32 reader_id) { g_hash_table_remove (obj_store->readers, (gpointer)(long)reader_id); } int seaf_obj_store_async_read (struct SeafObjStore *obj_store, guint32 reader_id, const char *obj_id) { AsyncTask *task = g_new0 (AsyncTask, 1); GError *error = NULL; task->rw_id = reader_id; memcpy (task->obj_id, obj_id, 41); g_thread_pool_push (obj_store->read_tpool, task, &error); if (error) { seaf_warning ("Failed to start aysnc read of %s.\n", obj_id); return -1; } return 0; } guint32 seaf_obj_store_register_async_stat (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data) { guint32 id = obj_store->next_st_id++; OSCallbackStruct *cb_struct = g_new0 (OSCallbackStruct, 1); memcpy (cb_struct->repo_id, repo_id, 36); cb_struct->version = version; cb_struct->cb = callback; cb_struct->cb_data = cb_data; g_hash_table_insert (obj_store->stats, (gpointer)(long)id, cb_struct); return id; } void seaf_obj_store_unregister_async_stat (struct SeafObjStore *obj_store, guint32 stat_id) { g_hash_table_remove (obj_store->stats, (gpointer)(long)stat_id); } int seaf_obj_store_async_stat (struct SeafObjStore *obj_store, guint32 stat_id, const char *obj_id) { AsyncTask *task = g_new0 (AsyncTask, 1); GError *error = NULL; task->rw_id = stat_id; memcpy (task->obj_id, obj_id, 41); g_thread_pool_push (obj_store->stat_tpool, task, &error); if (error) { seaf_warning ("Failed to start aysnc stat of %s.\n", obj_id); return -1; } return 0; } guint32 seaf_obj_store_register_async_write (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data) { guint32 id = obj_store->next_rd_id++; OSCallbackStruct *cb_struct = g_new0 (OSCallbackStruct, 1); memcpy (cb_struct->repo_id, repo_id, 36); cb_struct->version = version; cb_struct->cb = callback; cb_struct->cb_data = cb_data; g_hash_table_insert (obj_store->writers, (gpointer)(long)id, cb_struct); return id; } void seaf_obj_store_unregister_async_write (struct SeafObjStore *obj_store, guint32 writer_id) { g_hash_table_remove (obj_store->writers, (gpointer)(long)writer_id); } int seaf_obj_store_async_write (struct SeafObjStore *obj_store, guint32 writer_id, const char *obj_id, const void *obj_data, int data_len, gboolean need_sync) { AsyncTask *task = g_new0 (AsyncTask, 1); GError *error = NULL; task->rw_id = writer_id; memcpy (task->obj_id, obj_id, 41); task->data = g_memdup (obj_data, data_len); task->len = data_len; task->need_sync = need_sync; g_thread_pool_push (obj_store->write_tpool, task, &error); if (error) { seaf_warning ("Failed to start aysnc write of %s.\n", obj_id); return -1; } return 0; } int seaf_obj_store_remove_store (struct SeafObjStore *obj_store, const char *store_id) { ObjBackend *bend = obj_store->bend; return bend->remove_store (bend, store_id); } seafile-6.1.5/common/obj-store.h000066400000000000000000000107301323477647300165210ustar00rootroot00000000000000#ifndef OBJ_STORE_H #define OBJ_STORE_H #include #include struct _SeafileSession; struct SeafObjStore; struct CEventManager; struct SeafObjStore * seaf_obj_store_new (struct _SeafileSession *seaf, const char *obj_type); int seaf_obj_store_init (struct SeafObjStore *obj_store, gboolean enable_async, struct CEventManager *ev_mgr); /* Synchronous I/O interface. */ int seaf_obj_store_read_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id, void **data, int *len); int seaf_obj_store_write_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id, void *data, int len, gboolean need_sync); gboolean seaf_obj_store_obj_exists (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id); void seaf_obj_store_delete_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, const char *obj_id); typedef gboolean (*SeafObjFunc) (const char *repo_id, int version, const char *obj_id, void *user_data); int seaf_obj_store_foreach_obj (struct SeafObjStore *obj_store, const char *repo_id, int version, SeafObjFunc process, void *user_data); int seaf_obj_store_copy_obj (struct SeafObjStore *obj_store, const char *src_store_id, int src_version, const char *dst_store_id, int dst_version, const char *obj_id); /* Asynchronous I/O interface. */ typedef struct OSAsyncResult { guint32 rw_id; char obj_id[41]; /* @data is owned by obj-store, don't free it. */ void *data; int len; gboolean success; } OSAsyncResult; typedef void (*OSAsyncCallback) (OSAsyncResult *res, void *cb_data); /* Async read */ guint32 seaf_obj_store_register_async_read (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data); void seaf_obj_store_unregister_async_read (struct SeafObjStore *obj_store, guint32 reader_id); int seaf_obj_store_async_read (struct SeafObjStore *obj_store, guint32 reader_id, const char *obj_id); /* Async write */ guint32 seaf_obj_store_register_async_write (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data); void seaf_obj_store_unregister_async_write (struct SeafObjStore *obj_store, guint32 writer_id); int seaf_obj_store_async_write (struct SeafObjStore *obj_store, guint32 writer_id, const char *obj_id, const void *obj_data, int data_len, gboolean need_sync); /* Async stat */ guint32 seaf_obj_store_register_async_stat (struct SeafObjStore *obj_store, const char *repo_id, int version, OSAsyncCallback callback, void *cb_data); void seaf_obj_store_unregister_async_stat (struct SeafObjStore *obj_store, guint32 stat_id); int seaf_obj_store_async_stat (struct SeafObjStore *obj_store, guint32 stat_id, const char *obj_id); int seaf_obj_store_remove_store (struct SeafObjStore *obj_store, const char *store_id); #endif seafile-6.1.5/common/object-list.c000066400000000000000000000023051323477647300170260ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "object-list.h" ObjectList * object_list_new () { ObjectList *ol = g_new0 (ObjectList, 1); ol->obj_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); ol->obj_ids = g_ptr_array_new_with_free_func (g_free); return ol; } void object_list_free (ObjectList *ol) { if (ol->obj_hash) g_hash_table_destroy (ol->obj_hash); g_ptr_array_free (ol->obj_ids, TRUE); g_free (ol); } void object_list_serialize (ObjectList *ol, uint8_t **buffer, uint32_t *len) { uint32_t i; uint32_t offset = 0; uint8_t *buf; int ollen = object_list_length(ol); buf = g_new (uint8_t, 41 * ollen); for (i = 0; i < ollen; ++i) { memcpy (&buf[offset], g_ptr_array_index(ol->obj_ids, i), 41); offset += 41; } *buffer = buf; *len = 41 * ollen; } gboolean object_list_insert (ObjectList *ol, const char *object_id) { if (g_hash_table_lookup (ol->obj_hash, object_id)) return FALSE; char *id = g_strdup(object_id); g_hash_table_replace (ol->obj_hash, id, id); g_ptr_array_add (ol->obj_ids, id); return TRUE; } seafile-6.1.5/common/object-list.h000066400000000000000000000014421323477647300170340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef OBJECT_LIST_H #define OBJECT_LIST_H #include typedef struct { GHashTable *obj_hash; GPtrArray *obj_ids; } ObjectList; ObjectList * object_list_new (); void object_list_free (ObjectList *ol); void object_list_serialize (ObjectList *ol, uint8_t **buffer, uint32_t *len); /** * Add object to ObjectList. * Return FALSE if it is already in the list, TRUE otherwise. */ gboolean object_list_insert (ObjectList *ol, const char *object_id); inline static gboolean object_list_exists (ObjectList *ol, const char *object_id) { return (g_hash_table_lookup(ol->obj_hash, object_id) != NULL); } inline static int object_list_length (ObjectList *ol) { return ol->obj_ids->len; } #endif seafile-6.1.5/common/processors/000077500000000000000000000000001323477647300166455ustar00rootroot00000000000000seafile-6.1.5/common/processors/objecttx-common.h000066400000000000000000000025431323477647300221320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef OBJECTTX_COMMON_H #define OBJECTTX_COMMON_H #define SC_GET_OBJECT "301" #define SS_GET_OBJECT "Get Object" #define SC_OBJECT "302" #define SS_OBJECT "Object" #define SC_END "303" #define SS_END "END" #define SC_COMMIT_IDS "304" #define SS_COMMIT_IDS "Commit IDs" #define SC_ACK "305" #define SS_ACK "Ack" #define SC_OBJ_SEG "306" #define SS_OBJ_SEG "Object Segment" #define SC_OBJ_SEG_END "307" #define SS_OBJ_SEG_END "Object Segment End" #define SC_OBJ_LIST_SEG "308" #define SS_OBJ_LIST_SEG "Object List Segment" #define SC_OBJ_LIST_SEG_END "309" #define SS_OBJ_LIST_SEG_END "Object List Segment End" #define SC_NOT_FOUND "401" #define SS_NOT_FOUND "Object not found" #define SC_BAD_OL "402" #define SS_BAD_OL "Bad Object List" #define SC_BAD_OBJECT "403" #define SS_BAD_OBJECT "Bad Object" #define SC_ACCESS_DENIED "410" #define SS_ACCESS_DENIED "Access denied" /* for fs transfer */ #define SC_ROOT "304" #define SS_ROOT "FS Root" #define SC_ROOT_END "305" #define SS_ROOT_END "FS Root End" /* max fs object segment size */ #define MAX_OBJ_SEG_SIZE 64000 typedef struct { char id[41]; uint8_t object[0]; } __attribute__((__packed__)) ObjectPack; #endif seafile-6.1.5/common/rpc-service.c000066400000000000000000004506461323477647300170500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include #include "utils.h" #include "seafile-session.h" #include "fs-mgr.h" #include "repo-mgr.h" #include "seafile-error.h" #include "seafile-rpc.h" #ifdef SEAFILE_SERVER #include "web-accesstoken-mgr.h" #endif #ifndef SEAFILE_SERVER #include "seafile-config.h" #endif #define DEBUG_FLAG SEAFILE_DEBUG_OTHER #include "log.h" #ifndef SEAFILE_SERVER #include "../daemon/vc-utils.h" #endif /* SEAFILE_SERVER */ /* -------- Utilities -------- */ static GObject* convert_repo (SeafRepo *r) { SeafileRepo *repo = NULL; #ifndef SEAFILE_SERVER if (r->head == NULL) return NULL; if (r->worktree_invalid && !seafile_session_config_get_allow_invalid_worktree(seaf)) return NULL; #endif repo = seafile_repo_new (); if (!repo) return NULL; g_object_set (repo, "id", r->id, "name", r->name, "desc", r->desc, "encrypted", r->encrypted, "magic", r->magic, "enc_version", r->enc_version, "head_cmmt_id", r->head ? r->head->commit_id : NULL, "root", r->root_id, "version", r->version, "last_modify", (int)r->last_modify, NULL); g_object_set (repo, "repo_id", r->id, "repo_name", r->name, "repo_desc", r->desc, "last_modified", (int)r->last_modify, NULL); #ifdef SEAFILE_SERVER if (r->virtual_info) { g_object_set (repo, "is_virtual", TRUE, "origin_repo_id", r->virtual_info->origin_repo_id, "origin_path", r->virtual_info->path, NULL); } if (r->encrypted && r->enc_version == 2) g_object_set (repo, "random_key", r->random_key, NULL); g_object_set (repo, "store_id", r->store_id, "repaired", r->repaired, "size", r->size, "file_count", r->file_count, NULL); #endif #ifndef SEAFILE_SERVER g_object_set (repo, "worktree", r->worktree, "relay-id", r->relay_id, "worktree-invalid", r->worktree_invalid, "last-sync-time", r->last_sync_time, "auto-sync", r->auto_sync, NULL); #endif /* SEAFILE_SERVER */ return (GObject *)repo; } static void free_repo_obj (gpointer repo) { if (!repo) return; g_object_unref ((GObject *)repo); } static GList * convert_repo_list (GList *inner_repos) { GList *ret = NULL, *ptr; GObject *repo = NULL; for (ptr = inner_repos; ptr; ptr=ptr->next) { SeafRepo *r = ptr->data; repo = convert_repo (r); if (!repo) { g_list_free_full (ret, free_repo_obj); return NULL; } ret = g_list_prepend (ret, repo); } return g_list_reverse (ret); } /* * RPC functions only available for clients. */ #ifndef SEAFILE_SERVER #include "sync-mgr.h" GObject * seafile_get_session_info (GError **error) { SeafileSessionInfo *info; info = seafile_session_info_new (); g_object_set (info, "datadir", seaf->seaf_dir, NULL); return (GObject *) info; } int seafile_set_config (const char *key, const char *value, GError **error) { return seafile_session_config_set_string(seaf, key, value); } char * seafile_get_config (const char *key, GError **error) { return seafile_session_config_get_string(seaf, key); } int seafile_set_config_int (const char *key, int value, GError **error) { return seafile_session_config_set_int(seaf, key, value); } int seafile_get_config_int (const char *key, GError **error) { gboolean exists = TRUE; int ret = seafile_session_config_get_int(seaf, key, &exists); if (!exists) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Config not exists"); return -1; } return ret; } int seafile_set_upload_rate_limit (int limit, GError **error) { if (limit < 0) limit = 0; seaf->sync_mgr->upload_limit = limit; return seafile_session_config_set_int (seaf, KEY_UPLOAD_LIMIT, limit); } int seafile_set_download_rate_limit (int limit, GError **error) { if (limit < 0) limit = 0; seaf->sync_mgr->download_limit = limit; return seafile_session_config_set_int (seaf, KEY_DOWNLOAD_LIMIT, limit); } int seafile_repo_last_modify(const char *repo_id, GError **error) { SeafRepo *repo; int ctime = 0; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "No such repository"); return -1; } ctime = repo->last_modify; #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif return ctime; } GObject * seafile_get_checkout_task (const char *repo_id, GError **error) { if (!repo_id) { seaf_warning ("Invalid args\n"); return NULL; } CheckoutTask *task; task = seaf_repo_manager_get_checkout_task(seaf->repo_mgr, repo_id); if (!task) return NULL; SeafileCheckoutTask *c_task = g_object_new (SEAFILE_TYPE_CHECKOUT_TASK, "repo_id", task->repo_id, "worktree", task->worktree, "total_files", task->total_files, "finished_files", task->finished_files, NULL); return (GObject *)c_task; } char * seafile_gen_default_worktree (const char *worktree_parent, const char *repo_name, GError **error) { if (!worktree_parent || !repo_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty args"); return NULL; } return seaf_clone_manager_gen_default_worktree (seaf->clone_mgr, worktree_parent, repo_name); } int seafile_check_path_for_clone (const char *path, GError **error) { if (!seaf_clone_manager_check_worktree_path(seaf->clone_mgr, path, error)) { return -1; } return 0; } char * seafile_clone (const char *repo_id, int repo_version, const char *relay_id, const char *repo_name, const char *worktree, const char *token, const char *passwd, const char *magic, const char *peer_addr, const char *peer_port, const char *email, const char *random_key, int enc_version, const char *more_info, GError **error) { if (!repo_id || strlen(repo_id) != 36) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!relay_id || strlen(relay_id) != 40) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id"); return NULL; } if (!worktree) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Worktre must be specified"); return NULL; } if (!token || !peer_addr || !peer_port || !email ) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument can't be NULL"); return NULL; } return seaf_clone_manager_add_task (seaf->clone_mgr, repo_id, repo_version, relay_id, repo_name, token, passwd, magic, enc_version, random_key, worktree, peer_addr, peer_port, email, more_info, error); } char * seafile_download (const char *repo_id, int repo_version, const char *relay_id, const char *repo_name, const char *wt_parent, const char *token, const char *passwd, const char *magic, const char *peer_addr, const char *peer_port, const char *email, const char *random_key, int enc_version, const char *more_info, GError **error) { if (!repo_id || strlen(repo_id) != 36) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!relay_id || strlen(relay_id) != 40) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id"); return NULL; } if (!wt_parent) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Worktre must be specified"); return NULL; } if (!token || !peer_addr || !peer_port || !email ) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument can't be NULL"); return NULL; } return seaf_clone_manager_add_download_task (seaf->clone_mgr, repo_id, repo_version, relay_id, repo_name, token, passwd, magic, enc_version, random_key, wt_parent, peer_addr, peer_port, email, more_info, error); } int seafile_cancel_clone_task (const char *repo_id, GError **error) { return seaf_clone_manager_cancel_task (seaf->clone_mgr, repo_id); } int seafile_remove_clone_task (const char *repo_id, GError **error) { return seaf_clone_manager_remove_task (seaf->clone_mgr, repo_id); } GList * seafile_get_clone_tasks (GError **error) { GList *tasks, *ptr; GList *ret = NULL; CloneTask *task; SeafileCloneTask *t; tasks = seaf_clone_manager_get_tasks (seaf->clone_mgr); for (ptr = tasks; ptr != NULL; ptr = ptr->next) { task = ptr->data; t = g_object_new (SEAFILE_TYPE_CLONE_TASK, "state", clone_task_state_to_str(task->state), "error_str", clone_task_error_to_str(task->error), "err_detail", task->err_detail, "repo_id", task->repo_id, "repo_name", task->repo_name, "worktree", task->worktree, NULL); ret = g_list_prepend (ret, t); } g_list_free (tasks); return ret; } int seafile_sync (const char *repo_id, const char *peer_id, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo ID should not be null"); return -1; } return seaf_sync_manager_add_sync_task (seaf->sync_mgr, repo_id, error); } static void get_task_size(TransferTask *task, gint64 *rsize, gint64 *dsize) { if (task->runtime_state == TASK_RT_STATE_INIT || task->runtime_state == TASK_RT_STATE_COMMIT || task->runtime_state == TASK_RT_STATE_FS || task->runtime_state == TASK_RT_STATE_FINISHED) { *rsize = task->rsize; *dsize = task->dsize; } if (task->runtime_state == TASK_RT_STATE_DATA) { if (task->type == TASK_TYPE_DOWNLOAD) { *dsize = task->block_list->n_valid_blocks; *rsize = task->block_list->n_blocks - *dsize; } else { *dsize = task->n_uploaded; *rsize = task->block_list->n_blocks - *dsize; } } } static SeafileTask * convert_task (TransferTask *task) { gint64 rsize = 0, dsize = 0; SeafileTask *t = seafile_task_new(); if (task->protocol_version < 7) get_task_size (task, &rsize, &dsize); g_object_set (t, "repo_id", task->repo_id, "state", task_state_to_str(task->state), "rt_state", task_rt_state_to_str(task->runtime_state), "error_str", task_error_str(task->error), NULL); if (task->type == TASK_TYPE_DOWNLOAD) { g_object_set (t, "ttype", "download", NULL); if (task->runtime_state == TASK_RT_STATE_DATA) { if (task->protocol_version >= 7) g_object_set (t, "block_total", (gint64)task->n_to_download, "block_done", (gint64)transfer_task_get_done_blocks (task), NULL); else g_object_set (t, "block_total", (gint64)task->block_list->n_blocks, "block_done", (gint64)transfer_task_get_done_blocks (task), NULL); g_object_set (t, "rate", transfer_task_get_rate(task), NULL); } } else { g_object_set (t, "ttype", "upload", NULL); if (task->runtime_state == TASK_RT_STATE_DATA) { g_object_set (t, "block_total", (gint64)task->block_list->n_blocks, "block_done", (gint64)transfer_task_get_done_blocks (task), NULL); g_object_set (t, "rate", transfer_task_get_rate(task), NULL); } } return t; } static SeafileTask * convert_http_task (HttpTxTask *task) { SeafileTask *t = seafile_task_new(); g_object_set (t, "repo_id", task->repo_id, "state", http_task_state_to_str(task->state), "rt_state", http_task_rt_state_to_str(task->runtime_state), "error_str", http_task_error_str(task->error), NULL); if (task->type == HTTP_TASK_TYPE_DOWNLOAD) { g_object_set (t, "ttype", "download", NULL); if (task->runtime_state == HTTP_TASK_RT_STATE_BLOCK) { g_object_set (t, "block_total", (gint64)task->n_files, "block_done", (gint64)task->done_files, NULL); g_object_set (t, "rate", http_tx_task_get_rate(task), NULL); } else if (task->runtime_state == HTTP_TASK_RT_STATE_FS) { g_object_set (t, "fs_objects_total", task->n_fs_objs, "fs_objects_done", task->done_fs_objs, NULL); } } else { g_object_set (t, "ttype", "upload", NULL); if (task->runtime_state == HTTP_TASK_RT_STATE_BLOCK) { SyncInfo *info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, task->repo_id); if (info && info->multipart_upload) { g_object_set (t, "block_total", info->total_bytes, "block_done", info->uploaded_bytes, NULL); } else { g_object_set (t, "block_total", (gint64)task->n_blocks, "block_done", (gint64)task->done_blocks, NULL); } g_object_set (t, "rate", http_tx_task_get_rate(task), NULL); } } return t; } GObject * seafile_find_transfer_task (const char *repo_id, GError *error) { TransferTask *task; HttpTxTask *http_task; task = seaf_transfer_manager_find_transfer_by_repo (seaf->transfer_mgr, repo_id); if (task) return (GObject *)convert_task (task); http_task = http_tx_manager_find_task (seaf->http_tx_mgr, repo_id); if (http_task) return (GObject *)convert_http_task (http_task); return NULL; } int seafile_get_upload_rate(GError **error) { return seaf->sync_mgr->last_sent_bytes; } int seafile_get_download_rate(GError **error) { return seaf->sync_mgr->last_recv_bytes; } GObject * seafile_get_repo_sync_info (const char *repo_id, GError **error) { SyncInfo *info; info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); if (!info) return NULL; SeafileSyncInfo *sinfo; sinfo = g_object_new (SEAFILE_TYPE_SYNC_INFO, "repo_id", info->repo_id, "head_commit", info->head_commit, "deleted_on_relay", info->deleted_on_relay, "need_fetch", info->need_fetch, "need_upload", info->need_upload, "need_merge", info->need_merge, /* "last_sync_time", info->last_sync_time, */ NULL); return (GObject *)sinfo; } GObject * seafile_get_repo_sync_task (const char *repo_id, GError **error) { SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { return NULL; } SyncInfo *info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); if (!info || !info->current_task) return NULL; SyncTask *task = info->current_task; const char *sync_state; char allzeros[41] = {0}; if (!info->in_sync && memcmp(allzeros, info->head_commit, 41) == 0) { sync_state = "waiting for sync"; } else { sync_state = sync_state_to_str(task->state); if (strcmp(sync_state, "error") == 0 && !info->in_error) sync_state = "synchronized"; } SeafileSyncTask *s_task; s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK, "force_upload", task->is_manual_sync, "state", sync_state, "error", sync_error_to_str(task->error), "err_detail", task->err_detail, "repo_id", info->repo_id, NULL); return (GObject *)s_task; } GList * seafile_get_sync_task_list (GError **error) { GHashTable *sync_info_tbl = seaf->sync_mgr->sync_infos; GHashTableIter iter; SeafileSyncTask *s_task; GList *task_list = NULL; gpointer key, value; g_hash_table_iter_init (&iter, sync_info_tbl); while (g_hash_table_iter_next (&iter, &key, &value)) { SyncInfo *info = value; if (!info->in_sync) continue; SyncTask *task = info->current_task; if (!task) continue; s_task = g_object_new (SEAFILE_TYPE_SYNC_TASK, "force_upload", task->is_manual_sync, "state", sync_state_to_str(task->state), "error", sync_error_to_str(task->error), "repo_id", info->repo_id, NULL); task_list = g_list_prepend (task_list, s_task); } return task_list; } int seafile_set_repo_property (const char *repo_id, const char *key, const char *value, GError **error) { int ret; if (repo_id == NULL || key == NULL || value == NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Can't find Repo %s", repo_id); return -1; } ret = seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, key, value); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to set key for repo %s", repo_id); return -1; } return 0; } gchar * seafile_get_repo_property (const char *repo_id, const char *key, GError **error) { char *value = NULL; if (!repo_id || !key) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Can't find Repo %s", repo_id); return NULL; } value = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, key); return value; } char * seafile_get_repo_relay_address (const char *repo_id, GError **error) { char *relay_addr = NULL; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo_id, &relay_addr, NULL); return relay_addr; } char * seafile_get_repo_relay_port (const char *repo_id, GError **error) { char *relay_port = NULL; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo_id, NULL, &relay_port); return relay_port; } int seafile_update_repo_relay_info (const char *repo_id, const char *new_addr, const char *new_port, GError **error) { if (!repo_id || !new_addr || !new_port) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } int port = atoi(new_port); if (port <= 0 || port > 65535) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid port"); return -1; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { return -1; } CcnetPeer *relay = ccnet_get_peer (seaf->ccnetrpc_client, repo->relay_id); if (!relay) { GString *buf = g_string_new(NULL); g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", repo->relay_id, new_addr, new_port); ccnet_send_command (seaf->session, buf->str, NULL, NULL); g_string_free (buf, TRUE); } else { if (g_strcmp0(relay->public_addr, new_addr) != 0 || relay->public_port != (uint16_t)port) { ccnet_update_peer_address (seaf->ccnetrpc_client, repo->relay_id, new_addr, port); } g_object_unref (relay); } return seaf_repo_manager_update_repo_relay_info (seaf->repo_mgr, repo, new_addr, new_port); } int seafile_update_repos_server_host (const char *old_host, const char *new_host, const char *new_server_url, GError **error) { if (!old_host || !new_host || !new_server_url) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } return seaf_repo_manager_update_repos_server_host( seaf->repo_mgr, old_host, new_host, new_server_url); } int seafile_calc_dir_size (const char *path, GError **error) { if (!path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } gint64 size_64 = ccnet_calc_directory_size(path, error); if (size_64 < 0) { seaf_warning ("failed to calculate dir size for %s\n", path); return -1; } /* get the size in MB */ int size = (int) (size_64 >> 20); return size; } int seafile_disable_auto_sync (GError **error) { return seaf_sync_manager_disable_auto_sync (seaf->sync_mgr); } int seafile_enable_auto_sync (GError **error) { return seaf_sync_manager_enable_auto_sync (seaf->sync_mgr); } int seafile_is_auto_sync_enabled (GError **error) { return seaf_sync_manager_is_auto_sync_enabled (seaf->sync_mgr); } char * seafile_get_path_sync_status (const char *repo_id, const char *path, int is_dir, GError **error) { char *canon_path = NULL; int len; char *status; if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } /* Empty path means to get status of the worktree folder. */ if (strcmp (path, "") != 0) { if (*path == '/') ++path; canon_path = g_strdup(path); len = strlen(canon_path); if (canon_path[len-1] == '/') canon_path[len-1] = 0; } else { canon_path = g_strdup(path); } status = seaf_sync_manager_get_path_sync_status (seaf->sync_mgr, repo_id, canon_path, is_dir); g_free (canon_path); return status; } int seafile_mark_file_locked (const char *repo_id, const char *path, GError **error) { char *canon_path = NULL; int len; int ret; if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (*path == '/') ++path; if (path[0] == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path"); return -1; } canon_path = g_strdup(path); len = strlen(canon_path); if (canon_path[len-1] == '/') canon_path[len-1] = 0; ret = seaf_filelock_manager_mark_file_locked (seaf->filelock_mgr, repo_id, path, FALSE); g_free (canon_path); return ret; } int seafile_mark_file_unlocked (const char *repo_id, const char *path, GError **error) { char *canon_path = NULL; int len; int ret; if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (*path == '/') ++path; if (path[0] == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path"); return -1; } canon_path = g_strdup(path); len = strlen(canon_path); if (canon_path[len-1] == '/') canon_path[len-1] = 0; ret = seaf_filelock_manager_mark_file_unlocked (seaf->filelock_mgr, repo_id, path); g_free (canon_path); return ret; } char * seafile_get_server_property (const char *server_url, const char *key, GError **error) { if (!server_url || !key) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } return seaf_repo_manager_get_server_property (seaf->repo_mgr, server_url, key); } int seafile_set_server_property (const char *server_url, const char *key, const char *value, GError **error) { if (!server_url || !key || !value) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } return seaf_repo_manager_set_server_property (seaf->repo_mgr, server_url, key, value); } GList * seafile_get_file_sync_errors (int offset, int limit, GError **error) { return seaf_repo_manager_get_file_sync_errors (seaf->repo_mgr, offset, limit); } #endif /* not define SEAFILE_SERVER */ /* * RPC functions available for both clients and server. */ GList * seafile_branch_gets (const char *repo_id, GError **error) { if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } GList *blist = seaf_branch_manager_get_branch_list(seaf->branch_mgr, repo_id); GList *ptr; GList *ret = NULL; for (ptr = blist; ptr; ptr=ptr->next) { SeafBranch *b = ptr->data; SeafileBranch *branch = seafile_branch_new (); g_object_set (branch, "repo_id", b->repo_id, "name", b->name, "commit_id", b->commit_id, NULL); ret = g_list_prepend (ret, branch); seaf_branch_unref (b); } ret = g_list_reverse (ret); g_list_free (blist); return ret; } #ifdef SEAFILE_SERVER GList* seafile_get_trash_repo_list (int start, int limit, GError **error) { return seaf_repo_manager_get_trash_repo_list (seaf->repo_mgr, start, limit, error); } GList * seafile_get_trash_repos_by_owner (const char *owner, GError **error) { if (!owner) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } return seaf_repo_manager_get_trash_repos_by_owner (seaf->repo_mgr, owner, error); } int seafile_del_repo_from_trash (const char *repo_id, GError **error) { int ret = 0; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } ret = seaf_repo_manager_del_repo_from_trash (seaf->repo_mgr, repo_id, error); return ret; } int seafile_empty_repo_trash (GError **error) { return seaf_repo_manager_empty_repo_trash (seaf->repo_mgr, error); } int seafile_empty_repo_trash_by_owner (const char *owner, GError **error) { if (!owner) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } return seaf_repo_manager_empty_repo_trash_by_owner (seaf->repo_mgr, owner, error); } int seafile_restore_repo_from_trash (const char *repo_id, GError **error) { int ret = 0; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } ret = seaf_repo_manager_restore_repo_from_trash (seaf->repo_mgr, repo_id, error); return ret; } #endif GList* seafile_get_repo_list (int start, int limit, GError **error) { GList *repos = seaf_repo_manager_get_repo_list(seaf->repo_mgr, start, limit); GList *ret = NULL; ret = convert_repo_list (repos); #ifdef SEAFILE_SERVER GList *ptr; for (ptr = repos; ptr != NULL; ptr = ptr->next) seaf_repo_unref ((SeafRepo *)ptr->data); #endif g_list_free (repos); return ret; } #ifdef SEAFILE_SERVER gint64 seafile_count_repos (GError **error) { return seaf_repo_manager_count_repos (seaf->repo_mgr, error); } #endif GObject* seafile_get_repo (const char *repo_id, GError **error) { SeafRepo *r; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } r = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); /* Don't return repo that's not checked out. */ if (r == NULL) return NULL; GObject *repo = convert_repo (r); #ifdef SEAFILE_SERVER seaf_repo_unref (r); #endif return repo; } SeafileCommit * convert_to_seafile_commit (SeafCommit *c) { SeafileCommit *commit = seafile_commit_new (); g_object_set (commit, "id", c->commit_id, "creator_name", c->creator_name, "creator", c->creator_id, "desc", c->desc, "ctime", c->ctime, "repo_id", c->repo_id, "root_id", c->root_id, "parent_id", c->parent_id, "second_parent_id", c->second_parent_id, "version", c->version, "new_merge", c->new_merge, "conflict", c->conflict, "device_name", c->device_name, NULL); return commit; } GObject* seafile_get_commit (const char *repo_id, int version, const gchar *id, GError **error) { SeafileCommit *commit; SeafCommit *c; if (!repo_id || !is_uuid_valid(repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!id || !is_object_id_valid(id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return NULL; } c = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, id); if (!c) return NULL; commit = convert_to_seafile_commit (c); seaf_commit_unref (c); return (GObject *)commit; } struct CollectParam { int offset; int limit; int count; GList *commits; #ifdef SEAFILE_SERVER gint64 truncate_time; gboolean traversed_head; #endif }; static gboolean get_commit (SeafCommit *c, void *data, gboolean *stop) { struct CollectParam *cp = data; #ifdef SEAFILE_SERVER if (cp->truncate_time == 0) { *stop = TRUE; /* Stop after traversing the head commit. */ } /* We use <= here. This is for handling clean trash and history. * If the user cleans all history, truncate time will be equal to * the commit's ctime. In such case, we don't actually want to display * this commit. */ else if (cp->truncate_time > 0 && (gint64)(c->ctime) <= cp->truncate_time && cp->traversed_head) { *stop = TRUE; return TRUE; } /* Always traverse the head commit. */ if (!cp->traversed_head) cp->traversed_head = TRUE; #endif /* if offset = 1, limit = 1, we should stop when the count = 2 */ if (cp->limit > 0 && cp->count >= cp->offset + cp->limit) { *stop = TRUE; return TRUE; /* TRUE to indicate no error */ } if (cp->count >= cp->offset) { SeafileCommit *commit = convert_to_seafile_commit (c); cp->commits = g_list_prepend (cp->commits, commit); } ++cp->count; return TRUE; /* TRUE to indicate no error */ } GList* seafile_get_commit_list (const char *repo_id, int offset, int limit, GError **error) { SeafRepo *repo; GList *commits = NULL; gboolean ret; struct CollectParam cp; char *commit_id; if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } /* correct parameter */ if (offset < 0) offset = 0; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "No such repository"); return NULL; } if (!repo->head) { SeafBranch *branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "master"); if (branch != NULL) { commit_id = g_strdup (branch->commit_id); seaf_branch_unref (branch); } else { seaf_warning ("[repo-mgr] Failed to get repo %s branch master\n", repo_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "No head and branch master"); #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif return NULL; } } else { commit_id = g_strdup (repo->head->commit_id); } /* Init CollectParam */ memset (&cp, 0, sizeof(cp)); cp.offset = offset; cp.limit = limit; #ifdef SEAFILE_SERVER cp.truncate_time = seaf_repo_manager_get_repo_truncate_time (seaf->repo_mgr, repo_id); #endif ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, repo->id, repo->version, commit_id, get_commit, &cp, TRUE); g_free (commit_id); #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif if (!ret) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_LIST_COMMITS, "Failed to list commits"); return NULL; } commits = g_list_reverse (cp.commits); return commits; } #ifndef SEAFILE_SERVER static int do_unsync_repo(SeafRepo *repo) { if (!seaf->started) { seaf_message ("System not started, skip removing repo.\n"); return -1; } if (repo->auto_sync && (repo->sync_interval == 0)) seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id); seaf_sync_manager_cancel_sync_task (seaf->sync_mgr, repo->id); SyncInfo *info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo->id); /* If we are syncing the repo, * we just mark the repo as deleted and let sync-mgr actually delete it. * Otherwise we are safe to delete the repo. */ char *worktree = g_strdup (repo->worktree); if (info != NULL && info->in_sync) { seaf_repo_manager_mark_repo_deleted (seaf->repo_mgr, repo); } else { seaf_repo_manager_del_repo (seaf->repo_mgr, repo); } g_free (worktree); return 0; } static void cancel_clone_tasks_by_account (const char *account_server, const char *account_email) { GList *ptr, *tasks; CloneTask *task; tasks = seaf_clone_manager_get_tasks (seaf->clone_mgr); for (ptr = tasks; ptr != NULL; ptr = ptr->next) { task = ptr->data; if (g_strcmp0(account_server, task->peer_addr) == 0 && g_strcmp0(account_email, task->email) == 0) { seaf_clone_manager_cancel_task (seaf->clone_mgr, task->repo_id); } } g_list_free (tasks); } int seafile_unsync_repos_by_account (const char *server_addr, const char *email, GError **error) { if (!server_addr || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } GList *ptr, *repos = seaf_repo_manager_get_repo_list(seaf->repo_mgr, -1, -1); if (!repos) { return 0; } for (ptr = repos; ptr; ptr = ptr->next) { SeafRepo *repo = (SeafRepo*)ptr->data; char *addr = NULL; seaf_repo_manager_get_repo_relay_info(seaf->repo_mgr, repo->id, &addr, /* addr */ NULL); /* port */ if (g_strcmp0(addr, server_addr) == 0 && g_strcmp0(repo->email, email) == 0) { if (do_unsync_repo(repo) < 0) { return -1; } } g_free (addr); } g_list_free (repos); cancel_clone_tasks_by_account (server_addr, email); return 0; } int seafile_remove_repo_tokens_by_account (const char *server_addr, const char *email, GError **error) { if (!server_addr || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } GList *ptr, *repos = seaf_repo_manager_get_repo_list(seaf->repo_mgr, -1, -1); if (!repos) { return 0; } for (ptr = repos; ptr; ptr = ptr->next) { SeafRepo *repo = (SeafRepo*)ptr->data; char *addr = NULL; seaf_repo_manager_get_repo_relay_info(seaf->repo_mgr, repo->id, &addr, /* addr */ NULL); /* port */ if (g_strcmp0(addr, server_addr) == 0 && g_strcmp0(repo->email, email) == 0) { if (seaf_repo_manager_remove_repo_token(seaf->repo_mgr, repo) < 0) { return -1; } } g_free (addr); } g_list_free (repos); cancel_clone_tasks_by_account (server_addr, email); return 0; } int seafile_set_repo_token (const char *repo_id, const char *token, GError **error) { int ret; if (repo_id == NULL || token == NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Can't find Repo %s", repo_id); return -1; } ret = seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, token); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to set token for repo %s", repo_id); return -1; } return 0; } #endif int seafile_destroy_repo (const char *repo_id, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } #ifndef SEAFILE_SERVER SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No such repository"); return -1; } return do_unsync_repo(repo); #else return seaf_repo_manager_del_repo (seaf->repo_mgr, repo_id, error); #endif } GObject * seafile_generate_magic_and_random_key(int enc_version, const char* repo_id, const char *passwd, GError **error) { if (!repo_id || !passwd) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } gchar magic[65] = {0}; gchar random_key[97] = {0}; seafile_generate_magic (CURRENT_ENC_VERSION, repo_id, passwd, magic); seafile_generate_random_key (passwd, random_key); SeafileEncryptionInfo *sinfo; sinfo = g_object_new (SEAFILE_TYPE_ENCRYPTION_INFO, "repo_id", repo_id, "passwd", passwd, "enc_version", CURRENT_ENC_VERSION, "magic", magic, "random_key", random_key, NULL); return (GObject *)sinfo; } #include "diff-simple.h" inline static const char* get_diff_status_str(char status) { if (status == DIFF_STATUS_ADDED) return "add"; if (status == DIFF_STATUS_DELETED) return "del"; if (status == DIFF_STATUS_MODIFIED) return "mod"; if (status == DIFF_STATUS_RENAMED) return "mov"; if (status == DIFF_STATUS_DIR_ADDED) return "newdir"; if (status == DIFF_STATUS_DIR_DELETED) return "deldir"; return NULL; } GList * seafile_diff (const char *repo_id, const char *arg1, const char *arg2, int fold_dir_diff, GError **error) { SeafRepo *repo; char *err_msgs = NULL; GList *diff_entries, *p; GList *ret = NULL; if (!repo_id || !arg1 || !arg2) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if ((arg1[0] != 0 && !is_object_id_valid (arg1)) || !is_object_id_valid(arg2)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No such repository"); return NULL; } diff_entries = seaf_repo_diff (repo, arg1, arg2, fold_dir_diff, &err_msgs); if (err_msgs) { g_set_error (error, SEAFILE_DOMAIN, -1, "%s", err_msgs); g_free (err_msgs); #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif return NULL; } #ifdef SEAFILE_SERVER seaf_repo_unref (repo); #endif for (p = diff_entries; p != NULL; p = p->next) { DiffEntry *de = p->data; SeafileDiffEntry *entry = g_object_new ( SEAFILE_TYPE_DIFF_ENTRY, "status", get_diff_status_str(de->status), "name", de->name, "new_name", de->new_name, NULL); ret = g_list_prepend (ret, entry); } for (p = diff_entries; p != NULL; p = p->next) { DiffEntry *de = p->data; diff_entry_free (de); } g_list_free (diff_entries); return g_list_reverse (ret); } /* * RPC functions only available for server. */ #ifdef SEAFILE_SERVER GList * seafile_list_dir_by_path(const char *repo_id, const char *commit_id, const char *path, GError **error) { SeafRepo *repo = NULL; SeafCommit *commit = NULL; SeafDir *dir; SeafDirent *dent; SeafileDirent *d; GList *ptr; GList *res = NULL; if (!repo_id || !commit_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Args can't be NULL"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!is_object_id_valid (commit_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return NULL; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo->version, commit_id); if (!commit) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_COMMIT, "No such commit"); goto out; } char *rpath = format_dir_path (path); dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, rpath, error); g_free (rpath); if (!dir) { seaf_warning ("Can't find seaf dir for %s in repo %s\n", path, repo->store_id); goto out; } for (ptr = dir->entries; ptr != NULL; ptr = ptr->next) { dent = ptr->data; if (!is_object_id_valid (dent->id)) continue; d = g_object_new (SEAFILE_TYPE_DIRENT, "obj_id", dent->id, "obj_name", dent->name, "mode", dent->mode, "version", dent->version, "mtime", dent->mtime, "size", dent->size, NULL); res = g_list_prepend (res, d); } seaf_dir_free (dir); res = g_list_reverse (res); out: seaf_repo_unref (repo); seaf_commit_unref (commit); return res; } static void filter_error (GError **error) { if (*error && g_error_matches(*error, SEAFILE_DOMAIN, SEAF_ERR_PATH_NO_EXIST)) { g_clear_error (error); } } char * seafile_get_dir_id_by_commit_and_path(const char *repo_id, const char *commit_id, const char *path, GError **error) { SeafRepo *repo = NULL; char *res = NULL; SeafCommit *commit = NULL; SeafDir *dir; if (!repo_id || !commit_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Args can't be NULL"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!is_object_id_valid (commit_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return NULL; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo->version, commit_id); if (!commit) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_COMMIT, "No such commit"); goto out; } char *rpath = format_dir_path (path); dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, rpath, error); g_free (rpath); if (!dir) { seaf_warning ("Can't find seaf dir for %s in repo %s\n", path, repo->store_id); filter_error (error); goto out; } res = g_strdup (dir->dir_id); seaf_dir_free (dir); out: seaf_repo_unref (repo); seaf_commit_unref (commit); return res; } int seafile_edit_repo (const char *repo_id, const char *name, const char *description, const char *user, GError **error) { SeafRepo *repo = NULL; SeafCommit *commit = NULL, *parent = NULL; int ret = 0; if (!user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No user given"); return -1; } if (!name && !description) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "At least one argument should be non-null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } retry: repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No such library"); return -1; } if (!name) name = repo->name; if (!description) description = repo->desc; /* * We only change repo_name or repo_desc, so just copy the head commit * and change these two fields. */ parent = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!parent) { seaf_warning ("Failed to get commit %s:%s.\n", repo->id, repo->head->commit_id); ret = -1; goto out; } commit = seaf_commit_new (NULL, repo->id, parent->root_id, user, EMPTY_SHA1, "Changed library name or description", 0); commit->parent_id = g_strdup(parent->commit_id); seaf_repo_to_commit (repo, commit); g_free (commit->repo_name); commit->repo_name = g_strdup(name); g_free (commit->repo_desc); commit->repo_desc = g_strdup(description); if (seaf_commit_manager_add_commit (seaf->commit_mgr, commit) < 0) { ret = -1; goto out; } seaf_branch_set_commit (repo->head, commit->commit_id); if (seaf_branch_manager_test_and_update_branch (seaf->branch_mgr, repo->head, parent->commit_id) < 0) { seaf_repo_unref (repo); seaf_commit_unref (commit); seaf_commit_unref (parent); repo = NULL; commit = NULL; parent = NULL; goto retry; } out: seaf_commit_unref (commit); seaf_commit_unref (parent); seaf_repo_unref (repo); return ret; } int seafile_change_repo_passwd (const char *repo_id, const char *old_passwd, const char *new_passwd, const char *user, GError **error) { SeafRepo *repo = NULL; SeafCommit *commit = NULL, *parent = NULL; int ret = 0; if (!user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No user given"); return -1; } if (!old_passwd || old_passwd[0] == 0 || !new_passwd || new_passwd[0] == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty passwd"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } retry: repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "No such library"); return -1; } if (!repo->encrypted) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo not encrypted"); return -1; } if (repo->enc_version < 2) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Unsupported enc version"); return -1; } if (seafile_verify_repo_passwd (repo_id, old_passwd, repo->magic, 2) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Incorrect password"); return -1; } parent = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!parent) { seaf_warning ("Failed to get commit %s:%s.\n", repo->id, repo->head->commit_id); ret = -1; goto out; } char new_magic[65], new_random_key[97]; seafile_generate_magic (2, repo_id, new_passwd, new_magic); if (seafile_update_random_key (old_passwd, repo->random_key, new_passwd, new_random_key) < 0) { ret = -1; goto out; } memcpy (repo->magic, new_magic, 64); memcpy (repo->random_key, new_random_key, 96); commit = seaf_commit_new (NULL, repo->id, parent->root_id, user, EMPTY_SHA1, "Changed library password", 0); commit->parent_id = g_strdup(parent->commit_id); seaf_repo_to_commit (repo, commit); if (seaf_commit_manager_add_commit (seaf->commit_mgr, commit) < 0) { ret = -1; goto out; } seaf_branch_set_commit (repo->head, commit->commit_id); if (seaf_branch_manager_test_and_update_branch (seaf->branch_mgr, repo->head, parent->commit_id) < 0) { seaf_repo_unref (repo); seaf_commit_unref (commit); seaf_commit_unref (parent); repo = NULL; commit = NULL; parent = NULL; goto retry; } if (seaf_passwd_manager_is_passwd_set (seaf->passwd_mgr, repo_id, user)) seaf_passwd_manager_set_passwd (seaf->passwd_mgr, repo_id, user, new_passwd, error); out: seaf_commit_unref (commit); seaf_commit_unref (parent); seaf_repo_unref (repo); return ret; } int seafile_is_repo_owner (const char *email, const char *repo_id, GError **error) { if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return 0; } char *owner = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, repo_id); if (!owner) { /* seaf_warning ("Failed to get owner info for repo %s.\n", repo_id); */ return 0; } if (strcmp(owner, email) != 0) { g_free (owner); return 0; } g_free (owner); return 1; } int seafile_set_repo_owner(const char *repo_id, const char *email, GError **error) { if (!repo_id || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } return seaf_repo_manager_set_repo_owner(seaf->repo_mgr, repo_id, email); } char * seafile_get_repo_owner (const char *repo_id, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *owner = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, repo_id); /* if (!owner){ */ /* seaf_warning ("Failed to get repo owner for repo %s.\n", repo_id); */ /* } */ return owner; } GList * seafile_get_orphan_repo_list(GError **error) { GList *ret = NULL; GList *repos, *ptr; repos = seaf_repo_manager_get_orphan_repo_list(seaf->repo_mgr); ret = convert_repo_list (repos); for (ptr = repos; ptr; ptr = ptr->next) { seaf_repo_unref ((SeafRepo *)ptr->data); } g_list_free (repos); return ret; } GList * seafile_list_owned_repos (const char *email, int ret_corrupted, GError **error) { GList *ret = NULL; GList *repos, *ptr; char *repo_id = NULL; int is_shared; repos = seaf_repo_manager_get_repos_by_owner (seaf->repo_mgr, email, ret_corrupted); ret = convert_repo_list (repos); for (ptr = ret; ptr; ptr = ptr->next) { g_object_get (ptr->data, "repo_id", &repo_id, NULL); is_shared = seaf_share_manager_is_repo_shared (seaf->share_mgr, repo_id); if (is_shared < 0) { g_free (repo_id); break; } else { g_object_set (ptr->data, "is_shared", is_shared, NULL); g_free (repo_id); } } while (ptr) { g_object_set (ptr->data, "is_shared", FALSE, NULL); ptr = ptr->prev; } for(ptr = repos; ptr; ptr = ptr->next) { seaf_repo_unref ((SeafRepo *)ptr->data); } g_list_free (repos); return ret; } int seafile_add_chunk_server (const char *server, GError **error) { SeafCSManager *cs_mgr = seaf->cs_mgr; CcnetPeer *peer; peer = ccnet_get_peer_by_idname (seaf->ccnetrpc_client, server); if (!peer) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id or name %s", server); return -1; } if (seaf_cs_manager_add_chunk_server (cs_mgr, peer->id) < 0) { g_object_unref (peer); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to add chunk server %s", server); return -1; } g_object_unref (peer); return 0; } int seafile_del_chunk_server (const char *server, GError **error) { SeafCSManager *cs_mgr = seaf->cs_mgr; CcnetPeer *peer; peer = ccnet_get_peer_by_idname (seaf->ccnetrpc_client, server); if (!peer) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid peer id or name %s", server); return -1; } if (seaf_cs_manager_del_chunk_server (cs_mgr, peer->id) < 0) { g_object_unref (peer); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Failed to delete chunk server %s", server); return -1; } g_object_unref (peer); return 0; } char * seafile_list_chunk_servers (GError **error) { SeafCSManager *cs_mgr = seaf->cs_mgr; GList *servers, *ptr; char *cs_id; CcnetPeer *peer; GString *buf = g_string_new (""); servers = seaf_cs_manager_get_chunk_servers (cs_mgr); ptr = servers; while (ptr) { cs_id = ptr->data; peer = ccnet_get_peer (seaf->ccnetrpc_client, cs_id); if (!peer) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal error"); g_string_free (buf, TRUE); return NULL; } g_object_unref (peer); g_string_append_printf (buf, "%s\n", cs_id); ptr = ptr->next; } g_list_free (servers); return (g_string_free (buf, FALSE)); } gint64 seafile_get_user_quota_usage (const char *email, GError **error) { gint64 ret; if (!email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad user id"); return -1; } ret = seaf_quota_manager_get_user_usage (seaf->quota_mgr, email); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal server error"); return -1; } return ret; } gint64 seafile_get_user_share_usage (const char *email, GError **error) { gint64 ret; if (!email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad user id"); return -1; } ret = seaf_quota_manager_get_user_share_usage (seaf->quota_mgr, email); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal server error"); return -1; } return ret; } gint64 seafile_server_repo_size(const char *repo_id, GError **error) { gint64 ret; if (!repo_id || strlen(repo_id) != 36) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } ret = seaf_repo_manager_get_repo_size (seaf->repo_mgr, repo_id); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal server error"); return -1; } return ret; } int seafile_set_repo_history_limit (const char *repo_id, int days, GError **error) { if (!repo_id || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (seaf_repo_manager_set_repo_history_limit (seaf->repo_mgr, repo_id, days) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "DB Error"); return -1; } return 0; } int seafile_get_repo_history_limit (const char *repo_id, GError **error) { if (!repo_id || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } return seaf_repo_manager_get_repo_history_limit (seaf->repo_mgr, repo_id); } int seafile_repo_set_access_property (const char *repo_id, const char *ap, GError **error) { int ret; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (strlen(repo_id) != 36) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Wrong repo id"); return -1; } if (g_strcmp0(ap, "public") != 0 && g_strcmp0(ap, "own") != 0 && g_strcmp0(ap, "private") != 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Wrong access property"); return -1; } ret = seaf_repo_manager_set_access_property (seaf->repo_mgr, repo_id, ap); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal server error"); return -1; } return ret; } char * seafile_repo_query_access_property (const char *repo_id, GError **error) { char *ret; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (strlen(repo_id) != 36) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Wrong repo id"); return NULL; } ret = seaf_repo_manager_query_access_property (seaf->repo_mgr, repo_id); return ret; } char * seafile_web_get_access_token (const char *repo_id, const char *obj_id, const char *op, const char *username, int use_onetime, GError **error) { char *token; if (!repo_id || !obj_id || !op || !username) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Missing args"); return NULL; } token = seaf_web_at_manager_get_access_token (seaf->web_at_mgr, repo_id, obj_id, op, username, use_onetime, error); return token; } GObject * seafile_web_query_access_token (const char *token, GError **error) { SeafileWebAccess *webaccess = NULL; if (!token) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Token should not be null"); return NULL; } webaccess = seaf_web_at_manager_query_access_token (seaf->web_at_mgr, token); if (webaccess) return (GObject *)webaccess; return NULL; } char * seafile_query_zip_progress (const char *token, GError **error) { return zip_download_mgr_query_zip_progress (seaf->zip_download_mgr, token, error); } int seafile_add_share (const char *repo_id, const char *from_email, const char *to_email, const char *permission, GError **error) { int ret; if (!repo_id || !from_email || !to_email || !permission) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Missing args"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (g_strcmp0 (from_email, to_email) == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Can not share repo to myself"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } ret = seaf_share_manager_add_share (seaf->share_mgr, repo_id, from_email, to_email, permission); return ret; } GList * seafile_list_share_repos (const char *email, const char *type, int start, int limit, GError **error) { if (g_strcmp0 (type, "from_email") != 0 && g_strcmp0 (type, "to_email") != 0 ) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Wrong type argument"); return NULL; } return seaf_share_manager_list_share_repos (seaf->share_mgr, email, type, start, limit); } GList * seafile_list_repo_shared_to (const char *from_user, const char *repo_id, GError **error) { if (!from_user || !repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Missing args"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } return seaf_share_manager_list_repo_shared_to (seaf->share_mgr, from_user, repo_id, error); } int seafile_share_subdir_to_user (const char *repo_id, const char *path, const char *owner, const char *share_user, const char *permission, const char *passwd, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (is_empty_string (share_user)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_user parameter"); return -1; } if (strcmp (owner, share_user) == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Can't share subdir to myself"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } char *real_path; char *vrepo_name; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); // Use subdir name as virtual repo name and description vrepo_name = g_path_get_basename (real_path); vrepo_id = seaf_repo_manager_create_virtual_repo (seaf->repo_mgr, repo_id, real_path, vrepo_name, vrepo_name, owner, passwd, error); if (!vrepo_id) { ret = -1; goto out; } ret = seaf_share_manager_add_share (seaf->share_mgr, vrepo_id, owner, share_user, permission); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to share subdir to user"); } g_free (vrepo_id); out: g_free (vrepo_name); g_free (real_path); return ret; } int seafile_unshare_subdir_for_user (const char *repo_id, const char *path, const char *owner, const char *share_user, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (is_empty_string (share_user) || strcmp (owner, share_user) == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_user parameter"); return -1; } char *real_path; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); vrepo_id = seaf_repo_manager_get_virtual_repo_id (seaf->repo_mgr, repo_id, real_path, owner); if (!vrepo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to get shared sub repo"); ret = -1; goto out; } ret = seaf_share_manager_remove_share (seaf->share_mgr, vrepo_id, owner, share_user); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to unshare subdir for user"); } g_free (vrepo_id); out: g_free (real_path); return ret; } int seafile_update_share_subdir_perm_for_user (const char *repo_id, const char *path, const char *owner, const char *share_user, const char *permission, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (is_empty_string (share_user) || strcmp (owner, share_user) == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_user parameter"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } char *real_path; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); vrepo_id = seaf_repo_manager_get_virtual_repo_id (seaf->repo_mgr, repo_id, real_path, owner); if (!vrepo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to get shared sub repo"); ret = -1; goto out; } ret = seaf_share_manager_set_permission (seaf->share_mgr, vrepo_id, owner, share_user, permission); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to update share subdir permission for user"); } g_free (vrepo_id); out: g_free (real_path); return ret; } GList * seafile_list_repo_shared_group (const char *from_user, const char *repo_id, GError **error) { if (!from_user || !repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Missing args"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } return seaf_share_manager_list_repo_shared_group (seaf->share_mgr, from_user, repo_id, error); } int seafile_remove_share (const char *repo_id, const char *from_email, const char *to_email, GError **error) { int ret; if (!repo_id || !from_email ||!to_email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Missing args"); return -1; } ret = seaf_share_manager_remove_share (seaf->share_mgr, repo_id, from_email, to_email); return ret; } /* Group repo RPC. */ int seafile_group_share_repo (const char *repo_id, int group_id, const char *user_name, const char *permission, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; int ret; if (group_id <= 0 || !user_name || !repo_id || !permission) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad input argument"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } ret = seaf_repo_manager_add_group_repo (mgr, repo_id, group_id, user_name, permission, error); return ret; } int seafile_group_unshare_repo (const char *repo_id, int group_id, const char *user_name, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; int ret; if (!user_name || !repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "User name and repo id can not be NULL"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } ret = seaf_repo_manager_del_group_repo (mgr, repo_id, group_id, error); return ret; } int seafile_share_subdir_to_group (const char *repo_id, const char *path, const char *owner, int share_group, const char *permission, const char *passwd, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (share_group < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_group parameter"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } char *real_path; char *vrepo_name; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); // Use subdir name as virtual repo name and description vrepo_name = g_path_get_basename (real_path); vrepo_id = seaf_repo_manager_create_virtual_repo (seaf->repo_mgr, repo_id, real_path, vrepo_name, vrepo_name, owner, passwd, error); if (!vrepo_id) { ret = -1; goto out; } ret = seaf_repo_manager_add_group_repo (seaf->repo_mgr, vrepo_id, share_group, owner, permission, error); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to share subdir to group"); } g_free (vrepo_id); out: g_free (vrepo_name); g_free (real_path); return ret; } int seafile_unshare_subdir_for_group (const char *repo_id, const char *path, const char *owner, int share_group, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (share_group < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_group parameter"); return -1; } char *real_path; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); vrepo_id = seaf_repo_manager_get_virtual_repo_id (seaf->repo_mgr, repo_id, real_path, owner); if (!vrepo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to get shared sub repo"); ret = -1; goto out; } ret = seaf_repo_manager_del_group_repo (seaf->repo_mgr, vrepo_id, share_group, error); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to unshare subdir for group"); } g_free (vrepo_id); out: g_free (real_path); return ret; } int seafile_update_share_subdir_perm_for_group (const char *repo_id, const char *path, const char *owner, int share_group, const char *permission, GError **error) { if (is_empty_string (repo_id) || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (is_empty_string (path) || strcmp (path, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid path parameter"); return -1; } if (is_empty_string (owner)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid owner parameter"); return -1; } if (share_group < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid share_group parameter"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } char *real_path; char *vrepo_id; int ret = 0; real_path = format_dir_path (path); vrepo_id = seaf_repo_manager_get_virtual_repo_id (seaf->repo_mgr, repo_id, real_path, owner); if (!vrepo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to get shared sub repo"); ret = -1; goto out; } ret = seaf_repo_manager_set_group_repo_perm (seaf->repo_mgr, vrepo_id, share_group, permission, error); if (ret < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to update share subdir permission for group"); } g_free (vrepo_id); out: g_free (real_path); return ret; } char * seafile_get_shared_groups_by_repo(const char *repo_id, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; GList *group_ids = NULL, *ptr; GString *result; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } group_ids = seaf_repo_manager_get_groups_by_repo (mgr, repo_id, error); if (!group_ids) { return NULL; } result = g_string_new(""); ptr = group_ids; while (ptr) { g_string_append_printf (result, "%d\n", (int)(long)ptr->data); ptr = ptr->next; } g_list_free (group_ids); return g_string_free (result, FALSE); } char * seafile_get_group_repoids (int group_id, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; GList *repo_ids = NULL, *ptr; GString *result; repo_ids = seaf_repo_manager_get_group_repoids (mgr, group_id, error); if (!repo_ids) { return NULL; } result = g_string_new(""); ptr = repo_ids; while (ptr) { g_string_append_printf (result, "%s\n", (char *)ptr->data); g_free (ptr->data); ptr = ptr->next; } g_list_free (repo_ids); return g_string_free (result, FALSE); } GList * seafile_get_repos_by_group (int group_id, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; GList *ret = NULL; if (group_id < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid group id."); return NULL; } ret = seaf_repo_manager_get_repos_by_group (mgr, group_id, error); return ret; } GList * seafile_get_group_repos_by_owner (char *user, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; GList *ret = NULL; if (!user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "user name can not be NULL"); return NULL; } ret = seaf_repo_manager_get_group_repos_by_owner (mgr, user, error); if (!ret) { return NULL; } return g_list_reverse (ret); } char * seafile_get_group_repo_owner (const char *repo_id, GError **error) { SeafRepoManager *mgr = seaf->repo_mgr; GString *result = g_string_new (""); if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *share_from = seaf_repo_manager_get_group_repo_owner (mgr, repo_id, error); if (share_from) { g_string_append_printf (result, "%s", share_from); g_free (share_from); } return g_string_free (result, FALSE); } int seafile_remove_repo_group(int group_id, const char *username, GError **error) { if (group_id <= 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Wrong group id argument"); return -1; } return seaf_repo_manager_remove_group_repos (seaf->repo_mgr, group_id, username, error); } /* Inner public repo RPC */ int seafile_set_inner_pub_repo (const char *repo_id, const char *permission, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad args"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (seaf_repo_manager_set_inner_pub_repo (seaf->repo_mgr, repo_id, permission) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal error"); return -1; } return 0; } int seafile_unset_inner_pub_repo (const char *repo_id, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad args"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (seaf_repo_manager_unset_inner_pub_repo (seaf->repo_mgr, repo_id) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Internal error"); return -1; } return 0; } GList * seafile_list_inner_pub_repos (GError **error) { return seaf_repo_manager_list_inner_pub_repos (seaf->repo_mgr); } gint64 seafile_count_inner_pub_repos (GError **error) { return seaf_repo_manager_count_inner_pub_repos (seaf->repo_mgr); } GList * seafile_list_inner_pub_repos_by_owner (const char *user, GError **error) { if (!user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } return seaf_repo_manager_list_inner_pub_repos_by_owner (seaf->repo_mgr, user); } int seafile_is_inner_pub_repo (const char *repo_id, GError **error) { if (!repo_id) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } return seaf_repo_manager_is_inner_pub_repo (seaf->repo_mgr, repo_id); } gint64 seafile_get_file_size (const char *store_id, int version, const char *file_id, GError **error) { gint64 file_size; if (!store_id || !is_uuid_valid(store_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid store id"); return -1; } if (!file_id || !is_object_id_valid (file_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid file id"); return -1; } file_size = seaf_fs_manager_get_file_size (seaf->fs_mgr, store_id, version, file_id); if (file_size < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "failed to read file size"); return -1; } return file_size; } gint64 seafile_get_dir_size (const char *store_id, int version, const char *dir_id, GError **error) { gint64 dir_size; if (!store_id || !is_uuid_valid (store_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid store id"); return -1; } if (!dir_id || !is_object_id_valid (dir_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid dir id"); return -1; } dir_size = seaf_fs_manager_get_fs_size (seaf->fs_mgr, store_id, version, dir_id); if (dir_size < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Failed to caculate dir size"); return -1; } return dir_size; } int seafile_check_passwd (const char *repo_id, const char *magic, GError **error) { if (!repo_id || strlen(repo_id) != 36 || !magic) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (seaf_passwd_manager_check_passwd (seaf->passwd_mgr, repo_id, magic, error) < 0) { return -1; } return 0; } int seafile_set_passwd (const char *repo_id, const char *user, const char *passwd, GError **error) { if (!repo_id || strlen(repo_id) != 36 || !user || !passwd) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (seaf_passwd_manager_set_passwd (seaf->passwd_mgr, repo_id, user, passwd, error) < 0) { return -1; } return 0; } int seafile_unset_passwd (const char *repo_id, const char *user, GError **error) { if (!repo_id || strlen(repo_id) != 36 || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (seaf_passwd_manager_unset_passwd (seaf->passwd_mgr, repo_id, user, error) < 0) { return -1; } return 0; } int seafile_is_passwd_set (const char *repo_id, const char *user, GError **error) { if (!repo_id || strlen(repo_id) != 36 || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } return seaf_passwd_manager_is_passwd_set (seaf->passwd_mgr, repo_id, user); } GObject * seafile_get_decrypt_key (const char *repo_id, const char *user, GError **error) { SeafileCryptKey *ret; if (!repo_id || strlen(repo_id) != 36 || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } ret = seaf_passwd_manager_get_decrypt_key (seaf->passwd_mgr, repo_id, user); if (!ret) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Password was not set"); return NULL; } return (GObject *)ret; } int seafile_revert_on_server (const char *repo_id, const char *commit_id, const char *user_name, GError **error) { if (!repo_id || strlen(repo_id) != 36 || !commit_id || strlen(commit_id) != 40 || !user_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_object_id_valid (commit_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return -1; } return seaf_repo_manager_revert_on_server (seaf->repo_mgr, repo_id, commit_id, user_name, error); } int seafile_post_file (const char *repo_id, const char *temp_file_path, const char *parent_dir, const char *file_name, const char *user, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; int ret = 0; if (!repo_id || !temp_file_path || !parent_dir || !file_name || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_file_name = normalize_utf8_path (file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } rpath = format_dir_path (norm_parent_dir); if (seaf_repo_manager_post_file (seaf->repo_mgr, repo_id, temp_file_path, rpath, norm_file_name, user, error) < 0) { ret = -1; } out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return ret; } char * seafile_post_file_blocks (const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, gint64 file_size, int replace_existed, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; char *new_id = NULL; if (!repo_id || !parent_dir || !file_name || !blockids_json || ! paths_json || !user || file_size < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_file_name = normalize_utf8_path (file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rpath = format_dir_path (norm_parent_dir); seaf_repo_manager_post_file_blocks (seaf->repo_mgr, repo_id, rpath, norm_file_name, blockids_json, paths_json, user, file_size, replace_existed, &new_id, error); out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return new_id; } char * seafile_post_multi_files (const char *repo_id, const char *parent_dir, const char *filenames_json, const char *paths_json, const char *user, int replace_existed, GError **error) { char *norm_parent_dir = NULL, *rpath = NULL; char *ret_json = NULL; if (!repo_id || !filenames_json || !parent_dir || !paths_json || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rpath = format_dir_path (norm_parent_dir); seaf_repo_manager_post_multi_files (seaf->repo_mgr, repo_id, rpath, filenames_json, paths_json, user, replace_existed, &ret_json, error); out: g_free (norm_parent_dir); g_free (rpath); return ret_json; } char * seafile_put_file (const char *repo_id, const char *temp_file_path, const char *parent_dir, const char *file_name, const char *user, const char *head_id, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; char *new_file_id = NULL; if (!repo_id || !temp_file_path || !parent_dir || !file_name || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_file_name = normalize_utf8_path (file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rpath = format_dir_path (norm_parent_dir); seaf_repo_manager_put_file (seaf->repo_mgr, repo_id, temp_file_path, rpath, norm_file_name, user, head_id, &new_file_id, error); out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return new_file_id; } char * seafile_put_file_blocks (const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, const char *head_id, gint64 file_size, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; char *new_file_id = NULL; if (!repo_id || !parent_dir || !file_name || !blockids_json || ! paths_json || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_file_name = normalize_utf8_path (file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rpath = format_dir_path (norm_parent_dir); seaf_repo_manager_put_file_blocks (seaf->repo_mgr, repo_id, rpath, norm_file_name, blockids_json, paths_json, user, head_id, file_size, &new_file_id, error); out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return new_file_id; } int seafile_post_dir (const char *repo_id, const char *parent_dir, const char *new_dir_name, const char *user, GError **error) { char *norm_parent_dir = NULL, *norm_dir_name = NULL, *rpath = NULL; int ret = 0; if (!repo_id || !parent_dir || !new_dir_name || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_dir_name = normalize_utf8_path (new_dir_name); if (!norm_dir_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } rpath = format_dir_path (norm_parent_dir); if (seaf_repo_manager_post_dir (seaf->repo_mgr, repo_id, rpath, norm_dir_name, user, error) < 0) { ret = -1; } out: g_free (norm_parent_dir); g_free (norm_dir_name); g_free (rpath); return ret; } int seafile_post_empty_file (const char *repo_id, const char *parent_dir, const char *new_file_name, const char *user, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; int ret = 0; if (!repo_id || !parent_dir || !new_file_name || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_file_name = normalize_utf8_path (new_file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } rpath = format_dir_path (norm_parent_dir); if (seaf_repo_manager_post_empty_file (seaf->repo_mgr, repo_id, rpath, norm_file_name, user, error) < 0) { ret = -1; } out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return ret; } int seafile_del_file (const char *repo_id, const char *parent_dir, const char *file_name, const char *user, GError **error) { char *norm_parent_dir = NULL, *norm_file_name = NULL, *rpath = NULL; int ret = 0; if (!repo_id || !parent_dir || !file_name || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_file_name = normalize_utf8_path (file_name); if (!norm_file_name) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } rpath = format_dir_path (norm_parent_dir); if (seaf_repo_manager_del_file (seaf->repo_mgr, repo_id, rpath, norm_file_name, user, error) < 0) { ret = -1; } out: g_free (norm_parent_dir); g_free (norm_file_name); g_free (rpath); return ret; } GObject * seafile_copy_file (const char *src_repo_id, const char *src_dir, const char *src_filename, const char *dst_repo_id, const char *dst_dir, const char *dst_filename, const char *user, int need_progress, int synchronous, GError **error) { char *norm_src_dir = NULL, *norm_src_filename = NULL; char *norm_dst_dir = NULL, *norm_dst_filename = NULL; char *rsrc_dir = NULL, *rdst_dir = NULL; GObject *ret = NULL; if (!src_repo_id || !src_dir || !src_filename || !dst_repo_id || !dst_dir || !dst_filename || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (src_repo_id) || !is_uuid_valid(dst_repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_src_dir = normalize_utf8_path (src_dir); if (!norm_src_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_src_filename = normalize_utf8_path (src_filename); if (!norm_src_filename) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_dst_dir = normalize_utf8_path (dst_dir); if (!norm_dst_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_dst_filename = normalize_utf8_path (dst_filename); if (!norm_dst_filename) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rsrc_dir = format_dir_path (norm_src_dir); rdst_dir = format_dir_path (norm_dst_dir); ret = (GObject *)seaf_repo_manager_copy_file (seaf->repo_mgr, src_repo_id, rsrc_dir, norm_src_filename, dst_repo_id, rdst_dir, norm_dst_filename, user, need_progress, synchronous, error); out: g_free (norm_src_dir); g_free (norm_src_filename); g_free (norm_dst_dir); g_free (norm_dst_filename); g_free (rsrc_dir); g_free (rdst_dir); return ret; } GObject * seafile_move_file (const char *src_repo_id, const char *src_dir, const char *src_filename, const char *dst_repo_id, const char *dst_dir, const char *dst_filename, int replace, const char *user, int need_progress, int synchronous, GError **error) { char *norm_src_dir = NULL, *norm_src_filename = NULL; char *norm_dst_dir = NULL, *norm_dst_filename = NULL; char *rsrc_dir = NULL, *rdst_dir = NULL; GObject *ret = NULL; if (!src_repo_id || !src_dir || !src_filename || !dst_repo_id || !dst_dir || !dst_filename || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (src_repo_id) || !is_uuid_valid(dst_repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } norm_src_dir = normalize_utf8_path (src_dir); if (!norm_src_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_src_filename = normalize_utf8_path (src_filename); if (!norm_src_filename) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_dst_dir = normalize_utf8_path (dst_dir); if (!norm_dst_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } norm_dst_filename = normalize_utf8_path (dst_filename); if (!norm_dst_filename) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); goto out; } rsrc_dir = format_dir_path (norm_src_dir); rdst_dir = format_dir_path (norm_dst_dir); ret = (GObject *)seaf_repo_manager_move_file (seaf->repo_mgr, src_repo_id, rsrc_dir, norm_src_filename, dst_repo_id, rdst_dir, norm_dst_filename, replace, user, need_progress, synchronous, error); out: g_free (norm_src_dir); g_free (norm_src_filename); g_free (norm_dst_dir); g_free (norm_dst_filename); g_free (rsrc_dir); g_free (rdst_dir); return ret; } GObject * seafile_get_copy_task (const char *task_id, GError **error) { return (GObject *)seaf_copy_manager_get_task (seaf->copy_mgr, task_id); } int seafile_cancel_copy_task (const char *task_id, GError **error) { return seaf_copy_manager_cancel_task (seaf->copy_mgr, task_id); } int seafile_rename_file (const char *repo_id, const char *parent_dir, const char *oldname, const char *newname, const char *user, GError **error) { char *norm_parent_dir = NULL, *norm_oldname = NULL, *norm_newname = NULL; char *rpath = NULL; int ret = 0; if (!repo_id || !parent_dir || !oldname || !newname || !user) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } norm_parent_dir = normalize_utf8_path (parent_dir); if (!norm_parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_oldname = normalize_utf8_path (oldname); if (!norm_oldname) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } norm_newname = normalize_utf8_path (newname); if (!norm_newname) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Path is in valid UTF8 encoding"); ret = -1; goto out; } rpath = format_dir_path (norm_parent_dir); if (seaf_repo_manager_rename_file (seaf->repo_mgr, repo_id, rpath, norm_oldname, norm_newname, user, error) < 0) { ret = -1; } out: g_free (norm_parent_dir); g_free (norm_oldname); g_free (norm_newname); g_free (rpath); return ret; } int seafile_is_valid_filename (const char *repo_id, const char *filename, GError **error) { if (!repo_id || !filename) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return -1; } int ret = seaf_repo_manager_is_valid_filename (seaf->repo_mgr, repo_id, filename, error); return ret; } char * seafile_create_repo (const char *repo_name, const char *repo_desc, const char *owner_email, const char *passwd, GError **error) { if (!repo_name || !repo_desc || !owner_email) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } char *repo_id; repo_id = seaf_repo_manager_create_new_repo (seaf->repo_mgr, repo_name, repo_desc, owner_email, passwd, error); return repo_id; } char * seafile_create_enc_repo (const char *repo_id, const char *repo_name, const char *repo_desc, const char *owner_email, const char *magic, const char *random_key, int enc_version, GError **error) { if (!repo_id || !repo_name || !repo_desc || !owner_email) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } char *ret; ret = seaf_repo_manager_create_enc_repo (seaf->repo_mgr, repo_id, repo_name, repo_desc, owner_email, magic, random_key, enc_version, error); return ret; } int seafile_set_user_quota (const char *user, gint64 quota, GError **error) { if (!user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } return seaf_quota_manager_set_user_quota (seaf->quota_mgr, user, quota); } gint64 seafile_get_user_quota (const char *user, GError **error) { if (!user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } return seaf_quota_manager_get_user_quota (seaf->quota_mgr, user); } int seafile_check_quota (const char *repo_id, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } return seaf_quota_manager_check_quota (seaf->quota_mgr, repo_id); } static char * get_obj_id_by_path (const char *repo_id, const char *path, gboolean want_dir, GError **error) { SeafRepo *repo = NULL; SeafCommit *commit = NULL; char *obj_id = NULL; if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Get repo error"); goto out; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!commit) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Get commit error"); goto out; } guint32 mode = 0; obj_id = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, path, &mode, error); out: if (repo) seaf_repo_unref (repo); if (commit) seaf_commit_unref (commit); if (obj_id) { /* check if the mode matches */ if ((want_dir && !S_ISDIR(mode)) || ((!want_dir) && S_ISDIR(mode))) { g_free (obj_id); return NULL; } } return obj_id; } char *seafile_get_file_id_by_path (const char *repo_id, const char *path, GError **error) { char *rpath = format_dir_path (path); char *ret = get_obj_id_by_path (repo_id, rpath, FALSE, error); g_free (rpath); filter_error (error); return ret; } char *seafile_get_dir_id_by_path (const char *repo_id, const char *path, GError **error) { char *rpath = format_dir_path (path); char *ret = get_obj_id_by_path (repo_id, rpath, TRUE, error); g_free (rpath); filter_error (error); return ret; } GObject * seafile_get_dirent_by_path (const char *repo_id, const char *path, GError **error) { if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "invalid repo id"); return NULL; } char *rpath = format_dir_path (path); if (strcmp (rpath, "/") == 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "invalid path"); g_free (rpath); return NULL; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Get repo error"); return NULL; } SeafCommit *commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!commit) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Get commit error"); seaf_repo_unref (repo); return NULL; } SeafDirent *dirent = seaf_fs_manager_get_dirent_by_path (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, rpath, error); g_free (rpath); if (!dirent) { filter_error (error); seaf_repo_unref (repo); seaf_commit_unref (commit); return NULL; } GObject *obj = g_object_new (SEAFILE_TYPE_DIRENT, "obj_id", dirent->id, "obj_name", dirent->name, "mode", dirent->mode, "version", dirent->version, "mtime", dirent->mtime, "size", dirent->size, "modifier", dirent->modifier, NULL); seaf_repo_unref (repo); seaf_commit_unref (commit); seaf_dirent_free (dirent); return obj; } char * seafile_list_file_blocks (const char *repo_id, const char *file_id, int offset, int limit, GError **error) { SeafRepo *repo; Seafile *file; GString *buf = g_string_new (""); int index = 0; if (!repo_id || !is_uuid_valid(repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad repo id"); return NULL; } if (!file_id || !is_object_id_valid(file_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad file id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return NULL; } file = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo->store_id, repo->version, file_id); if (!file) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad file id"); seaf_repo_unref (repo); return NULL; } if (offset < 0) offset = 0; for (index = 0; index < file->n_blocks; index++) { if (index < offset) { continue; } if (limit > 0) { if (index >= offset + limit) break; } g_string_append_printf (buf, "%s\n", file->blk_sha1s[index]); } seafile_unref (file); seaf_repo_unref (repo); return g_string_free (buf, FALSE); } /* * Directories are always before files. Otherwise compare the names. */ static gint comp_dirent_func (gconstpointer a, gconstpointer b) { const SeafDirent *dent_a = a, *dent_b = b; if (S_ISDIR(dent_a->mode) && S_ISREG(dent_b->mode)) return -1; if (S_ISREG(dent_a->mode) && S_ISDIR(dent_b->mode)) return 1; return strcasecmp (dent_a->name, dent_b->name); } GList * seafile_list_dir (const char *repo_id, const char *dir_id, int offset, int limit, GError **error) { SeafRepo *repo; SeafDir *dir; SeafDirent *dent; SeafileDirent *d; GList *res = NULL; GList *p; if (!repo_id || !is_uuid_valid(repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad repo id"); return NULL; } if (!dir_id || !is_object_id_valid (dir_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad dir id"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return NULL; } dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, repo->store_id, repo->version, dir_id); if (!dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_DIR_ID, "Bad dir id"); seaf_repo_unref (repo); return NULL; } dir->entries = g_list_sort (dir->entries, comp_dirent_func); if (offset < 0) { offset = 0; } int index = 0; for (p = dir->entries; p != NULL; p = p->next, index++) { if (index < offset) { continue; } if (limit > 0) { if (index >= offset + limit) break; } dent = p->data; if (!is_object_id_valid (dent->id)) continue; d = g_object_new (SEAFILE_TYPE_DIRENT, "obj_id", dent->id, "obj_name", dent->name, "mode", dent->mode, "version", dent->version, "mtime", dent->mtime, "size", dent->size, "permission", "", NULL); res = g_list_prepend (res, d); } seaf_dir_free (dir); seaf_repo_unref (repo); res = g_list_reverse (res); return res; } GList * seafile_list_file_revisions (const char *repo_id, const char *path, int max_revision, int limit, int show_days, GError **error) { if (!repo_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *rpath = format_dir_path (path); GList *commit_list; commit_list = seaf_repo_manager_list_file_revisions (seaf->repo_mgr, repo_id, NULL, rpath, max_revision, limit, show_days, FALSE, error); g_free (rpath); return commit_list; } GList * seafile_calc_files_last_modified (const char *repo_id, const char *parent_dir, int limit, GError **error) { if (!repo_id || !parent_dir) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *rpath = format_dir_path (parent_dir); GList *ret = seaf_repo_manager_calc_files_last_modified (seaf->repo_mgr, repo_id, rpath, limit, error); g_free (rpath); return ret; } int seafile_revert_file (const char *repo_id, const char *commit_id, const char *path, const char *user, GError **error) { if (!repo_id || !commit_id || !path || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_object_id_valid (commit_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return -1; } char *rpath = format_dir_path (path); int ret = seaf_repo_manager_revert_file (seaf->repo_mgr, repo_id, commit_id, rpath, user, error); g_free (rpath); return ret; } int seafile_revert_dir (const char *repo_id, const char *commit_id, const char *path, const char *user, GError **error) { if (!repo_id || !commit_id || !path || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_object_id_valid (commit_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid commit id"); return -1; } char *rpath = format_dir_path (path); int ret = seaf_repo_manager_revert_dir (seaf->repo_mgr, repo_id, commit_id, rpath, user, error); g_free (rpath); return ret; } char * seafile_check_repo_blocks_missing (const char *repo_id, const char *blockids_json, GError **error) { json_t *array, *value, *ret_json; json_error_t err; size_t index; char *json_data, *ret; SeafRepo *repo = NULL; array = json_loadb (blockids_json, strlen(blockids_json), 0, &err); if (!array) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %.8s.\n", repo_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo not found"); json_decref (array); return NULL; } ret_json = json_array(); size_t n = json_array_size (array); for (index = 0; index < n; index++) { value = json_array_get (array, index); const char *blockid = json_string_value (value); if (!blockid) continue; if (!seaf_block_manager_block_exists(seaf->block_mgr, repo_id, repo->version, blockid)) { json_array_append_new (ret_json, json_string(blockid)); } } json_data = json_dumps (ret_json, 0); ret = g_strdup (json_data); free (json_data); json_decref (ret_json); json_decref (array); return ret; } GList * seafile_get_deleted (const char *repo_id, int show_days, const char *path, const char *scan_stat, int limit, GError **error) { if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad arguments"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *rpath = NULL; if (path) rpath = format_dir_path (path); GList *ret = seaf_repo_manager_get_deleted_entries (seaf->repo_mgr, repo_id, show_days, rpath, scan_stat, limit, error); g_free (rpath); return ret; } char * seafile_generate_repo_token (const char *repo_id, const char *email, GError **error) { char *token; if (!repo_id || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } token = seaf_repo_manager_generate_repo_token (seaf->repo_mgr, repo_id, email, error); return token; } int seafile_delete_repo_token (const char *repo_id, const char *token, const char *user, GError **error) { if (!repo_id || !token || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } return seaf_repo_manager_delete_token (seaf->repo_mgr, repo_id, token, user, error); } GList * seafile_list_repo_tokens (const char *repo_id, GError **error) { GList *ret_list; if (!repo_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } ret_list = seaf_repo_manager_list_repo_tokens (seaf->repo_mgr, repo_id, error); return ret_list; } GList * seafile_list_repo_tokens_by_email (const char *email, GError **error) { GList *ret_list; if (!email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } ret_list = seaf_repo_manager_list_repo_tokens_by_email (seaf->repo_mgr, email, error); return ret_list; } int seafile_delete_repo_tokens_by_peer_id(const char *email, const char *peer_id, GError **error) { if (!email || !peer_id) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } /* check the peer id */ if (strlen(peer_id) != 40) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "invalid peer id"); return -1; } const char *c = peer_id; while (*c) { char v = *c; if ((v >= '0' && v <= '9') || (v >= 'a' && v <= 'z')) { c++; continue; } else { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "invalid peer id"); return -1; } } GList *tokens = NULL; if (seaf_repo_manager_delete_repo_tokens_by_peer_id (seaf->repo_mgr, email, peer_id, &tokens, error) < 0) { g_list_free_full (tokens, (GDestroyNotify)g_free); return -1; } seaf_http_server_invalidate_tokens(seaf->http_server, tokens); g_list_free_full (tokens, (GDestroyNotify)g_free); return 0; } int seafile_delete_repo_tokens_by_email (const char *email, GError **error) { if (!email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } return seaf_repo_manager_delete_repo_tokens_by_email (seaf->repo_mgr, email, error); } char * seafile_check_permission (const char *repo_id, const char *user, GError **error) { if (!repo_id || !user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (strlen(user) == 0) return NULL; return seaf_repo_manager_check_permission (seaf->repo_mgr, repo_id, user, error); } char * seafile_check_permission_by_path (const char *repo_id, const char *path, const char *user, GError **error) { return seafile_check_permission (repo_id, user, error); } GList * seafile_list_dir_with_perm (const char *repo_id, const char *path, const char *dir_id, const char *user, int offset, int limit, GError **error) { if (!repo_id || !is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } if (!dir_id || !is_object_id_valid (dir_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid dir id"); return NULL; } char *rpath = format_dir_path (path); GList *ret = seaf_repo_manager_list_dir_with_perm (seaf->repo_mgr, repo_id, rpath, dir_id, user, offset, limit, error); g_free (rpath); return ret; } int seafile_set_share_permission (const char *repo_id, const char *from_email, const char *to_email, const char *permission, GError **error) { if (!repo_id || !from_email || !to_email || !permission) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id parameter"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } return seaf_share_manager_set_permission (seaf->share_mgr, repo_id, from_email, to_email, permission); } int seafile_set_group_repo_permission (int group_id, const char *repo_id, const char *permission, GError **error) { if (!repo_id || !permission) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return -1; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return -1; } if (!is_permission_valid (permission)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid permission parameter"); return -1; } return seaf_repo_manager_set_group_repo_perm (seaf->repo_mgr, repo_id, group_id, permission, error); } char * seafile_get_file_id_by_commit_and_path(const char *repo_id, const char *commit_id, const char *path, GError **error) { SeafRepo *repo; SeafCommit *commit; char *file_id; if (!repo_id || !is_uuid_valid(repo_id) || !commit_id || !path) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Arguments should not be empty"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Bad repo id"); return NULL; } commit = seaf_commit_manager_get_commit(seaf->commit_mgr, repo_id, repo->version, commit_id); if (!commit) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "bad commit id"); seaf_repo_unref (repo); return NULL; } char *rpath = format_dir_path (path); file_id = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, repo->store_id, repo->version, commit->root_id, rpath, NULL, error); g_free (rpath); filter_error (error); seaf_commit_unref(commit); seaf_repo_unref (repo); return file_id; } /* Virtual repo related */ char * seafile_create_virtual_repo (const char *origin_repo_id, const char *path, const char *repo_name, const char *repo_desc, const char *owner, const char *passwd, GError **error) { if (!origin_repo_id || !path ||!repo_name || !repo_desc || !owner) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (origin_repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo id"); return NULL; } char *repo_id; char *rpath = format_dir_path (path); repo_id = seaf_repo_manager_create_virtual_repo (seaf->repo_mgr, origin_repo_id, rpath, repo_name, repo_desc, owner, passwd, error); g_free (rpath); return repo_id; } GList * seafile_get_virtual_repos_by_owner (const char *owner, GError **error) { GList *repos, *ret = NULL, *ptr; SeafRepo *r, *o; SeafileRepo *repo; char *orig_repo_id; gboolean is_original_owner; if (!owner) { g_set_error (error, 0, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } repos = seaf_repo_manager_get_virtual_repos_by_owner (seaf->repo_mgr, owner, error); for (ptr = repos; ptr != NULL; ptr = ptr->next) { r = ptr->data; orig_repo_id = r->virtual_info->origin_repo_id; o = seaf_repo_manager_get_repo (seaf->repo_mgr, orig_repo_id); if (!o) { seaf_warning ("Failed to get origin repo %.10s.\n", orig_repo_id); seaf_repo_unref (r); continue; } char *orig_owner = seaf_repo_manager_get_repo_owner (seaf->repo_mgr, orig_repo_id); if (g_strcmp0 (orig_owner, owner) == 0) is_original_owner = TRUE; else is_original_owner = FALSE; g_free (orig_owner); char *perm = seaf_repo_manager_check_permission (seaf->repo_mgr, r->id, owner, NULL); repo = (SeafileRepo *)convert_repo (r); if (repo) { g_object_set (repo, "is_original_owner", is_original_owner, "origin_repo_name", o->name, "virtual_perm", perm, NULL); ret = g_list_prepend (ret, repo); } seaf_repo_unref (r); seaf_repo_unref (o); g_free (perm); } g_list_free (repos); return g_list_reverse (ret); } GObject * seafile_get_virtual_repo (const char *origin_repo, const char *path, const char *owner, GError **error) { char *repo_id; GObject *repo_obj; char *rpath = format_dir_path (path); repo_id = seaf_repo_manager_get_virtual_repo_id (seaf->repo_mgr, origin_repo, rpath, owner); g_free (rpath); if (!repo_id) return NULL; repo_obj = seafile_get_repo (repo_id, error); g_free (repo_id); return repo_obj; } /* System default library */ char * seafile_get_system_default_repo_id (GError **error) { return get_system_default_repo_id(seaf); } static int update_valid_since_time (SeafRepo *repo, gint64 new_time) { int ret = 0; gint64 old_time = seaf_repo_manager_get_repo_valid_since (repo->manager, repo->id); if (new_time > 0) { if (new_time > old_time) ret = seaf_repo_manager_set_repo_valid_since (repo->manager, repo->id, new_time); } else if (new_time == 0) { /* Only the head commit is valid after GC if no history is kept. */ SeafCommit *head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (head && (old_time < 0 || head->ctime > (guint64)old_time)) ret = seaf_repo_manager_set_repo_valid_since (repo->manager, repo->id, head->ctime); seaf_commit_unref (head); } return ret; } /* Clean up a repo's history. * It just set valid-since time but not actually delete the data. */ int seafile_clean_up_repo_history (const char *repo_id, int keep_days, GError **error) { SeafRepo *repo; int ret; if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid arguments"); return -1; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Cannot find repo %s.\n", repo_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid arguments"); return -1; } gint64 truncate_time, now; if (keep_days > 0) { now = (gint64)time(NULL); truncate_time = now - keep_days * 24 * 3600; } else truncate_time = 0; ret = update_valid_since_time (repo, truncate_time); if (ret < 0) { seaf_warning ("Failed to update valid since time for repo %.8s.\n", repo->id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Database error"); } seaf_repo_unref (repo); return ret; } GList * seafile_get_shared_users_for_subdir (const char *repo_id, const char *path, const char *from_user, GError **error) { if (!repo_id || !path || !from_user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id"); return NULL; } char *rpath = format_dir_path (path); GList *ret = seaf_repo_manager_get_shared_users_for_subdir (seaf->repo_mgr, repo_id, rpath, from_user, error); g_free (rpath); return ret; } GList * seafile_get_shared_groups_for_subdir (const char *repo_id, const char *path, const char *from_user, GError **error) { if (!repo_id || !path || !from_user) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Argument should not be null"); return NULL; } if (!is_uuid_valid (repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Invalid repo_id"); return NULL; } char *rpath = format_dir_path (path); GList *ret = seaf_repo_manager_get_shared_groups_for_subdir (seaf->repo_mgr, repo_id, rpath, from_user, error); g_free (rpath); return ret; } #endif /* SEAFILE_SERVER */ seafile-6.1.5/common/seaf-db.c000066400000000000000000000571171323477647300161230ustar00rootroot00000000000000 #include "common.h" #include "log.h" #include #include "seaf-db.h" #ifdef WIN32 #include #define sleep(n) Sleep(1000 * (n)) #endif #define MAX_GET_CONNECTION_RETRIES 3 struct SeafDB { int type; ConnectionPool_T pool; }; struct SeafDBRow { ResultSet_T res; }; struct SeafDBTrans { Connection_T conn; }; SeafDB * seaf_db_new_mysql (const char *host, const char *port, const char *user, const char *passwd, const char *db_name, const char *unix_socket, gboolean use_ssl, const char *charset, int max_connections) { SeafDB *db; GString *url; URL_T zdb_url; gboolean has_param = FALSE; db = g_new0 (SeafDB, 1); if (!db) { seaf_warning ("Failed to alloc db structure.\n"); return NULL; } char *passwd_esc = g_uri_escape_string (passwd, NULL, FALSE); url = g_string_new (""); g_string_append_printf (url, "mysql://%s:%s@%s:%s/", user, passwd_esc, host, port); if (db_name) g_string_append (url, db_name); if (unix_socket) { g_string_append_printf (url, "?unix-socket=%s", unix_socket); has_param = TRUE; } if (use_ssl) { g_string_append_printf (url, "%suse-ssl=true", has_param?"&":"?"); has_param = TRUE; } if (charset) { g_string_append_printf (url, "%scharset=%s", has_param?"&":"?", charset); has_param = TRUE; } g_free (passwd_esc); zdb_url = URL_new (url->str); db->pool = ConnectionPool_new (zdb_url); if (!db->pool) { seaf_warning ("Failed to create db connection pool.\n"); g_string_free (url, TRUE); g_free (db); return NULL; } ConnectionPool_setMaxConnections (db->pool, max_connections); ConnectionPool_start (db->pool); db->type = SEAF_DB_TYPE_MYSQL; g_string_free (url, TRUE); return db; } SeafDB * seaf_db_new_pgsql (const char *host, const char *user, const char *passwd, const char *db_name, const char *unix_socket) { SeafDB *db; GString *url; URL_T zdb_url; db = g_new0(SeafDB, 1); if (!db) { seaf_warning ("Failed to alloc db structre.\n"); return NULL; } url = g_string_new (""); g_string_append_printf (url, "postgresql://%s:%s@%s/", user, passwd, host); if (db_name) g_string_append (url, db_name); if (unix_socket) g_string_append_printf (url, "?unix-socket=%s", unix_socket); zdb_url = URL_new (url->str); db->pool = ConnectionPool_new (zdb_url); if (!db->pool) { seaf_warning ("Failed to create db connection pool.\n"); g_string_free(url, TRUE); g_free (db); return NULL; } ConnectionPool_start (db->pool); db->type = SEAF_DB_TYPE_PGSQL; return db; } SeafDB * seaf_db_new_sqlite (const char *db_path, int max_connections) { SeafDB *db; GString *url; URL_T zdb_url; db = g_new0 (SeafDB, 1); if (!db) { seaf_warning ("Failed to alloc db structure.\n"); return NULL; } url = g_string_new (""); g_string_append_printf (url, "sqlite://%s", db_path); zdb_url = URL_new (url->str); db->pool = ConnectionPool_new (zdb_url); if (!db->pool) { seaf_warning ("Failed to create db connection pool.\n"); g_string_free (url, TRUE); g_free (db); return NULL; } ConnectionPool_setMaxConnections (db->pool, max_connections); ConnectionPool_start (db->pool); db->type = SEAF_DB_TYPE_SQLITE; return db; } void seaf_db_free (SeafDB *db) { ConnectionPool_stop (db->pool); ConnectionPool_free (&db->pool); g_free (db); } int seaf_db_type (SeafDB *db) { return db->type; } static Connection_T get_db_connection (SeafDB *db) { Connection_T conn; int n_retries = 0; /* Wait for at most 30 seconds before getting a connection from pool. */ do { conn = ConnectionPool_getConnection (db->pool); if (!conn) g_usleep (100000); } while (!conn && ++n_retries < 300); if (!conn) seaf_warning ("Failed to get database connection.\n"); return conn; } int seaf_db_query (SeafDB *db, const char *sql) { Connection_T conn = get_db_connection (db); if (!conn) return -1; /* Handle zdb "exception"s. */ TRY Connection_execute (conn, "%s", sql); Connection_close (conn); RETURN (0); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; /* Should not be reached. */ return 0; } gboolean seaf_db_check_for_existence (SeafDB *db, const char *sql, gboolean *db_err) { Connection_T conn; ResultSet_T result; gboolean ret = TRUE; *db_err = FALSE; conn = get_db_connection (db); if (!conn) { *db_err = TRUE; return FALSE; } TRY result = Connection_executeQuery (conn, "%s", sql); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); *db_err = TRUE; return FALSE; END_TRY; TRY if (!ResultSet_next (result)) ret = FALSE; CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); *db_err = TRUE; return FALSE; END_TRY; Connection_close (conn); return ret; } int seaf_db_foreach_selected_row (SeafDB *db, const char *sql, SeafDBRowFunc callback, void *data) { Connection_T conn; ResultSet_T result; SeafDBRow seaf_row; int n_rows = 0; conn = get_db_connection (db); if (!conn) return -1; TRY result = Connection_executeQuery (conn, "%s", sql); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; seaf_row.res = result; TRY while (ResultSet_next (result)) { n_rows++; if (!callback (&seaf_row, data)) break; } CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; Connection_close (conn); return n_rows; } const char * seaf_db_row_get_column_text (SeafDBRow *row, guint32 idx) { g_return_val_if_fail (idx < ResultSet_getColumnCount(row->res), NULL); return ResultSet_getString (row->res, idx+1); } int seaf_db_row_get_column_int (SeafDBRow *row, guint32 idx) { g_return_val_if_fail (idx < ResultSet_getColumnCount(row->res), -1); return ResultSet_getInt (row->res, idx+1); } gint64 seaf_db_row_get_column_int64 (SeafDBRow *row, guint32 idx) { g_return_val_if_fail (idx < ResultSet_getColumnCount(row->res), -1); return ResultSet_getLLong (row->res, idx+1); } int seaf_db_get_int (SeafDB *db, const char *sql) { int ret = -1; Connection_T conn; ResultSet_T result; SeafDBRow seaf_row; conn = get_db_connection (db); if (!conn) return -1; TRY result = Connection_executeQuery (conn, "%s", sql); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) ret = seaf_db_row_get_column_int (&seaf_row, 0); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; Connection_close (conn); return ret; } gint64 seaf_db_get_int64 (SeafDB *db, const char *sql) { gint64 ret = -1; Connection_T conn; ResultSet_T result; SeafDBRow seaf_row; conn = get_db_connection (db); if (!conn) return -1; TRY result = Connection_executeQuery (conn, "%s", sql); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) ret = seaf_db_row_get_column_int64 (&seaf_row, 0); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return -1; END_TRY; Connection_close (conn); return ret; } char * seaf_db_get_string (SeafDB *db, const char *sql) { char *ret = NULL; const char *s; Connection_T conn; ResultSet_T result; SeafDBRow seaf_row; conn = get_db_connection (db); if (!conn) return NULL; TRY result = Connection_executeQuery (conn, "%s", sql); CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return NULL; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) { s = seaf_db_row_get_column_text (&seaf_row, 0); ret = g_strdup(s); } CATCH (SQLException) seaf_warning ("Error exec query %s: %s.\n", sql, Exception_frame.message); Connection_close (conn); return NULL; END_TRY; Connection_close (conn); return ret; } char * seaf_db_escape_string (SeafDB *db, const char *from) { const char *p = from; char *to, *q; to = g_malloc0 (2*strlen(from)+1); q = to; while (*p != '\0') { if (*p == '\'' || *p == '\\' || *p == '"') { *q = *p; *(++q) = *p; } else *q = *p; ++p; ++q; } return to; } gboolean pgsql_index_exists (SeafDB *db, const char *index_name) { char sql[256]; gboolean db_err = FALSE; snprintf (sql, sizeof(sql), "SELECT 1 FROM pg_class WHERE relname='%s'", index_name); return seaf_db_check_for_existence (db, sql, &db_err); } /* Prepared Statements */ struct SeafDBStatement { PreparedStatement_T p; Connection_T conn; }; typedef struct SeafDBStatement SeafDBStatement; SeafDBStatement * seaf_db_prepare_statement (SeafDB *db, const char *sql) { PreparedStatement_T p; SeafDBStatement *ret = g_new0 (SeafDBStatement, 1); Connection_T conn = get_db_connection (db); if (!conn) { g_free (ret); return NULL; } TRY p = Connection_prepareStatement (conn, "%s", sql); ret->p = p; ret->conn = conn; RETURN (ret); CATCH (SQLException) seaf_warning ("Error prepare statement %s: %s.\n", sql, Exception_frame.message); g_free (ret); Connection_close (conn); return NULL; END_TRY; /* Should not be reached. */ return NULL; } void seaf_db_statement_free (SeafDBStatement *p) { Connection_close (p->conn); g_free (p); } int seaf_db_statement_set_int (PreparedStatement_T p, int idx, int x) { TRY PreparedStatement_setInt (p, idx, x); RETURN (0); CATCH (SQLException) seaf_warning ("Error set int in prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; return -1; } int seaf_db_statement_set_string (PreparedStatement_T p, int idx, const char *s) { TRY PreparedStatement_setString (p, idx, s); RETURN (0); CATCH (SQLException) seaf_warning ("Error set string in prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; return -1; } int seaf_db_statement_set_int64 (PreparedStatement_T p, int idx, gint64 x) { TRY PreparedStatement_setLLong (p, idx, (long long)x); RETURN (0); CATCH (SQLException) seaf_warning ("Error set int64 in prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; return -1; } static int set_parameters_va (PreparedStatement_T p, int n, va_list args) { int i; const char *type; for (i = 0; i < n; ++i) { type = va_arg (args, const char *); if (strcmp(type, "int") == 0) { int x = va_arg (args, int); if (seaf_db_statement_set_int (p, i+1, x) < 0) return -1; } else if (strcmp (type, "int64") == 0) { gint64 x = va_arg (args, gint64); if (seaf_db_statement_set_int64 (p, i+1, x) < 0) return -1; } else if (strcmp (type, "string") == 0) { const char *s = va_arg (args, const char *); if (seaf_db_statement_set_string (p, i+1, s) < 0) return -1; } else { seaf_warning ("BUG: invalid prep stmt parameter type %s.\n", type); g_return_val_if_reached (-1); } } return 0; } int seaf_db_statement_query (SeafDB *db, const char *sql, int n, ...) { SeafDBStatement *p; volatile int ret = 0; p = seaf_db_prepare_statement (db, sql); if (!p) return -1; va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); va_end (args); return -1; } va_end (args); TRY PreparedStatement_execute (p->p); CATCH (SQLException) seaf_warning ("Error execute prep stmt: %s.\n", Exception_frame.message); ret = -1; END_TRY; seaf_db_statement_free (p); return ret; } gboolean seaf_db_statement_exists (SeafDB *db, const char *sql, gboolean *db_err, int n, ...) { SeafDBStatement *p; ResultSet_T result; volatile gboolean ret = TRUE; *db_err = FALSE; p = seaf_db_prepare_statement (db, sql); if (!p) { *db_err = TRUE; return FALSE; } va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); *db_err = TRUE; va_end (args); return FALSE; } va_end (args); TRY result = PreparedStatement_executeQuery (p->p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); *db_err = TRUE; return FALSE; END_TRY; TRY if (!ResultSet_next (result)) ret = FALSE; CATCH (SQLException) seaf_warning ("Error get next result from prep stmt: %s.\n", Exception_frame.message); *db_err = TRUE; ret = FALSE; END_TRY; seaf_db_statement_free (p); return ret; } int seaf_db_statement_foreach_row (SeafDB *db, const char *sql, SeafDBRowFunc callback, void *data, int n, ...) { SeafDBStatement *p; ResultSet_T result; SeafDBRow seaf_row; volatile int n_rows = 0; p = seaf_db_prepare_statement (db, sql); if (!p) return -1; va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); va_end (args); return -1; } va_end (args); TRY result = PreparedStatement_executeQuery (p->p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_row.res = result; TRY while (ResultSet_next (result)) { n_rows++; if (!callback (&seaf_row, data)) break; } CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_db_statement_free (p); return n_rows; } int seaf_db_statement_get_int (SeafDB *db, const char *sql, int n, ...) { SeafDBStatement *p; volatile int ret = -1; ResultSet_T result; SeafDBRow seaf_row; p = seaf_db_prepare_statement (db, sql); if (!p) return -1; va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); va_end (args); return -1; } va_end (args); TRY result = PreparedStatement_executeQuery (p->p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) ret = seaf_db_row_get_column_int (&seaf_row, 0); CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_db_statement_free (p); return ret; } gint64 seaf_db_statement_get_int64 (SeafDB *db, const char *sql, int n, ...) { SeafDBStatement *p; volatile gint64 ret = -1; ResultSet_T result; SeafDBRow seaf_row; p = seaf_db_prepare_statement (db, sql); if (!p) return -1; va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); va_end (args); return -1; } va_end (args); TRY result = PreparedStatement_executeQuery (p->p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) ret = seaf_db_row_get_column_int64 (&seaf_row, 0); CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return -1; END_TRY; seaf_db_statement_free (p); return ret; } char * seaf_db_statement_get_string (SeafDB *db, const char *sql, int n, ...) { SeafDBStatement *p; char *ret = NULL; const char *s; ResultSet_T result; SeafDBRow seaf_row; p = seaf_db_prepare_statement (db, sql); if (!p) return NULL; va_list args; va_start (args, n); if (set_parameters_va (p->p, n, args) < 0) { seaf_db_statement_free (p); va_end (args); return NULL; } va_end (args); TRY result = PreparedStatement_executeQuery (p->p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return NULL; END_TRY; seaf_row.res = result; TRY if (ResultSet_next (result)) { s = seaf_db_row_get_column_text (&seaf_row, 0); ret = g_strdup(s); } CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); seaf_db_statement_free (p); return NULL; END_TRY; seaf_db_statement_free (p); return ret; } /* Transaction */ SeafDBTrans * seaf_db_begin_transaction (SeafDB *db) { Connection_T conn; SeafDBTrans *trans; trans = g_new0 (SeafDBTrans, 1); if (!trans) return NULL; conn = get_db_connection (db); if (!conn) { g_free (trans); return NULL; } trans->conn = conn; TRY Connection_beginTransaction (trans->conn); CATCH (SQLException) seaf_warning ("Start transaction failed: %s.\n", Exception_frame.message); Connection_close (trans->conn); g_free (trans); return NULL; END_TRY; return trans; } void seaf_db_trans_close (SeafDBTrans *trans) { Connection_close (trans->conn); g_free (trans); } int seaf_db_commit (SeafDBTrans *trans) { Connection_T conn = trans->conn; TRY Connection_commit (conn); CATCH (SQLException) seaf_warning ("Commit failed: %s.\n", Exception_frame.message); return -1; END_TRY; return 0; } int seaf_db_rollback (SeafDBTrans *trans) { Connection_T conn = trans->conn; TRY Connection_rollback (conn); CATCH (SQLException) seaf_warning ("Rollback failed: %s.\n", Exception_frame.message); return -1; END_TRY; return 0; } static PreparedStatement_T trans_prepare_statement (Connection_T conn, const char *sql) { PreparedStatement_T p; TRY p = Connection_prepareStatement (conn, "%s", sql); RETURN (p); CATCH (SQLException) seaf_warning ("Error prepare statement %s: %s.\n", sql, Exception_frame.message); return NULL; END_TRY; /* Should not be reached. */ return NULL; } int seaf_db_trans_query (SeafDBTrans *trans, const char *sql, int n, ...) { PreparedStatement_T p; p = trans_prepare_statement (trans->conn, sql); if (!p) return -1; va_list args; va_start (args, n); if (set_parameters_va (p, n, args) < 0) { va_end (args); return -1; } va_end (args); /* Handle zdb "exception"s. */ TRY PreparedStatement_execute (p); RETURN (0); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; /* Should not be reached. */ return 0; } gboolean seaf_db_trans_check_for_existence (SeafDBTrans *trans, const char *sql, gboolean *db_err, int n, ...) { ResultSet_T result; gboolean ret = TRUE; *db_err = FALSE; PreparedStatement_T p; p = trans_prepare_statement (trans->conn, sql); if (!p) { *db_err = TRUE; return FALSE; } va_list args; va_start (args, n); if (set_parameters_va (p, n, args) < 0) { *db_err = TRUE; va_end (args); return -1; } va_end (args); TRY result = PreparedStatement_executeQuery (p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); *db_err = TRUE; return FALSE; END_TRY; TRY if (!ResultSet_next (result)) ret = FALSE; CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); *db_err = TRUE; return FALSE; END_TRY; return ret; } int seaf_db_trans_foreach_selected_row (SeafDBTrans *trans, const char *sql, SeafDBRowFunc callback, void *data, int n, ...) { ResultSet_T result; SeafDBRow seaf_row; int n_rows = 0; PreparedStatement_T p; p = trans_prepare_statement (trans->conn, sql); if (!p) return FALSE; va_list args; va_start (args, n); if (set_parameters_va (p, n, args) < 0) { va_end (args); return -1; } va_end (args); TRY result = PreparedStatement_executeQuery (p); CATCH (SQLException) seaf_warning ("Error exec prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; seaf_row.res = result; TRY while (ResultSet_next (result)) { n_rows++; if (!callback (&seaf_row, data)) break; } CATCH (SQLException) seaf_warning ("Error get next result for prep stmt: %s.\n", Exception_frame.message); return -1; END_TRY; return n_rows; } seafile-6.1.5/common/seaf-db.h000066400000000000000000000061041323477647300161160ustar00rootroot00000000000000#ifndef SEAF_DB_H #define SEAF_DB_H enum { SEAF_DB_TYPE_SQLITE, SEAF_DB_TYPE_MYSQL, SEAF_DB_TYPE_PGSQL, }; typedef struct SeafDB SeafDB; typedef struct SeafDBRow SeafDBRow; typedef struct SeafDBTrans SeafDBTrans; typedef gboolean (*SeafDBRowFunc) (SeafDBRow *, void *); SeafDB * seaf_db_new_mysql (const char *host, const char *port, const char *user, const char *passwd, const char *db, const char *unix_socket, gboolean use_ssl, const char *charset, int max_connections); SeafDB * seaf_db_new_pgsql (const char *host, const char *user, const char *passwd, const char *db_name, const char *unix_socket); SeafDB * seaf_db_new_sqlite (const char *db_path, int max_connections); void seaf_db_free (SeafDB *db); int seaf_db_type (SeafDB *db); int seaf_db_query (SeafDB *db, const char *sql); gboolean seaf_db_check_for_existence (SeafDB *db, const char *sql, gboolean *db_err); int seaf_db_foreach_selected_row (SeafDB *db, const char *sql, SeafDBRowFunc callback, void *data); const char * seaf_db_row_get_column_text (SeafDBRow *row, guint32 idx); int seaf_db_row_get_column_int (SeafDBRow *row, guint32 idx); gint64 seaf_db_row_get_column_int64 (SeafDBRow *row, guint32 idx); int seaf_db_get_int (SeafDB *db, const char *sql); gint64 seaf_db_get_int64 (SeafDB *db, const char *sql); char * seaf_db_get_string (SeafDB *db, const char *sql); /* Transaction related */ SeafDBTrans * seaf_db_begin_transaction (SeafDB *db); void seaf_db_trans_close (SeafDBTrans *trans); int seaf_db_commit (SeafDBTrans *trans); int seaf_db_rollback (SeafDBTrans *trans); int seaf_db_trans_query (SeafDBTrans *trans, const char *sql, int n, ...); gboolean seaf_db_trans_check_for_existence (SeafDBTrans *trans, const char *sql, gboolean *db_err, int n, ...); int seaf_db_trans_foreach_selected_row (SeafDBTrans *trans, const char *sql, SeafDBRowFunc callback, void *data, int n, ...); /* Escape a string contant by doubling '\" characters. */ char * seaf_db_escape_string (SeafDB *db, const char *from); gboolean pgsql_index_exists (SeafDB *db, const char *index_name); /* Prepared Statements */ int seaf_db_statement_query (SeafDB *db, const char *sql, int n, ...); gboolean seaf_db_statement_exists (SeafDB *db, const char *sql, gboolean *db_err, int n, ...); int seaf_db_statement_foreach_row (SeafDB *db, const char *sql, SeafDBRowFunc callback, void *data, int n, ...); int seaf_db_statement_get_int (SeafDB *db, const char *sql, int n, ...); gint64 seaf_db_statement_get_int64 (SeafDB *db, const char *sql, int n, ...); char * seaf_db_statement_get_string (SeafDB *db, const char *sql, int n, ...); #endif seafile-6.1.5/common/seaf-tree-walk.c000066400000000000000000000067031323477647300174240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "log.h" #include "seafile-session.h" #include "fs-mgr.h" #include "seaf-tree-walk.h" #include "utils.h" #include #include #include #include void fill_tree_descriptor(const char *repo_id, int version, struct tree_desc *desc, const char *root_id) { SeafDir *dir; if (!root_id) { desc->tree = NULL; return; } dir = seaf_fs_manager_get_seafdir_sorted (seaf->fs_mgr, repo_id, version, root_id); if (!dir) { seaf_warning ("Failed to fill tree descriptor with %s.\n", root_id); desc->tree = NULL; } desc->tree = dir; } char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n) { int len = n->pathlen; int pathlen = info->pathlen; path[pathlen + len] = 0; for (;;) { memcpy(path + pathlen, n->path, len); if (!pathlen) break; path[--pathlen] = '/'; n = &info->name; len = n->pathlen; info = info->prev; pathlen -= len; } return path; } int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) { struct name_entry *entries = g_new0 (struct name_entry, n); GList **ptrs = g_new0 (GList *, n); int i; SeafDirent *dent; char *first_name; gboolean done; unsigned long mask = 0, dirmask = 0; int error = 0, ret; for (i = 0; i < n; ++i) { if (t[i].tree) ptrs[i] = t[i].tree->entries; else ptrs[i] = NULL; } while (1) { first_name = NULL; mask = dirmask = 0; memset (entries, 0, sizeof(entries[0])*n); done = TRUE; /* Find the "largest" name, assuming dirents are sorted. */ for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { done = FALSE; dent = ptrs[i]->data; if (!first_name) first_name = dent->name; else if (strcmp(dent->name, first_name) > 0) first_name = dent->name; } } if (done) break; /* * Setup name entries for all names that equals first_name */ for (i = 0; i < n; ++i) { if (ptrs[i] != NULL) { dent = ptrs[i]->data; if (strcmp(first_name, dent->name) == 0) { mask |= 1 << i; /* We treat empty dirs as a file. */ if (S_ISDIR(dent->mode) && memcmp (dent->id, EMPTY_SHA1, 40) != 0) dirmask |= 1 << i; hex_to_rawdata (dent->id, entries[i].sha1, 20); entries[i].path = dent->name; entries[i].pathlen = dent->name_len; entries[i].mode = dent->mode; entries[i].mtime = dent->mtime; if (S_ISREG(dent->mode)) { entries[i].modifier = dent->modifier; } ptrs[i] = ptrs[i]->next; } } } ret = info->fn (n, mask, dirmask, entries, info); if (ret < 0) { error = ret; } } g_free (entries); g_free (ptrs); return error; } seafile-6.1.5/common/seaf-tree-walk.h000066400000000000000000000022171323477647300174250ustar00rootroot00000000000000#ifndef SEAF_TREE_WALK_H #define SEAF_TREE_WALK_H #include "fs-mgr.h" struct name_entry { unsigned char sha1[20]; const char *path; int pathlen; unsigned int mode; char *modifier; guint64 mtime; }; struct tree_desc { SeafDir *tree; }; inline static void tree_desc_free (struct tree_desc *t) { if (t->tree) seaf_dir_free (t->tree); } struct traverse_info; typedef int (*traverse_callback_t)(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *); struct traverse_info { struct traverse_info *prev; struct name_entry name; int pathlen; unsigned long conflicts; traverse_callback_t fn; void *data; int show_all_errors; }; void fill_tree_descriptor(const char *repo_id, int version, struct tree_desc *desc, const char *root_id); int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info); char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n); static inline int traverse_path_len(const struct traverse_info *info, const struct name_entry *n) { return info->pathlen + n->pathlen; } #endif seafile-6.1.5/common/seaf-utils.c000066400000000000000000000124641323477647300166720ustar00rootroot00000000000000#include "common.h" #include "log.h" #include "seafile-session.h" #include "seaf-utils.h" #include "seaf-db.h" #include #include char * seafile_session_get_tmp_file_path (SeafileSession *session, const char *basename, char path[]) { int path_len; path_len = strlen (session->tmp_file_dir); memcpy (path, session->tmp_file_dir, path_len + 1); path[path_len] = '/'; strcpy (path + path_len + 1, basename); return path; } #ifdef SEAFILE_SERVER #define SQLITE_DB_NAME "seafile.db" #define DEFAULT_MAX_CONNECTIONS 100 static int sqlite_db_start (SeafileSession *session) { char *db_path; int max_connections = 0; max_connections = g_key_file_get_integer (session->config, "database", "max_connections", NULL); if (max_connections <= 0) max_connections = DEFAULT_MAX_CONNECTIONS; db_path = g_build_filename (session->seaf_dir, SQLITE_DB_NAME, NULL); session->db = seaf_db_new_sqlite (db_path, max_connections); if (!session->db) { seaf_warning ("Failed to start sqlite db.\n"); return -1; } return 0; } #define MYSQL_DEFAULT_PORT "3306" static int mysql_db_start (SeafileSession *session) { char *host, *port, *user, *passwd, *db, *unix_socket, *charset; gboolean use_ssl = FALSE; int max_connections = 0; GError *error = NULL; host = g_key_file_get_string (session->config, "database", "host", &error); if (!host) { seaf_warning ("DB host not set in config.\n"); return -1; } port = g_key_file_get_string (session->config, "database", "port", &error); if (!port) { port = g_strdup(MYSQL_DEFAULT_PORT); } user = g_key_file_get_string (session->config, "database", "user", &error); if (!user) { seaf_warning ("DB user not set in config.\n"); return -1; } passwd = g_key_file_get_string (session->config, "database", "password", &error); if (!passwd) { seaf_warning ("DB passwd not set in config.\n"); return -1; } db = g_key_file_get_string (session->config, "database", "db_name", &error); if (!db) { seaf_warning ("DB name not set in config.\n"); return -1; } unix_socket = g_key_file_get_string (session->config, "database", "unix_socket", NULL); use_ssl = g_key_file_get_boolean (session->config, "database", "use_ssl", NULL); charset = g_key_file_get_string (session->config, "database", "connection_charset", NULL); max_connections = g_key_file_get_integer (session->config, "database", "max_connections", NULL); if (max_connections <= 0) max_connections = DEFAULT_MAX_CONNECTIONS; session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, charset, max_connections); if (!session->db) { seaf_warning ("Failed to start mysql db.\n"); return -1; } g_free (host); g_free (port); g_free (user); g_free (passwd); g_free (db); g_free (unix_socket); g_free (charset); if (error) g_clear_error (&error); return 0; } static int pgsql_db_start (SeafileSession *session) { char *host, *user, *passwd, *db, *unix_socket; GError *error = NULL; host = g_key_file_get_string (session->config, "database", "host", &error); if (!host) { seaf_warning ("DB host not set in config.\n"); return -1; } user = g_key_file_get_string (session->config, "database", "user", &error); if (!user) { seaf_warning ("DB user not set in config.\n"); return -1; } passwd = g_key_file_get_string (session->config, "database", "password", &error); if (!passwd) { seaf_warning ("DB passwd not set in config.\n"); return -1; } db = g_key_file_get_string (session->config, "database", "db_name", &error); if (!db) { seaf_warning ("DB name not set in config.\n"); return -1; } unix_socket = g_key_file_get_string (session->config, "database", "unix_socket", &error); session->db = seaf_db_new_pgsql (host, user, passwd, db, unix_socket); if (!session->db) { seaf_warning ("Failed to start pgsql db.\n"); return -1; } g_free (host); g_free (user); g_free (passwd); g_free (db); g_free (unix_socket); return 0; } int load_database_config (SeafileSession *session) { char *type; GError *error = NULL; int ret = 0; type = g_key_file_get_string (session->config, "database", "type", &error); /* Default to use sqlite if not set. */ if (!type || strcasecmp (type, "sqlite") == 0) { ret = sqlite_db_start (session); } else if (strcasecmp (type, "mysql") == 0) { ret = mysql_db_start (session); } else if (strcasecmp (type, "pgsql") == 0) { ret = pgsql_db_start (session); } else { seaf_warning ("Unsupported db type %s.\n", type); ret = -1; } g_free (type); return ret; } #endif seafile-6.1.5/common/seaf-utils.h000066400000000000000000000005341323477647300166720ustar00rootroot00000000000000#ifndef SEAF_UTILS_H #define SEAF_UTILS_H struct _SeafileSession; char * seafile_session_get_tmp_file_path (struct _SeafileSession *session, const char *basename, char path[]); #ifdef SEAFILE_SERVER int load_database_config (struct _SeafileSession *session); #endif #endif seafile-6.1.5/common/seafile-crypt.c000066400000000000000000000411111323477647300173540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include "seafile-crypt.h" #ifdef USE_GPL_CRYPTO #include #include #include #else #include #include #include #endif #include "utils.h" #include "log.h" /* The EVP_EncryptXXX and EVP_DecryptXXX series of functions have a weird choice of returned value. */ #define ENC_SUCCESS 1 #define ENC_FAILURE 0 #define DEC_SUCCESS 1 #define DEC_FAILURE 0 #define KEYGEN_ITERATION 1 << 19 #define KEYGEN_ITERATION2 1000 /* Should generate random salt for each repo. */ static unsigned char salt[8] = { 0xda, 0x90, 0x45, 0xc3, 0x06, 0xc7, 0xcc, 0x26 }; SeafileCrypt * seafile_crypt_new (int version, unsigned char *key, unsigned char *iv) { SeafileCrypt *crypt = g_new0 (SeafileCrypt, 1); crypt->version = version; if (version == 1) memcpy (crypt->key, key, 16); else memcpy (crypt->key, key, 32); memcpy (crypt->iv, iv, 16); return crypt; } int seafile_derive_key (const char *data_in, int in_len, int version, unsigned char *key, unsigned char *iv) { #ifdef USE_GPL_CRYPTO if (version != 2) { seaf_warning ("Encrypted library version %d is not supported.\n", version); return -1; } pbkdf2_hmac_sha256 (in_len, (const guchar *)data_in, KEYGEN_ITERATION2, sizeof(salt), salt, 32, key); pbkdf2_hmac_sha256 (32, (const guchar *)key, 10, sizeof(salt), salt, 16, iv); return 0; #else if (version == 2) { PKCS5_PBKDF2_HMAC (data_in, in_len, salt, sizeof(salt), KEYGEN_ITERATION2, EVP_sha256(), 32, key); PKCS5_PBKDF2_HMAC ((char *)key, 32, salt, sizeof(salt), 10, EVP_sha256(), 16, iv); return 0; } else if (version == 1) { EVP_BytesToKey (EVP_aes_128_cbc(), /* cipher mode */ EVP_sha1(), /* message digest */ salt, /* salt */ (unsigned char*)data_in, in_len, KEYGEN_ITERATION, /* iteration times */ key, /* the derived key */ iv); /* IV, initial vector */ return 0; } else { EVP_BytesToKey (EVP_aes_128_ecb(), /* cipher mode */ EVP_sha1(), /* message digest */ NULL, /* salt */ (unsigned char*)data_in, in_len, 3, /* iteration times */ key, /* the derived key */ iv); /* IV, initial vector */ return 0; } #endif } int seafile_generate_random_key (const char *passwd, char *random_key) { SeafileCrypt *crypt; unsigned char secret_key[32], *rand_key; int outlen; unsigned char key[32], iv[16]; #ifdef USE_GPL_CRYPTO if (gnutls_rnd (GNUTLS_RND_RANDOM, secret_key, sizeof(secret_key)) < 0) { seaf_warning ("Failed to generate secret key for repo encryption.\n"); return -1; } #else if (RAND_bytes (secret_key, sizeof(secret_key)) != 1) { seaf_warning ("Failed to generate secret key for repo encryption " "with RAND_bytes(), use RAND_pseudo_bytes().\n"); RAND_pseudo_bytes (secret_key, sizeof(secret_key)); } #endif seafile_derive_key (passwd, strlen(passwd), 2, key, iv); crypt = seafile_crypt_new (2, key, iv); seafile_encrypt ((char **)&rand_key, &outlen, (char *)secret_key, sizeof(secret_key), crypt); rawdata_to_hex (rand_key, random_key, 48); g_free (crypt); g_free (rand_key); return 0; } void seafile_generate_magic (int version, const char *repo_id, const char *passwd, char *magic) { GString *buf = g_string_new (NULL); unsigned char key[32], iv[16]; /* Compute a "magic" string from repo_id and passwd. * This is used to verify the password given by user before decrypting * data. */ g_string_append_printf (buf, "%s%s", repo_id, passwd); seafile_derive_key (buf->str, buf->len, version, key, iv); g_string_free (buf, TRUE); rawdata_to_hex (key, magic, 32); } int seafile_verify_repo_passwd (const char *repo_id, const char *passwd, const char *magic, int version) { GString *buf = g_string_new (NULL); unsigned char key[32], iv[16]; char hex[65]; if (version != 1 && version != 2) { seaf_warning ("Unsupported enc_version %d.\n", version); return -1; } /* Recompute the magic and compare it with the one comes with the repo. */ g_string_append_printf (buf, "%s%s", repo_id, passwd); seafile_derive_key (buf->str, buf->len, version, key, iv); g_string_free (buf, TRUE); if (version == 2) rawdata_to_hex (key, hex, 32); else rawdata_to_hex (key, hex, 16); if (g_strcmp0 (hex, magic) == 0) return 0; else return -1; } int seafile_decrypt_repo_enc_key (int enc_version, const char *passwd, const char *random_key, unsigned char *key_out, unsigned char *iv_out) { unsigned char key[32], iv[16]; seafile_derive_key (passwd, strlen(passwd), enc_version, key, iv); if (enc_version == 1) { memcpy (key_out, key, 16); memcpy (iv_out, iv, 16); return 0; } else if (enc_version == 2) { unsigned char enc_random_key[48], *dec_random_key; int outlen; SeafileCrypt *crypt; if (random_key == NULL || random_key[0] == 0) { seaf_warning ("Empty random key.\n"); return -1; } hex_to_rawdata (random_key, enc_random_key, 48); crypt = seafile_crypt_new (enc_version, key, iv); if (seafile_decrypt ((char **)&dec_random_key, &outlen, (char *)enc_random_key, 48, crypt) < 0) { seaf_warning ("Failed to decrypt random key.\n"); g_free (crypt); return -1; } g_free (crypt); seafile_derive_key ((char *)dec_random_key, 32, enc_version, key, iv); memcpy (key_out, key, 32); memcpy (iv_out, iv, 16); g_free (dec_random_key); return 0; } return -1; } int seafile_update_random_key (const char *old_passwd, const char *old_random_key, const char *new_passwd, char *new_random_key) { unsigned char key[32], iv[16]; unsigned char random_key_raw[48], *secret_key, *new_random_key_raw; int secret_key_len, random_key_len; SeafileCrypt *crypt; /* First, use old_passwd to decrypt secret key from old_random_key. */ seafile_derive_key (old_passwd, strlen(old_passwd), 2, key, iv); hex_to_rawdata (old_random_key, random_key_raw, 48); crypt = seafile_crypt_new (2, key, iv); if (seafile_decrypt ((char **)&secret_key, &secret_key_len, (char *)random_key_raw, 48, crypt) < 0) { seaf_warning ("Failed to decrypt random key.\n"); g_free (crypt); return -1; } g_free (crypt); /* Second, use new_passwd to encrypt secret key. */ seafile_derive_key (new_passwd, strlen(new_passwd), 2, key, iv); crypt = seafile_crypt_new (2, key, iv); seafile_encrypt ((char **)&new_random_key_raw, &random_key_len, (char *)secret_key, secret_key_len, crypt); rawdata_to_hex (new_random_key_raw, new_random_key, 48); g_free (secret_key); g_free (new_random_key_raw); g_free (crypt); return 0; } #ifdef USE_GPL_CRYPTO int seafile_encrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt) { char *buf = NULL, *enc_buf = NULL; int buf_size, remain; guint8 padding; gnutls_cipher_hd_t handle; gnutls_datum_t key, iv; int rc, ret = 0; buf_size = BLK_SIZE * ((in_len / BLK_SIZE) + 1); remain = buf_size - in_len; buf = g_new (char, buf_size); memcpy (buf, data_in, in_len); padding = (guint8)remain; memset (buf + in_len, padding, remain); key.data = crypt->key; key.size = sizeof(crypt->key); iv.data = crypt->iv; iv.size = sizeof(crypt->iv); rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv); if (rc < 0) { seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc)); ret = -1; goto out; } enc_buf = g_new (char, buf_size); rc = gnutls_cipher_encrypt2 (handle, buf, buf_size, enc_buf, buf_size); if (rc < 0) { seaf_warning ("Failed to encrypt: %s\n", gnutls_strerror(rc)); ret = -1; gnutls_cipher_deinit (handle); goto out; } gnutls_cipher_deinit (handle); out: g_free (buf); if (ret < 0) { g_free (enc_buf); *data_out = NULL; *out_len = -1; } else { *data_out = enc_buf; *out_len = buf_size; } return ret; } int seafile_decrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt) { char *dec_buf = NULL; gnutls_cipher_hd_t handle; gnutls_datum_t key, iv; int rc, ret = 0; guint8 padding; int remain; if (in_len <= 0 || in_len % BLK_SIZE != 0) { seaf_warning ("Invalid encrypted buffer size.\n"); return -1; } key.data = crypt->key; key.size = sizeof(crypt->key); iv.data = crypt->iv; iv.size = sizeof(crypt->iv); rc = gnutls_cipher_init (&handle, GNUTLS_CIPHER_AES_256_CBC, &key, &iv); if (rc < 0) { seaf_warning ("Failed to init cipher: %s\n", gnutls_strerror(rc)); ret = -1; goto out; } dec_buf = g_new (char, in_len); rc = gnutls_cipher_decrypt2 (handle, data_in, in_len, dec_buf, in_len); if (rc < 0) { seaf_warning ("Failed to decrypt data: %s\n", gnutls_strerror(rc)); ret = -1; gnutls_cipher_deinit (handle); goto out; } padding = dec_buf[in_len - 1]; remain = padding; *out_len = (in_len - remain); *data_out = dec_buf; gnutls_cipher_deinit (handle); out: if (ret < 0) { g_free (dec_buf); *data_out = NULL; *out_len = -1; } return ret; } #else int seafile_encrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt) { *data_out = NULL; *out_len = -1; /* check validation */ if ( data_in == NULL || in_len <= 0 || crypt == NULL) { seaf_warning ("Invalid params.\n"); return -1; } EVP_CIPHER_CTX *ctx; int ret; int blks; /* Prepare CTX for encryption. */ ctx = EVP_CIPHER_CTX_new (); if (crypt->version == 2) ret = EVP_EncryptInit_ex (ctx, EVP_aes_256_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ else if (crypt->version == 1) ret = EVP_EncryptInit_ex (ctx, EVP_aes_128_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ else ret = EVP_EncryptInit_ex (ctx, EVP_aes_128_ecb(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ if (ret == ENC_FAILURE) { EVP_CIPHER_CTX_free (ctx); return -1; } /* Allocating output buffer. */ /* For EVP symmetric encryption, padding is always used __even if__ data size is a multiple of block size, in which case the padding length is the block size. so we have the following: */ blks = (in_len / BLK_SIZE) + 1; *data_out = (char *)g_malloc (blks * BLK_SIZE); if (*data_out == NULL) { seaf_warning ("failed to allocate the output buffer.\n"); goto enc_error; } int update_len, final_len; /* Do the encryption. */ ret = EVP_EncryptUpdate (ctx, (unsigned char*)*data_out, &update_len, (unsigned char*)data_in, in_len); if (ret == ENC_FAILURE) goto enc_error; /* Finish the possible partial block. */ ret = EVP_EncryptFinal_ex (ctx, (unsigned char*)*data_out + update_len, &final_len); *out_len = update_len + final_len; /* out_len should be equal to the allocated buffer size. */ if (ret == ENC_FAILURE || *out_len != (blks * BLK_SIZE)) goto enc_error; EVP_CIPHER_CTX_free (ctx); return 0; enc_error: EVP_CIPHER_CTX_free (ctx); *out_len = -1; if (*data_out != NULL) g_free (*data_out); *data_out = NULL; return -1; } int seafile_decrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt) { *data_out = NULL; *out_len = -1; /* Check validation. Because padding is always used, in_len must * be a multiple of BLK_SIZE */ if ( data_in == NULL || in_len <= 0 || in_len % BLK_SIZE != 0 || crypt == NULL) { seaf_warning ("Invalid param(s).\n"); return -1; } EVP_CIPHER_CTX *ctx; int ret; /* Prepare CTX for decryption. */ ctx = EVP_CIPHER_CTX_new (); if (crypt->version == 2) ret = EVP_DecryptInit_ex (ctx, EVP_aes_256_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ else if (crypt->version == 1) ret = EVP_DecryptInit_ex (ctx, EVP_aes_128_cbc(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ else ret = EVP_DecryptInit_ex (ctx, EVP_aes_128_ecb(), /* cipher mode */ NULL, /* engine, NULL for default */ crypt->key, /* derived key */ crypt->iv); /* initial vector */ if (ret == DEC_FAILURE) { EVP_CIPHER_CTX_free (ctx); return -1; } /* Allocating output buffer. */ *data_out = (char *)g_malloc (in_len); if (*data_out == NULL) { seaf_warning ("failed to allocate the output buffer.\n"); goto dec_error; } int update_len, final_len; /* Do the decryption. */ ret = EVP_DecryptUpdate (ctx, (unsigned char*)*data_out, &update_len, (unsigned char*)data_in, in_len); if (ret == DEC_FAILURE) goto dec_error; /* Finish the possible partial block. */ ret = EVP_DecryptFinal_ex (ctx, (unsigned char*)*data_out + update_len, &final_len); *out_len = update_len + final_len; /* out_len should be smaller than in_len. */ if (ret == DEC_FAILURE || *out_len > in_len) goto dec_error; EVP_CIPHER_CTX_free (ctx); return 0; dec_error: EVP_CIPHER_CTX_free (ctx); *out_len = -1; if (*data_out != NULL) g_free (*data_out); *data_out = NULL; return -1; } #endif /* USE_GPL_CRYPTO */ seafile-6.1.5/common/seafile-crypt.h000066400000000000000000000047711323477647300173740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef _SEAFILE_CRYPT_H #define _SEAFILE_CRYPT_H /* Block size, in bytes. For AES it can only be 16 bytes. */ #define BLK_SIZE 16 #define ENCRYPT_BLK_SIZE BLK_SIZE struct SeafileCrypt { int version; unsigned char key[32]; /* set when enc_version >= 1 */ unsigned char iv[16]; }; typedef struct SeafileCrypt SeafileCrypt; SeafileCrypt * seafile_crypt_new (int version, unsigned char *key, unsigned char *iv); /* Derive key and iv used by AES encryption from @data_in. key and iv is 16 bytes for version 1, and 32 bytes for version 2. @data_out: pointer to the output of the encrpyted/decrypted data, whose content must be freed by g_free when not used. @out_len: pointer to length of output, in bytes @data_in: address of input buffer @in_len: length of data to be encrpyted/decrypted, in bytes @crypt: container of crypto info. RETURN VALUES: On success, 0 is returned, and the encrpyted/decrypted data is in *data_out, with out_len set to its length. On failure, -1 is returned and *data_out is set to NULL, with out_len set to -1; */ int seafile_derive_key (const char *data_in, int in_len, int version, unsigned char *key, unsigned char *iv); /* * Generate the real key used to encrypt data. * The key 32 bytes long and encrpted with @passwd. */ int seafile_generate_random_key (const char *passwd, char *random_key); void seafile_generate_magic (int version, const char *repo_id, const char *passwd, char *magic); int seafile_verify_repo_passwd (const char *repo_id, const char *passwd, const char *magic, int version); int seafile_decrypt_repo_enc_key (int enc_version, const char *passwd, const char *random_key, unsigned char *key_out, unsigned char *iv_out); int seafile_update_random_key (const char *old_passwd, const char *old_random_key, const char *new_passwd, char *new_random_key); int seafile_encrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt); int seafile_decrypt (char **data_out, int *out_len, const char *data_in, const int in_len, SeafileCrypt *crypt); #endif /* _SEAFILE_CRYPT_H */ seafile-6.1.5/common/sync-repo-common.h000066400000000000000000000011061323477647300200170ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SYNC_REPO_COMMON #define SYNC_REPO_COMMON #define SC_COMMIT_ID "300" #define SS_COMMIT_ID "Commit ID" #define SC_NO_REPO "301" #define SS_NO_REPO "No such repo" #define SC_NO_BRANCH "302" #define SS_NO_BRANCH "No such branch" #define SC_NO_DSYNC "303" #define SS_NO_DSYNC "Not double sync" #define SC_REPO_CORRUPT "304" #define SS_REPO_CORRUPT "Repo corrupted" #define SC_SERVER_ERROR "401" #define SS_SERVER_ERROR "Internal server error" #endif seafile-6.1.5/common/unpack-trees.c000066400000000000000000001155511323477647300172200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "seaf-tree-walk.h" /* #include "cache-tree.h" */ #include "unpack-trees.h" /* #include "vc-utils.h" */ static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce, unsigned int set, unsigned int clear) { unsigned int size = ce_size(ce); struct cache_entry *new = malloc(size); clear |= CE_HASHED | CE_UNHASHED; if (set & CE_REMOVE) set |= CE_WT_REMOVE; memcpy(new, ce, size); new->next = NULL; new->ce_flags = (new->ce_flags & ~clear) | set; new->modifier = g_strdup(ce->modifier); add_index_entry(&o->result, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); } /* * add error messages on path * corresponding to the type with the message * indicating if it should be display in porcelain or not */ static int add_rejected_path(struct unpack_trees_options *o, enum unpack_trees_error_types e, const char *path) { o->unpack_rejects[e] = g_list_prepend(o->unpack_rejects[e], g_strdup(path)); return -1; } #if 0 /* * Unlink the last component and schedule the leading directories for * removal, such that empty directories get removed. */ static void unlink_entry(struct cache_entry *ce) { if (!check_leading_path(ce->name, ce_namelen(ce))) return; if (remove_or_warn(ce->ce_mode, ce->name)) return; schedule_dir_for_removal(ce->name, ce_namelen(ce)); } static struct checkout state; static int check_updates(struct unpack_trees_options *o) { unsigned cnt = 0, total = 0; struct progress *progress = NULL; struct index_state *index = &o->result; int i; int errs = 0; if (o->update && o->verbose_update) { for (total = cnt = 0; cnt < index->cache_nr; cnt++) { struct cache_entry *ce = index->cache[cnt]; if (ce->ce_flags & (CE_UPDATE | CE_WT_REMOVE)) total++; } progress = start_progress_delay("Checking out files", total, 50, 1); cnt = 0; } if (o->update) git_attr_set_direction(GIT_ATTR_CHECKOUT, &o->result); for (i = 0; i < index->cache_nr; i++) { struct cache_entry *ce = index->cache[i]; if (ce->ce_flags & CE_WT_REMOVE) { display_progress(progress, ++cnt); if (o->update) unlink_entry(ce); continue; } } remove_marked_cache_entries(&o->result); remove_scheduled_dirs(); for (i = 0; i < index->cache_nr; i++) { struct cache_entry *ce = index->cache[i]; if (ce->ce_flags & CE_UPDATE) { display_progress(progress, ++cnt); ce->ce_flags &= ~CE_UPDATE; if (o->update) { errs |= checkout_entry(ce, &state, NULL); } } } stop_progress(&progress); if (o->update) git_attr_set_direction(GIT_ATTR_CHECKIN, NULL); return errs != 0; } #endif static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o) { int ret = o->fn(src, o); if (ret > 0) ret = 0; return ret; } static void mark_ce_used(struct cache_entry *ce, struct unpack_trees_options *o) { ce->ce_flags |= CE_UNPACKED; if (o->cache_bottom < o->src_index->cache_nr && o->src_index->cache[o->cache_bottom] == ce) { int bottom = o->cache_bottom; while (bottom < o->src_index->cache_nr && o->src_index->cache[bottom]->ce_flags & CE_UNPACKED) bottom++; o->cache_bottom = bottom; } } static int locate_in_src_index(struct cache_entry *ce, struct unpack_trees_options *o) { struct index_state *index = o->src_index; int len = ce_namelen(ce); int pos = index_name_pos(index, ce->name, len); if (pos < 0) pos = -1 - pos; return pos; } /* * We call unpack_index_entry() with an unmerged cache entry * only in diff-index, and it wants a single callback. Skip * the other unmerged entry with the same name. */ static void mark_ce_used_same_name(struct cache_entry *ce, struct unpack_trees_options *o) { struct index_state *index = o->src_index; int len = ce_namelen(ce); int pos; for (pos = locate_in_src_index(ce, o); pos < index->cache_nr; pos++) { struct cache_entry *next = index->cache[pos]; if (len != ce_namelen(next) || memcmp(ce->name, next->name, len)) break; mark_ce_used(next, o); } } static struct cache_entry *next_cache_entry(struct unpack_trees_options *o) { const struct index_state *index = o->src_index; int pos = o->cache_bottom; while (pos < index->cache_nr) { struct cache_entry *ce = index->cache[pos]; if (!(ce->ce_flags & CE_UNPACKED)) return ce; pos++; } return NULL; } static void add_same_unmerged(struct cache_entry *ce, struct unpack_trees_options *o) { struct index_state *index = o->src_index; int len = ce_namelen(ce); int pos = index_name_pos(index, ce->name, len); if (0 <= pos) { g_error("programming error in a caller of mark_ce_used_same_name"); } for (pos = -pos - 1; pos < index->cache_nr; pos++) { struct cache_entry *next = index->cache[pos]; if (len != ce_namelen(next) || memcmp(ce->name, next->name, len)) break; add_entry(o, next, 0, 0); mark_ce_used(next, o); } } static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_options *o) { struct cache_entry *src[5] = { NULL }; int ret; src[0] = ce; mark_ce_used(ce, o); if (ce_stage(ce)) { if (o->skip_unmerged) { add_entry(o, ce, 0, 0); return 0; } } ret = call_unpack_fn(src, o); if (ce_stage(ce)) mark_ce_used_same_name(ce, o); return ret; } static int find_cache_pos(struct traverse_info *, const struct name_entry *); static void restore_cache_bottom(struct traverse_info *info, int bottom) { struct unpack_trees_options *o = info->data; if (o->diff_index_cached) return; o->cache_bottom = bottom; } static int switch_cache_bottom(struct traverse_info *info) { struct unpack_trees_options *o = info->data; int ret, pos; if (o->diff_index_cached) return 0; ret = o->cache_bottom; pos = find_cache_pos(info->prev, &info->name); if (pos < -1) o->cache_bottom = -2 - pos; else if (pos < 0) o->cache_bottom = o->src_index->cache_nr; return ret; } static int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info) { int i, ret, bottom; struct tree_desc t[MAX_UNPACK_TREES]; struct traverse_info newinfo; struct name_entry *p; struct unpack_trees_options *o = info->data; p = names; while (!p->mode) p++; newinfo = *info; newinfo.prev = info; newinfo.name = *p; newinfo.pathlen += p->pathlen + 1; newinfo.conflicts |= df_conflicts; for (i = 0; i < n; i++, dirmask >>= 1) { char root_id[41]; if (dirmask & 1) { rawdata_to_hex(names[i].sha1, root_id, 20); fill_tree_descriptor(o->repo_id, o->version, t+i, root_id); } else { fill_tree_descriptor(o->repo_id, o->version, t+i, NULL); } } bottom = switch_cache_bottom(&newinfo); ret = traverse_trees(n, t, &newinfo); restore_cache_bottom(&newinfo, bottom); for (i = 0; i < n; ++i) { tree_desc_free (&t[i]); } return ret; } /* * Compare the traverse-path to the cache entry without actually * having to generate the textual representation of the traverse * path. * * NOTE! This *only* compares up to the size of the traverse path * itself - the caller needs to do the final check for the cache * entry having more data at the end! */ static int do_compare_entry(const struct cache_entry *ce, const struct traverse_info *info, const struct name_entry *n) { int len, pathlen, ce_len; const char *ce_name; if (info->prev) { int cmp = do_compare_entry(ce, info->prev, &info->name); if (cmp) return cmp; } pathlen = info->pathlen; ce_len = ce_namelen(ce); /* If ce_len < pathlen then we must have previously hit "name == directory" entry */ if (ce_len < pathlen) return -1; ce_len -= pathlen; ce_name = ce->name + pathlen; len = n->pathlen; return df_name_compare(ce_name, ce_len, S_IFREG, n->path, len, n->mode); } static int compare_entry(const struct cache_entry *ce, const struct traverse_info *info, const struct name_entry *n) { int cmp = do_compare_entry(ce, info, n); if (cmp) return cmp; /* * Even if the beginning compared identically, the ce should * compare as bigger than a directory leading up to it! */ return ce_namelen(ce) > traverse_path_len(info, n); } static int ce_in_traverse_path(const struct cache_entry *ce, const struct traverse_info *info) { if (!info->prev) return 1; if (do_compare_entry(ce, info->prev, &info->name)) return 0; /* * If ce (blob) is the same name as the path (which is a tree * we will be descending into), it won't be inside it. */ return (info->pathlen < ce_namelen(ce)); } static struct cache_entry *create_ce_entry(const struct traverse_info *info, const struct name_entry *n, int stage) { int len = traverse_path_len(info, n); struct cache_entry *ce = calloc(1, cache_entry_size(len)); ce->ce_mode = create_ce_mode(n->mode); ce->ce_flags = create_ce_flags(len, stage); hashcpy(ce->sha1, n->sha1); make_traverse_path(ce->name, info, n); ce->modifier = g_strdup(n->modifier); ce->ce_mtime.sec = n->mtime; return ce; } static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmask, struct cache_entry **src, const struct name_entry *names, const struct traverse_info *info) { int i; struct unpack_trees_options *o = info->data; unsigned long conflicts; /* Do we have *only* directories? Nothing to do */ if (mask == dirmask && !src[0]) return 0; conflicts = info->conflicts; if (o->merge) conflicts >>= 1; conflicts |= dirmask; /* * Ok, we've filled in up to any potential index entry in src[0], * now do the rest. */ for (i = 0; i < n; i++) { int stage; unsigned int bit = 1ul << i; if (conflicts & bit) { src[i + o->merge] = o->df_conflict_entry; continue; } if (!(mask & bit)) continue; if (!o->merge) stage = 0; else if (i + 1 < o->head_idx) stage = 1; else if (i + 1 > o->head_idx) stage = 3; else stage = 2; src[i + o->merge] = create_ce_entry(info, names + i, stage); } if (o->merge) { int ret = call_unpack_fn(src, o); for (i = 1; i <= n; i++) if (src[i] && src[i] != o->df_conflict_entry) cache_entry_free(src[i]); return ret; } for (i = 0; i < n; i++) if (src[i] && src[i] != o->df_conflict_entry) add_entry(o, src[i], 0, 0); return 0; } /* NEEDSWORK: give this a better name and share with tree-walk.c */ static int name_compare(const char *a, int a_len, const char *b, int b_len) { int len = (a_len < b_len) ? a_len : b_len; int cmp = memcmp(a, b, len); if (cmp) return cmp; return (a_len - b_len); } /* * The tree traversal is looking at name p. If we have a matching entry, * return it. If name p is a directory in the index, do not return * anything, as we will want to match it when the traversal descends into * the directory. */ static int find_cache_pos(struct traverse_info *info, const struct name_entry *p) { int pos; struct unpack_trees_options *o = info->data; struct index_state *index = o->src_index; int pfxlen = info->pathlen; int p_len = p->pathlen; for (pos = o->cache_bottom; pos < index->cache_nr; pos++) { struct cache_entry *ce = index->cache[pos]; const char *ce_name, *ce_slash; int cmp, ce_len; if (ce->ce_flags & CE_UNPACKED) { /* * cache_bottom entry is already unpacked, so * we can never match it; don't check it * again. */ if (pos == o->cache_bottom) ++o->cache_bottom; continue; } if (!ce_in_traverse_path(ce, info)) continue; ce_name = ce->name + pfxlen; ce_slash = strchr(ce_name, '/'); if (ce_slash) ce_len = ce_slash - ce_name; else ce_len = ce_namelen(ce) - pfxlen; cmp = name_compare(p->path, p_len, ce_name, ce_len); /* * Exact match; if we have a directory we need to * delay returning it. */ if (!cmp) return ce_slash ? -2 - pos : pos; if (0 < cmp) continue; /* keep looking */ /* * ce_name sorts after p->path; could it be that we * have files under p->path directory in the index? * E.g. ce_name == "t-i", and p->path == "t"; we may * have "t/a" in the index. */ if (p_len < ce_len && !memcmp(ce_name, p->path, p_len) && ce_name[p_len] < '/') continue; /* keep looking */ break; } return -1; } static struct cache_entry *find_cache_entry(struct traverse_info *info, const struct name_entry *p) { int pos = find_cache_pos(info, p); struct unpack_trees_options *o = info->data; if (0 <= pos) return o->src_index->cache[pos]; else return NULL; } static void debug_path(struct traverse_info *info) { if (info->prev) { debug_path(info->prev); if (*info->prev->name.path) putchar('/'); } printf("%s", info->name.path); } static void debug_name_entry(int i, struct name_entry *n) { printf("ent#%d %06o %s\n", i, n->path ? n->mode : 0, n->path ? n->path : "(missing)"); } static void debug_unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info) { int i; printf("* unpack mask %lu, dirmask %lu, cnt %d ", mask, dirmask, n); debug_path(info); putchar('\n'); for (i = 0; i < n; i++) debug_name_entry(i, names + i); } static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info) { struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, }; struct unpack_trees_options *o = info->data; const struct name_entry *p = names; /* Find first entry with a real name (we could use "mask" too) */ while (!p->mode) p++; if (o->debug_unpack) debug_unpack_callback(n, mask, dirmask, names, info); /* Are we supposed to look at the index too? */ if (o->merge) { while (1) { int cmp; struct cache_entry *ce; if (o->diff_index_cached) ce = next_cache_entry(o); else ce = find_cache_entry(info, p); if (!ce) break; cmp = compare_entry(ce, info, p); if (cmp < 0) { if (unpack_index_entry(ce, o) < 0) return -1; continue; } if (!cmp) { if (ce_stage(ce)) { /* * If we skip unmerged index * entries, we'll skip this * entry *and* the tree * entries associated with it! */ if (o->skip_unmerged) { add_same_unmerged(ce, o); return mask; } } src[0] = ce; } break; } } if (unpack_nondirectories(n, mask, dirmask, src, names, info) < 0) return -1; if (src[0]) { if (ce_stage(src[0])) mark_ce_used_same_name(src[0], o); else mark_ce_used(src[0], o); } /* Now handle any directories.. */ if (dirmask) { unsigned long conflicts = mask & ~dirmask; if (o->merge) { conflicts <<= 1; if (src[0]) conflicts |= 1; } /* * This is an optimization that relies on cache tree. * Skip it for now. */ #if 0 /* special case: "diff-index --cached" looking at a tree */ if (o->diff_index_cached && n == 1 && dirmask == 1 && S_ISDIR(names->mode)) { int matches; matches = cache_tree_matches_traversal(o->src_index->cache_tree, names, info); /* * Everything under the name matches; skip the * entire hierarchy. diff_index_cached codepath * special cases D/F conflicts in such a way that * it does not do any look-ahead, so this is safe. */ if (matches) { o->cache_bottom += matches; return mask; } } #endif if (traverse_trees_recursive(n, dirmask, conflicts, names, info) < 0) return -1; return mask; } return mask; } static void setup_traverse_info(struct traverse_info *info, const char *base) { int pathlen = strlen(base); static struct traverse_info dummy; memset(info, 0, sizeof(*info)); if (pathlen && base[pathlen-1] == '/') pathlen--; info->pathlen = pathlen ? pathlen + 1 : 0; info->name.path = base; /* info->name.sha1 = NULL; */ if (pathlen) info->prev = &dummy; } int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o) { int ret = 0; static struct cache_entry *dfc; memset(&o->result, 0, sizeof(o->result)); o->result.initialized = 1; o->result.version = o->src_index->version; o->result.has_modifier = o->src_index->has_modifier; o->result.timestamp.sec = o->src_index->timestamp.sec; o->result.timestamp.nsec = o->src_index->timestamp.nsec; o->merge_size = len; mark_all_ce_unused(o->src_index); if (!dfc) dfc = calloc(1, cache_entry_size(0)); o->df_conflict_entry = dfc; if (len) { struct traverse_info info; setup_traverse_info(&info, ""); info.fn = unpack_callback; info.data = o; info.show_all_errors = o->show_all_errors; if (traverse_trees(len, t, &info) < 0) goto return_failed; } /* Any left-over entries in the index? */ if (o->merge) { while (1) { struct cache_entry *ce = next_cache_entry(o); if (!ce) break; if (unpack_index_entry(ce, o) < 0) goto return_failed; } } mark_all_ce_unused(o->src_index); if (o->trivial_merges_only && o->nontrivial_merge) { ret = -1; } /* o->src_index = NULL; */ /* ret = check_updates(o) ? (-2) : 0; */ /* if (o->dst_index) */ /* *o->dst_index = o->result; */ done: return ret; return_failed: /* if (o->show_all_errors) */ /* display_error_msgs(o); */ mark_all_ce_unused(o->src_index); ret = -1; goto done; } /* Here come the merge functions */ static int reject_merge(struct cache_entry *ce, struct unpack_trees_options *o) { return add_rejected_path(o, ERROR_WOULD_OVERWRITE, ce->name); } static int same(struct cache_entry *a, struct cache_entry *b) { if (!!a != !!b) return 0; if (!a && !b) return 1; if ((a->ce_flags | b->ce_flags) & CE_CONFLICTED) return 0; return a->ce_mode == b->ce_mode && !hashcmp(a->sha1, b->sha1); } /* * When a CE gets turned into an unmerged entry, we * want it to be up-to-date */ static int verify_uptodate_1(struct cache_entry *ce, struct unpack_trees_options *o, enum unpack_trees_error_types error_type) { #if 0 char full_path[SEAF_PATH_MAX]; SeafStat st; if (o->index_only || (!((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) && (o->reset || ce_uptodate(ce)))) return 0; snprintf(full_path, SEAF_PATH_MAX, "%s/%s", o->base, ce->name); if (!seaf_stat (full_path, &st)) { unsigned changed = ie_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE); if (!changed) return 0; /* * NEEDSWORK: the current default policy is to allow * submodule to be out of sync wrt the supermodule * index. This needs to be tightened later for * submodules that are marked to be automatically * checked out. */ if (S_ISGITLINK(ce->ce_mode)) return 0; errno = 0; } if (errno == ENOENT) return 0; return o->gently ? -1 : add_rejected_path(o, error_type, ce->name); #endif return 0; } static int verify_uptodate(struct cache_entry *ce, struct unpack_trees_options *o) { /* if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE)) */ /* return 0; */ return verify_uptodate_1(ce, o, ERROR_NOT_UPTODATE_FILE); } static void invalidate_ce_path(struct cache_entry *ce, struct unpack_trees_options *o) { #if 0 if (ce) cache_tree_invalidate_path(o->src_index->cache_tree, ce->name); #endif } #if 0 /* * Check that checking out ce->sha1 in subdir ce->name is not * going to overwrite any working files. * * Currently, git does not checkout subprojects during a superproject * checkout, so it is not going to overwrite anything. */ static int verify_clean_submodule(struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { return 0; } static int verify_clean_subdirectory(struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { /* * we are about to extract "ce->name"; we would not want to lose * anything in the existing directory there. */ int namelen; int i; struct dir_struct d; char *pathbuf; int cnt = 0; unsigned char sha1[20]; /* * First let's make sure we do not have a local modification * in that directory. */ namelen = strlen(ce->name); for (i = locate_in_src_index(ce, o); i < o->src_index->cache_nr; i++) { struct cache_entry *ce2 = o->src_index->cache[i]; int len = ce_namelen(ce2); if (len < namelen || strncmp(ce->name, ce2->name, namelen) || ce2->name[namelen] != '/') break; /* * ce2->name is an entry in the subdirectory to be * removed. */ if (!ce_stage(ce2)) { if (verify_uptodate(ce2, o)) return -1; add_entry(o, ce2, CE_REMOVE, 0); mark_ce_used(ce2, o); } cnt++; } /* * Then we need to make sure that we do not lose a locally * present file that is not ignored. */ pathbuf = malloc(namelen + 2); memcpy(pathbuf, ce->name, namelen); strcpy(pathbuf+namelen, "/"); memset(&d, 0, sizeof(d)); i = read_directory(&d, pathbuf, namelen+1, NULL); if (i) return o->gently ? -1 : add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name); free(pathbuf); return cnt; } static int check_ok_to_remove(const char *name, int len, int dtype, struct cache_entry *ce, SeafStat *st, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { struct cache_entry *result; if (S_ISDIR(st->st_mode)) { /* * We are checking out path "foo" and * found "foo/." in the working tree. * This is tricky -- if we have modified * files that are in "foo/" we would lose * them. */ if (verify_clean_subdirectory(ce, error_type, o) < 0) return -1; return 0; } /* * The previous round may already have decided to * delete this path, which is in a subdirectory that * is being replaced with a blob. */ result = index_name_exists(&o->result, name, len, 0); if (result) { if (result->ce_flags & CE_REMOVE) return 0; } return o->gently ? -1 : add_rejected_path(o, error_type, name); } #endif /* * We do not want to remove or overwrite a working tree file that * is not tracked, unless it is ignored. */ static int verify_absent_1(struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { #if 0 char full_path[SEAF_PATH_MAX]; SeafStat st; if (o->index_only || o->reset || !o->update) return 0; snprintf (full_path, SEAF_PATH_MAX, "%s/%s", o->base, ce->name); if (!seaf_stat (full_path, &st) && S_ISREG(st.st_mode)) return o->gently ? -1: add_rejected_path(o, error_type, ce->name); /* return check_ok_to_remove(ce->name, ce_namelen(ce), */ /* ce_to_dtype(ce), ce, &st, */ /* error_type, o); */ #endif return 0; } static int verify_absent(struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { /* if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE)) */ /* return 0; */ return verify_absent_1(ce, error_type, o); } static int merged_entry(struct cache_entry *merge, struct cache_entry *old, struct unpack_trees_options *o) { int update = CE_UPDATE; if (!old) { /* * New index entries. In sparse checkout, the following * verify_absent() will be delayed until after * traverse_trees() finishes in unpack_trees(), then: * * - CE_NEW_SKIP_WORKTREE will be computed correctly * - verify_absent() be called again, this time with * correct CE_NEW_SKIP_WORKTREE * * verify_absent() call here does nothing in sparse * checkout (i.e. o->skip_sparse_checkout == 0) */ update |= CE_ADDED; /* merge->ce_flags |= CE_NEW_SKIP_WORKTREE; */ if (verify_absent(merge, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) return -1; invalidate_ce_path(merge, o); } else if (!(old->ce_flags & CE_CONFLICTED)) { /* * See if we can re-use the old CE directly? * That way we get the uptodate stat info. * * This also removes the UPDATE flag on a match; otherwise * we will end up overwriting local changes in the work tree. */ if (same(old, merge)) { copy_cache_entry(merge, old); update = 0; } else { if (verify_uptodate(old, o)) return -1; /* Migrate old flags over */ /* update |= old->ce_flags & (CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE); */ invalidate_ce_path(old, o); } } else { /* * Previously unmerged entry left as an existence * marker by read_index_unmerged(); */ invalidate_ce_path(old, o); } /* We need timestamp when checking out the file later. */ if (old) { merge->current_mtime = old->ce_mtime.sec; } add_entry(o, merge, update, CE_STAGEMASK); return 1; } static int deleted_entry(struct cache_entry *ce, struct cache_entry *old, struct unpack_trees_options *o) { /* Did it exist in the index? */ if (!old) { if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED, o)) return -1; return 0; } if (!(old->ce_flags & CE_CONFLICTED) && verify_uptodate(old, o)) return -1; /* We need timestamp when checking out the file later. */ if (old) { ce->current_mtime = old->ce_mtime.sec; } add_entry(o, ce, CE_REMOVE, CE_STAGEMASK); invalidate_ce_path(ce, o); return 1; } static int keep_entry(struct cache_entry *ce, struct unpack_trees_options *o) { add_entry(o, ce, 0, 0); return 1; } #if DBRT_DEBUG static void show_stage_entry(FILE *o, const char *label, const struct cache_entry *ce) { if (!ce) fprintf(o, "%s (missing)\n", label); else fprintf(o, "%s%06o %s %d\t%s\n", label, ce->ce_mode, sha1_to_hex(ce->sha1), ce_stage(ce), ce->name); } #endif int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o) { struct cache_entry *index; struct cache_entry *head; struct cache_entry *remote = stages[o->head_idx + 1]; int count; int head_match = 0; int remote_match = 0; int df_conflict_head = 0; int df_conflict_remote = 0; int any_anc_missing = 0; int no_anc_exists = 1; int i; for (i = 1; i < o->head_idx; i++) { if (!stages[i] || stages[i] == o->df_conflict_entry) any_anc_missing = 1; else no_anc_exists = 0; } index = stages[0]; head = stages[o->head_idx]; if (head == o->df_conflict_entry) { df_conflict_head = 1; head = NULL; } if (remote == o->df_conflict_entry) { df_conflict_remote = 1; remote = NULL; } /* * First, if there's a #16 situation, note that to prevent #13 * and #14. */ if (!same(remote, head)) { for (i = 1; i < o->head_idx; i++) { if (same(stages[i], head)) { head_match = i; } if (same(stages[i], remote)) { remote_match = i; } } } /* * We start with cases where the index is allowed to match * something other than the head: #14(ALT) and #2ALT, where it * is permitted to match the result instead. */ /* #14, #14ALT, #2ALT */ if (remote && !df_conflict_head && head_match && !remote_match) { /* if (index && !same(index, remote) && !same(index, head)) */ /* return o->gently ? -1 : reject_merge(index, o); */ return merged_entry(remote, index, o); } /* * If we have an entry in the index cache, then we want to * make sure that it matches head. */ /* if (index && !same(index, head)) */ /* return o->gently ? -1 : reject_merge(index, o); */ if (head) { /* #5ALT, #15 */ if (same(head, remote)) return merged_entry(remote, index, o); /* #13, #3ALT */ if (!df_conflict_remote && remote_match && !head_match) return merged_entry(head, index, o); } /* #1 */ if (!head && !remote && any_anc_missing) return 0; /* * Under the "aggressive" rule, we resolve mostly trivial * cases that we historically had git-merge-one-file resolve. */ if (o->aggressive) { int head_deleted = !head; int remote_deleted = !remote; struct cache_entry *ce = NULL; if (index) ce = index; else if (head) ce = head; else if (remote) ce = remote; else { for (i = 1; i < o->head_idx; i++) { if (stages[i] && stages[i] != o->df_conflict_entry) { ce = stages[i]; break; } } } /* * Deleted in both. * Deleted in one and unchanged in the other. */ if ((head_deleted && remote_deleted) || (head_deleted && remote && remote_match) || (remote_deleted && head && head_match)) { if (index) return deleted_entry(index, index, o); if (ce && !head_deleted) { if (verify_absent(ce, ERROR_WOULD_LOSE_UNTRACKED_REMOVED, o)) return -1; } return 0; } /* * Added in both, identically. */ if (no_anc_exists && head && remote && same(head, remote)) return merged_entry(head, index, o); } /* Below are "no merge" cases, which require that the index be * up-to-date to avoid the files getting overwritten with * conflict resolution files. */ if (index) { if (verify_uptodate(index, o)) return -1; } o->nontrivial_merge = 1; /* #2, #3, #4, #6, #7, #9, #10, #11. */ count = 0; if (!head_match || !remote_match) { for (i = 1; i < o->head_idx; i++) { if (stages[i] && stages[i] != o->df_conflict_entry) { keep_entry(stages[i], o); count++; break; } } } #if DBRT_DEBUG else { fprintf(stderr, "read-tree: warning #16 detected\n"); show_stage_entry(stderr, "head ", stages[head_match]); show_stage_entry(stderr, "remote ", stages[remote_match]); } #endif /* We need ctime and mtime of index to handle worktree conflict later. */ if (head && index) { head->current_mtime = index->ce_mtime.sec; } if (head) { count += keep_entry(head, o); } if (remote) { count += keep_entry(remote, o); } return count; } /* * Two-way merge. * * The rule is to "carry forward" what is in the index without losing * information across a "fast-forward", favoring a successful merge * over a merge failure when it makes sense. For details of the * "carry forward" rule, please see . * */ int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *current = src[0]; struct cache_entry *oldtree = src[1]; struct cache_entry *newtree = src[2]; if (o->merge_size != 2) { g_warning ("Cannot do a twoway merge of %d trees", o->merge_size); return -1; } if (oldtree == o->df_conflict_entry) oldtree = NULL; if (newtree == o->df_conflict_entry) newtree = NULL; if (current) { if ((!oldtree && !newtree) || /* 4 and 5 */ (!oldtree && newtree && same(current, newtree)) || /* 6 and 7 */ (oldtree && newtree && same(oldtree, newtree)) || /* 14 and 15 */ (oldtree && newtree && !same(oldtree, newtree) && /* 18 and 19 */ same(current, newtree))) { return keep_entry(current, o); } else if (oldtree && !newtree && same(current, oldtree)) { /* 10 or 11 */ return deleted_entry(oldtree, current, o); } else if (oldtree && newtree && same(current, oldtree) && !same(current, newtree)) { /* 20 or 21 */ return merged_entry(newtree, current, o); } else { /* all other failures */ if (oldtree) return o->gently ? -1 : reject_merge(oldtree, o); if (current) return o->gently ? -1 : reject_merge(current, o); if (newtree) return o->gently ? -1 : reject_merge(newtree, o); return -1; } } else if (newtree) { if (oldtree && !o->initial_checkout) { /* * deletion of the path was staged; */ if (same(oldtree, newtree)) return 1; return reject_merge(oldtree, o); } return merged_entry(newtree, current, o); } return deleted_entry(oldtree, current, o); } /* * One-way merge. * * The rule is: * - take the stat information from stage0, take the data from stage1 */ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o) { struct cache_entry *old = src[0]; struct cache_entry *a = src[1]; if (o->merge_size != 1) { g_warning("Cannot do a oneway merge of %d trees", o->merge_size); return -1; } if (!a || a == o->df_conflict_entry) return deleted_entry(old, old, o); if (old && same(old, a)) { int update = 0; if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) { SeafStat st; char full_path[SEAF_PATH_MAX]; snprintf (full_path, SEAF_PATH_MAX, "%s/%s", o->base, old->name); if (seaf_stat (full_path, &st) || ie_match_stat(old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE)) update |= CE_UPDATE; } add_entry(o, old, update, 0); return 0; } return merged_entry(a, old, o); } static const char *unpack_errors[NB_UNPACK_TREES_ERROR_TYPES] = { /* ERROR_WOULD_OVERWRITE */ "%s: Local changes would be overwritten. Cannot %s.\n", /* ERROR_NOT_UPTODATE_FILE */ "%s: Local changes would be overwritten. Cannot %s.\n", /* ERROR_NOT_UPTODATE_DIR */ "%s: Untracked files in this directory would be lost. Cannot %s.\n", /* ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN */ "%s: This file is untracked and would be overwritten. Cannot %s.\n", /* ERROR_WOULD_LOSE_UNTRACKED_REMOVED */ "%s: This file is untracked and would be removed. Cannot %s.\n", }; static const char *opr_str[N_OPR_TYPES] = { "checkout", "merge", }; gboolean get_unpack_trees_error_msgs(struct unpack_trees_options *o, GString *msgbuf, int opr_type) { int e; gboolean has_error = FALSE; for (e = 0; e < NB_UNPACK_TREES_ERROR_TYPES; e++) { GList *rejects = o->unpack_rejects[e]; GList *rej; if (rejects) { has_error = TRUE; for (rej = rejects; rej; rej = rej->next) g_string_append_printf (msgbuf, unpack_errors[e], (char *) (rej->data), opr_str[opr_type]); /* * Dont need to free strings in the list. * They're in ce->name, which will be freeed later. */ string_list_free (rejects); } } return has_error; } seafile-6.1.5/common/unpack-trees.h000066400000000000000000000037711323477647300172250ustar00rootroot00000000000000#ifndef UNPACK_TREES_H #define UNPACK_TREES_H #include "common.h" #include "utils.h" #include "seaf-tree-walk.h" #include "index/index.h" #include "seafile-crypt.h" #define MAX_UNPACK_TREES 8 struct unpack_trees_options; typedef int (*merge_fn_t)(struct cache_entry **src, struct unpack_trees_options *options); enum unpack_trees_error_types { ERROR_WOULD_OVERWRITE = 0, ERROR_NOT_UPTODATE_FILE, ERROR_NOT_UPTODATE_DIR, ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, ERROR_WOULD_LOSE_UNTRACKED_REMOVED, NB_UNPACK_TREES_ERROR_TYPES }; struct unpack_trees_options { unsigned int reset, merge, update, index_only, nontrivial_merge, trivial_merges_only, verbose_update, aggressive, skip_unmerged, initial_checkout, diff_index_cached, debug_unpack, skip_sparse_checkout, gently, show_all_errors; char repo_id[37]; int version; const char *prefix; const char *base; int cache_bottom; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_ERROR_TYPES]; /* * Store error messages in an array, each case * corresponding to a error message type */ GList *unpack_rejects[NB_UNPACK_TREES_ERROR_TYPES]; int head_idx; int merge_size; struct cache_entry *df_conflict_entry; void *unpack_data; struct index_state *dst_index; struct index_state *src_index; struct index_state result; SeafileCrypt *crypt; }; extern int unpack_trees(unsigned n, struct tree_desc *t, struct unpack_trees_options *options); enum { OPR_CHECKOUT, OPR_MERGE, N_OPR_TYPES, }; gboolean get_unpack_trees_error_msgs(struct unpack_trees_options *o, GString *msgbuf, int opr_type); int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o); int twoway_merge(struct cache_entry **src, struct unpack_trees_options *o); int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o); #endif seafile-6.1.5/common/vc-common.c000066400000000000000000000447071323477647300165210ustar00rootroot00000000000000#include "common.h" #include "seafile-session.h" #include "vc-common.h" #include "log.h" #include "seafile-error.h" static GList * merge_bases_many (SeafCommit *one, int n, SeafCommit **twos); static gint compare_commit_by_time (gconstpointer a, gconstpointer b, gpointer unused) { const SeafCommit *commit_a = a; const SeafCommit *commit_b = b; /* Latest commit comes first in the list. */ return (commit_b->ctime - commit_a->ctime); } static gint compare_commit (gconstpointer a, gconstpointer b) { const SeafCommit *commit_a = a; const SeafCommit *commit_b = b; return strcmp (commit_a->commit_id, commit_b->commit_id); } static gboolean add_to_commit_hash (SeafCommit *commit, void *vhash, gboolean *stop) { GHashTable *hash = vhash; char *key = g_strdup (commit->commit_id); g_hash_table_replace (hash, key, key); return TRUE; } static GHashTable * commit_tree_to_hash (SeafCommit *head) { GHashTable *hash; gboolean res; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); res = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, head->repo_id, head->version, head->commit_id, add_to_commit_hash, hash, FALSE); if (!res) goto fail; return hash; fail: g_hash_table_destroy (hash); return NULL; } static GList * get_independent_commits (GList *commits) { SeafCommit **rslt; GList *list, *result; int cnt, i, j; SeafCommit *c; g_debug ("Get independent commits.\n"); cnt = g_list_length (commits); rslt = calloc(cnt, sizeof(*rslt)); for (list = commits, i = 0; list; list = list->next) rslt[i++] = list->data; g_list_free (commits); for (i = 0; i < cnt - 1; i++) { for (j = i+1; j < cnt; j++) { if (!rslt[i] || !rslt[j]) continue; result = merge_bases_many(rslt[i], 1, &rslt[j]); for (list = result; list; list = list->next) { c = list->data; /* If two commits have fast-forward relationship, * drop the older one. */ if (strcmp (rslt[i]->commit_id, c->commit_id) == 0) { seaf_commit_unref (rslt[i]); rslt[i] = NULL; } if (strcmp (rslt[j]->commit_id, c->commit_id) == 0) { seaf_commit_unref (rslt[j]); rslt[j] = NULL; } seaf_commit_unref (c); } } } /* Surviving ones in rslt[] are the independent results */ result = NULL; for (i = 0; i < cnt; i++) { if (rslt[i]) result = g_list_insert_sorted_with_data (result, rslt[i], compare_commit_by_time, NULL); } free(rslt); return result; } typedef struct { GList *result; GHashTable *commit_hash; } MergeTraverseData; static gboolean get_merge_bases (SeafCommit *commit, void *vdata, gboolean *stop) { MergeTraverseData *data = vdata; /* Found a common ancestor. * Dont traverse its parenets. */ if (g_hash_table_lookup (data->commit_hash, commit->commit_id)) { if (!g_list_find_custom (data->result, commit, compare_commit)) { data->result = g_list_insert_sorted_with_data (data->result, commit, compare_commit_by_time, NULL); seaf_commit_ref (commit); } *stop = TRUE; } return TRUE; } /* * Merge "one" with commits in "twos". * The ancestors returned may not be ancestors for all the input commits. * They are common ancestors for one and some commits in twos array. */ static GList * merge_bases_many (SeafCommit *one, int n, SeafCommit **twos) { GHashTable *commit_hash; GList *result = NULL; SeafCommit *commit; int i; MergeTraverseData data; gboolean res; for (i = 0; i < n; i++) { if (one == twos[i]) return g_list_append (result, one); } /* First construct a hash table of all commit ids rooted at one. */ commit_hash = commit_tree_to_hash (one); if (!commit_hash) { g_warning ("Failed to load commit hash.\n"); return NULL; } data.commit_hash = commit_hash; data.result = NULL; for (i = 0; i < n; i++) { res = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, twos[i]->repo_id, twos[i]->version, twos[i]->commit_id, get_merge_bases, &data, FALSE); if (!res) goto fail; } g_hash_table_destroy (commit_hash); result = data.result; if (!result || !result->next) return result; /* There are more than one. Try to find out independent ones. */ result = get_independent_commits (result); return result; fail: result = data.result; while (result) { commit = result->data; seaf_commit_unref (commit); result = g_list_delete_link (result, result); } g_hash_table_destroy (commit_hash); return NULL; } /* * Returns common ancesstor for two branches. * Any two commits should have a common ancestor. * So returning NULL indicates an error, for e.g. corupt commit. */ SeafCommit * get_merge_base (SeafCommit *head, SeafCommit *remote) { GList *result, *iter; SeafCommit *one, **twos; int n, i; SeafCommit *ret = NULL; one = head; twos = (SeafCommit **) calloc (1, sizeof(SeafCommit *)); twos[0] = remote; n = 1; result = merge_bases_many (one, n, twos); free (twos); if (!result || !result->next) goto done; /* * More than one common ancestors. * Loop until the oldest common ancestor is found. */ while (1) { n = g_list_length (result) - 1; one = result->data; twos = calloc (n, sizeof(SeafCommit *)); for (iter = result->next, i = 0; i < n; iter = iter->next, i++) { twos[i] = iter->data; } g_list_free (result); result = merge_bases_many (one, n, twos); free (twos); if (!result || !result->next) break; } done: if (result) ret = result->data; g_list_free (result); return ret; } /* * Returns true if src_head is ahead of dst_head. */ gboolean is_fast_forward (const char *repo_id, int version, const char *src_head, const char *dst_head) { VCCompareResult res; res = vc_compare_commits (repo_id, version, src_head, dst_head); return (res == VC_FAST_FORWARD); } VCCompareResult vc_compare_commits (const char *repo_id, int version, const char *c1, const char *c2) { SeafCommit *commit1, *commit2, *ca; VCCompareResult ret; /* Treat the same as up-to-date. */ if (strcmp (c1, c2) == 0) return VC_UP_TO_DATE; commit1 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, c1); if (!commit1) return VC_INDEPENDENT; commit2 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, c2); if (!commit2) { seaf_commit_unref (commit1); return VC_INDEPENDENT; } ca = get_merge_base (commit1, commit2); if (!ca) ret = VC_INDEPENDENT; else if (strcmp(ca->commit_id, commit1->commit_id) == 0) ret = VC_UP_TO_DATE; else if (strcmp(ca->commit_id, commit2->commit_id) == 0) ret = VC_FAST_FORWARD; else ret = VC_INDEPENDENT; if (ca) seaf_commit_unref (ca); seaf_commit_unref (commit1); seaf_commit_unref (commit2); return ret; } /** * Diff a specific file with parent(s). * If @commit is a merge, both parents will be compared. * @commit must have this file and it's id is given in @file_id. * * Returns 0 if there is no difference; 1 otherwise. * If returns 0, @parent will point to the next commit to traverse. * If I/O error occurs, @error will be set. */ static int diff_parents_with_path (SeafCommit *commit, const char *repo_id, const char *store_id, int version, const char *path, const char *file_id, char *parent, GError **error) { SeafCommit *p1 = NULL, *p2 = NULL; char *file_id_p1 = NULL, *file_id_p2 = NULL; int ret = 0; p1 = seaf_commit_manager_get_commit (seaf->commit_mgr, commit->repo_id, commit->version, commit->parent_id); if (!p1) { g_warning ("Failed to find commit %s.\n", commit->parent_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, " "); return 0; } if (strcmp (p1->root_id, EMPTY_SHA1) == 0) { seaf_commit_unref (p1); return 1; } if (commit->second_parent_id) { p2 = seaf_commit_manager_get_commit (seaf->commit_mgr, commit->repo_id, commit->version, commit->second_parent_id); if (!p2) { g_warning ("Failed to find commit %s.\n", commit->second_parent_id); seaf_commit_unref (p1); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, " "); return 0; } } if (!p2) { file_id_p1 = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, store_id, version, p1->root_id, path, NULL, error); if (*error) goto out; if (!file_id_p1 || strcmp (file_id, file_id_p1) != 0) ret = 1; else memcpy (parent, p1->commit_id, 41); } else { file_id_p1 = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, store_id, version, p1->root_id, path, NULL, error); if (*error) goto out; file_id_p2 = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, store_id, version, p2->root_id, path, NULL, error); if (*error) goto out; if (file_id_p1 && file_id_p2) { if (strcmp(file_id, file_id_p1) != 0 && strcmp(file_id, file_id_p2) != 0) ret = 1; else if (strcmp(file_id, file_id_p1) == 0) memcpy (parent, p1->commit_id, 41); else memcpy (parent, p2->commit_id, 41); } else if (file_id_p1 && !file_id_p2) { if (strcmp(file_id, file_id_p1) != 0) ret = 1; else memcpy (parent, p1->commit_id, 41); } else if (!file_id_p1 && file_id_p2) { if (strcmp(file_id, file_id_p2) != 0) ret = 1; else memcpy (parent, p2->commit_id, 41); } else { ret = 1; } } out: g_free (file_id_p1); g_free (file_id_p2); if (p1) seaf_commit_unref (p1); if (p2) seaf_commit_unref (p2); return ret; } static int get_file_modifier_mtime_v0 (const char *repo_id, const char *store_id, int version, const char *head, const char *path, char **modifier, gint64 *mtime) { char commit_id[41]; SeafCommit *commit = NULL; char *file_id = NULL; int changed; int ret = 0; GError *error = NULL; *modifier = NULL; *mtime = 0; memcpy (commit_id, head, 41); while (1) { commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, commit_id); if (!commit) { ret = -1; break; } /* We hit the initial commit. */ if (!commit->parent_id) break; file_id = seaf_fs_manager_path_to_obj_id (seaf->fs_mgr, store_id, version, commit->root_id, path, NULL, &error); if (error) { g_clear_error (&error); ret = -1; break; } /* We expect commit to have this file. */ if (!file_id) { ret = -1; break; } changed = diff_parents_with_path (commit, repo_id, store_id, version, path, file_id, commit_id, &error); if (error) { g_clear_error (&error); ret = -1; break; } if (changed) { *modifier = g_strdup (commit->creator_name); *mtime = commit->ctime; break; } else { /* If this commit doesn't change the file, commit_id will be set * to the parent commit to traverse. */ g_free (file_id); seaf_commit_unref (commit); } } g_free (file_id); if (commit) seaf_commit_unref (commit); return ret; } static int get_file_modifier_mtime_v1 (const char *repo_id, const char *store_id, int version, const char *head, const char *path, char **modifier, gint64 *mtime) { SeafCommit *commit = NULL; SeafDir *dir = NULL; SeafDirent *dent = NULL; int ret = 0; commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, head); if (!commit) { seaf_warning ("Failed to get commit %s.\n", head); return -1; } char *parent = g_path_get_dirname (path); if (strcmp(parent, ".") == 0) { g_free (parent); parent = g_strdup(""); } char *filename = g_path_get_basename (path); dir = seaf_fs_manager_get_seafdir_by_path (seaf->fs_mgr, store_id, version, commit->root_id, parent, NULL); if (!dir) { seaf_warning ("dir %s doesn't exist in repo %s.\n", parent, repo_id); ret = -1; goto out; } GList *p; for (p = dir->entries; p; p = p->next) { SeafDirent *d = p->data; if (strcmp (d->name, filename) == 0) { dent = d; break; } } if (!dent) { goto out; } *modifier = g_strdup(dent->modifier); *mtime = dent->mtime; out: g_free (parent); g_free (filename); seaf_commit_unref (commit); seaf_dir_free (dir); return ret; } /** * Get the user who last changed a file and the mtime. * @head: head commit to start the search. * @path: path of the file. */ int get_file_modifier_mtime (const char *repo_id, const char *store_id, int version, const char *head, const char *path, char **modifier, gint64 *mtime) { if (version > 0) return get_file_modifier_mtime_v1 (repo_id, store_id, version, head, path, modifier, mtime); else return get_file_modifier_mtime_v0 (repo_id, store_id, version, head, path, modifier, mtime); } char * gen_conflict_path (const char *origin_path, const char *modifier, gint64 mtime) { char time_buf[64]; time_t t = (time_t)mtime; char *copy = g_strdup (origin_path); GString *conflict_path = g_string_new (NULL); char *dot, *ext; strftime(time_buf, 64, "%Y-%m-%d-%H-%M-%S", localtime(&t)); dot = strrchr (copy, '.'); if (dot != NULL) { *dot = '\0'; ext = dot + 1; if (modifier) g_string_printf (conflict_path, "%s (SFConflict %s %s).%s", copy, modifier, time_buf, ext); else g_string_printf (conflict_path, "%s (SFConflict %s).%s", copy, time_buf, ext); } else { if (modifier) g_string_printf (conflict_path, "%s (SFConflict %s %s)", copy, modifier, time_buf); else g_string_printf (conflict_path, "%s (SFConflict %s)", copy, time_buf); } g_free (copy); return g_string_free (conflict_path, FALSE); } char * gen_conflict_path_wrapper (const char *repo_id, int version, const char *head, const char *in_repo_path, const char *original_path) { char *modifier; gint64 mtime; /* XXX: this function is only used in client, so store_id is always * the same as repo_id. This can be changed if it's also called in * server. */ if (get_file_modifier_mtime (repo_id, repo_id, version, head, in_repo_path, &modifier, &mtime) < 0) return NULL; return gen_conflict_path (original_path, modifier, mtime); } seafile-6.1.5/common/vc-common.h000066400000000000000000000026151323477647300165160ustar00rootroot00000000000000#ifndef VC_COMMON_H #define VC_COMMON_H #include "commit-mgr.h" SeafCommit * get_merge_base (SeafCommit *head, SeafCommit *remote); /* * Returns true if src_head is ahead of dst_head. */ gboolean is_fast_forward (const char *repo_id, int version, const char *src_head, const char *dst_head); typedef enum { VC_UP_TO_DATE, VC_FAST_FORWARD, VC_INDEPENDENT, } VCCompareResult; /* * Compares commits c1 and c2 as if we were going to merge c1 into c2. * * Returns: * VC_UP_TO_DATE: if c2 is ahead of c1, or c1 == c2; * VC_FAST_FORWARD: if c1 is ahead of c2; * VC_INDEPENDENT: if c1 and c2 has no inheritent relationship. * Returns VC_INDEPENDENT if c1 or c2 doesn't exist. */ VCCompareResult vc_compare_commits (const char *repo_id, int version, const char *c1, const char *c2); char * gen_conflict_path (const char *original_path, const char *modifier, gint64 mtime); int get_file_modifier_mtime (const char *repo_id, const char *store_id, int version, const char *head, const char *path, char **modifier, gint64 *mtime); /* Wrapper around the above two functions */ char * gen_conflict_path_wrapper (const char *repo_id, int version, const char *head, const char *in_repo_path, const char *original_path); #endif seafile-6.1.5/configure.ac000066400000000000000000000145051323477647300154460ustar00rootroot00000000000000dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) AC_INIT([seafile], [6.1.5], [info@seafile.com]) AC_CONFIG_HEADER([config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.9 foreign]) #AC_MINGW32 AC_CANONICAL_BUILD dnl enable the build of share library by default AC_ENABLE_SHARED AC_SUBST(LIBTOOL_DEPS) # Checks for programs. AC_PROG_CC #AM_C_PROTOTYPES AC_C_CONST AC_PROG_MAKE_SET # AC_PROG_RANLIB LT_INIT # Checks for headers. #AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h locale.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/socket.h sys/time.h termios.h unistd.h utime.h utmp.h]) # Checks for typedefs, structures, and compiler characteristics. AC_SYS_LARGEFILE # Checks for library functions. #AC_CHECK_FUNCS([alarm dup2 ftruncate getcwd gethostbyname gettimeofday memmove memset mkdir rmdir select setlocale socket strcasecmp strchr strdup strrchr strstr strtol uname utime strtok_r sendfile]) # check platform AC_MSG_CHECKING(for WIN32) if test "$build_os" = "mingw32" -o "$build_os" = "mingw64"; then bwin32=true AC_MSG_RESULT(compile in mingw) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING(for Mac) if test "$(uname)" = "Darwin"; then bmac=true AC_MSG_RESULT(compile in mac) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING(for Linux) if test "$bmac" != "true" -a "$bwin32" != "true"; then blinux=true AC_MSG_RESULT(compile in linux) else AC_MSG_RESULT(no) fi AM_CONDITIONAL([WIN32], [test "$bwin32" = "true"]) AM_CONDITIONAL([MACOS], [test "$bmac" = "true"]) AM_CONDITIONAL([LINUX], [test "$blinux" = "true"]) # check libraries if test "$bwin32" != true; then if test "$bmac" = true; then AC_CHECK_LIB(c, uuid_generate, [echo "found library uuid"], AC_MSG_ERROR([*** Unable to find uuid_generate in libc]), ) else AC_CHECK_LIB(uuid, uuid_generate, [echo "found library uuid"], AC_MSG_ERROR([*** Unable to find uuid library]), ) fi fi AC_CHECK_LIB(pthread, pthread_create, [echo "found library pthread"], AC_MSG_ERROR([*** Unable to find pthread library]), ) AC_CHECK_LIB(sqlite3, sqlite3_open,[echo "found library sqlite3"] , AC_MSG_ERROR([*** Unable to find sqlite3 library]), ) dnl Do we need to use AX_LIB_SQLITE3 to check sqlite? dnl AX_LIB_SQLITE3 CONSOLE= if test "$bwin32" = "true"; then AC_ARG_ENABLE(console, AC_HELP_STRING([--enable-console], [enable console]), [console=$enableval],[console="yes"]) if test x${console} != xyes ; then CONSOLE="-Wl,--subsystem,windows -Wl,--entry,_mainCRTStartup" fi fi AC_SUBST(CONSOLE) if test "$bwin32" = true; then LIB_WS32=-lws2_32 LIB_GDI32=-lgdi32 LIB_RT= LIB_INTL=-lintl LIBS= LIB_RESOLV= LIB_UUID=-lRpcrt4 LIB_IPHLPAPI=-liphlpapi LIB_SHELL32=-lshell32 LIB_PSAPI=-lpsapi LIB_MAC= MSVC_CFLAGS="-D__MSVCRT__ -D__MSVCRT_VERSION__=0x0601" LIB_CRYPT32=-lcrypt32 elif test "$bmac" = true ; then LIB_WS32= LIB_GDI32= LIB_RT= LIB_INTL= LIB_RESOLV=-lresolv LIB_UUID= LIB_IPHLPAPI= LIB_SHELL32= LIB_PSAPI= MSVC_CFLAGS= LIB_MAC="-framework CoreServices" LIB_CRYPT32= LIB_ICONV=-liconv else LIB_WS32= LIB_GDI32= LIB_RT= LIB_INTL= LIB_RESOLV=-lresolv LIB_UUID=-luuid LIB_IPHLPAPI= LIB_SHELL32= LIB_PSAPI= LIB_MAC= MSVC_CFLAGS= LIB_CRYPT32= fi AC_SUBST(LIB_WS32) AC_SUBST(LIB_GDI32) AC_SUBST(LIB_RT) AC_SUBST(LIB_INTL) AC_SUBST(LIB_RESOLV) AC_SUBST(LIB_UUID) AC_SUBST(LIB_IPHLPAPI) AC_SUBST(LIB_SHELL32) AC_SUBST(LIB_PSAPI) AC_SUBST(LIB_MAC) AC_SUBST(MSVC_CFLAGS) AC_SUBST(LIB_CRYPT32) AC_SUBST(LIB_ICONV) LIBEVENT_REQUIRED=2.0 GLIB_REQUIRED=2.16.0 CCNET_REQUIRED=0.9.3 SEARPC_REQUIRED=1.0 JANSSON_REQUIRED=2.2.1 CURL_REQUIRED=7.17 ZLIB_REQUIRED=1.2.0 GNUTLS_REQUIRED=3.3.0 PKG_CHECK_MODULES(GLIB2, [glib-2.0 >= $GLIB_REQUIRED]) AC_SUBST(GLIB2_CFLAGS) AC_SUBST(GLIB2_LIBS) PKG_CHECK_MODULES(GOBJECT, [gobject-2.0 >= $GLIB_REQUIRED]) AC_SUBST(GOBJECT_CFLAGS) AC_SUBST(GOBJECT_LIBS) PKG_CHECK_MODULES(CCNET, [libccnet >= $CCNET_REQUIRED]) AC_SUBST(CCNET_CFLAGS) AC_SUBST(CCNET_LIBS) PKG_CHECK_MODULES(SEARPC, [libsearpc >= $SEARPC_REQUIRED]) AC_SUBST(SEARPC_CFLAGS) AC_SUBST(SEARPC_LIBS) PKG_CHECK_MODULES(JANSSON, [jansson >= $JANSSON_REQUIRED]) AC_SUBST(JANSSON_CFLAGS) AC_SUBST(JANSSON_LIBS) PKG_CHECK_MODULES(LIBEVENT, [libevent >= $LIBEVENT_REQUIRED]) AC_SUBST(LIBEVENT_CFLAGS) AC_SUBST(LIBEVENT_LIBS) PKG_CHECK_MODULES(ZLIB, [zlib >= $ZLIB_REQUIRED]) AC_SUBST(ZLIB_CFLAGS) AC_SUBST(ZLIB_LIBS) PKG_CHECK_MODULES(CURL, [libcurl >= $CURL_REQUIRED]) AC_SUBST(CURL_CFLAGS) AC_SUBST(CURL_LIBS) AM_PATH_PYTHON([2.6]) if test "$bwin32" = true; then # set pyexecdir to somewhere like /c/Python26/Lib/site-packages pyexecdir=${PYTHON_DIR}/Lib/site-packages pythondir=${pyexecdir} pkgpyexecdir=${pyexecdir}/${PACKAGE} pkgpythondir=${pythondir}/${PACKAGE} fi # end for bwin32 BPWRAPPER_REQUIRED=0.1 AC_ARG_ENABLE(breakpad, AC_HELP_STRING([--enable-breakpad], [build google breadpad support]), [compile_breakpad=$enableval],[compile_breakpad="no"]) AM_CONDITIONAL([HAVE_BREAKPAD_SUPPORT], [test "${compile_breakpad}" = "yes"]) if test "${compile_breakpad}" = "yes"; then PKG_CHECK_MODULES(BPWRAPPER, [bpwrapper]) AC_DEFINE(HAVE_BREAKPAD_SUPPORT, 1, [Breakpad support enabled]) AC_SUBST(BPWRAPPER_CFLAGS) AC_SUBST(BPWRAPPER_LIBS) fi AC_ARG_WITH([gpl-crypto], AS_HELP_STRING([--with-gpl-crypto=[yes|no]], [Use GPL compatible crypto libraries. Default no.]), [ gpl_crypto=$with_gpl_crypto ], [ gpl_crypto="no"]) if test "xyes" = "x$gpl_crypto"; then PKG_CHECK_MODULES(GNUTLS, [gnutls >= $GNUTLS_REQUIRED]) AC_SUBST(GNUTLS_CFLAGS) AC_SUBST(GNUTLS_LIBS) PKG_CHECK_MODULES(NETTLE, [nettle]) AC_SUBST(NETTLE_CFLAGS) AC_SUBST(NETTLE_LIBS) AC_DEFINE(USE_GPL_CRYPTO, 1, [Use GPL-compatible crypto libraries]) else AC_CHECK_LIB(crypto, SHA1_Init, [echo "found library crypto"], AC_MSG_ERROR([*** Unable to find openssl crypto library]), ) PKG_CHECK_MODULES(SSL, [openssl]) AC_SUBST(SSL_CFLAGS) AC_SUBST(SSL_LIBS) fi ac_configure_args="$ac_configure_args -q" AC_CONFIG_FILES( Makefile include/Makefile lib/Makefile lib/libseafile.pc common/Makefile common/cdc/Makefile common/index/Makefile daemon/Makefile app/Makefile doc/Makefile python/Makefile python/seafile/Makefile ) AC_OUTPUT seafile-6.1.5/daemon/000077500000000000000000000000001323477647300144165ustar00rootroot00000000000000seafile-6.1.5/daemon/Makefile.am000066400000000000000000000063531323477647300164610ustar00rootroot00000000000000 AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ -DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \ -DSEAFILE_CLIENT \ -I$(top_srcdir)/include \ -I$(top_srcdir)/lib \ -I$(top_builddir)/lib \ -I$(top_srcdir)/common \ @CCNET_CFLAGS@ \ @SEARPC_CFLAGS@ \ @GLIB2_CFLAGS@ \ @MSVC_CFLAGS@ \ @CURL_CFLAGS@ \ @BPWRAPPER_CFLAGS@ \ @GNUTLS_CFLAGS@ \ -Wall bin_PROGRAMS = seaf-daemon proc_headers = $(addprefix processors/, \ check-tx-v3-proc.h \ sendfs-proc.h \ getfs-proc.h \ sendbranch-proc.h \ getcs-proc.h \ sync-repo-proc.h \ getcommit-v2-proc.h \ sendcommit-v3-proc.h \ sendcommit-v3-new-proc.h \ getcs-v2-proc.h \ checkbl-proc.h \ getcommit-v3-proc.h \ checkff-proc.h \ getca-proc.h \ check-protocol-proc.h \ sendcommit-v4-proc.h \ sendfs-v2-proc.h \ getfs-v2-proc.h) proc_headers += ../common/processors/objecttx-common.h noinst_HEADERS = \ repo-mgr.h \ transfer-mgr.h \ status.h sync-mgr.h \ wt-monitor.h \ merge.h merge-recursive.h vc-utils.h seafile-session.h \ clone-mgr.h \ wt-monitor-structs.h \ ../common/sync-repo-common.h \ block-tx-client.h \ seafile-config.h \ http-tx-mgr.h \ sync-status-tree.h \ filelock-mgr.h \ set-perm.h \ change-set.h \ $(proc_headers) if LINUX wt_monitor_src = wt-monitor.c wt-monitor-linux.c wt-monitor-structs.c endif if WIN32 wt_monitor_src = wt-monitor.c wt-monitor-win32.c wt-monitor-structs.c endif if MACOS wt_monitor_src = wt-monitor.c wt-monitor-macos.c wt-monitor-structs.c endif common_src = \ http-tx-mgr.c \ transfer-mgr.c \ ../common/unpack-trees.c ../common/seaf-tree-walk.c \ merge.c merge-recursive.c vc-utils.c \ status.c sync-mgr.c seafile-session.c \ ../common/seafile-crypt.c ../common/diff-simple.c $(wt_monitor_src) \ clone-mgr.c \ seafile-config.c \ ../common/branch-mgr.c ../common/fs-mgr.c \ repo-mgr.c ../common/commit-mgr.c \ ../common/log.c ../common/object-list.c \ ../common/rpc-service.c \ ../common/vc-common.c \ ../common/seaf-utils.c \ ../common/obj-store.c \ ../common/obj-backend-fs.c \ ../common/block-mgr.c \ ../common/block-backend.c \ ../common/block-backend-fs.c \ ../common/mq-mgr.c \ ../common/curl-init.c \ block-tx-client.c \ ../common/block-tx-utils.c \ sync-status-tree.c \ filelock-mgr.c \ set-perm.c \ change-set.c \ processors/check-tx-v3-proc.c \ processors/sendfs-proc.c \ processors/getfs-proc.c \ processors/sendbranch-proc.c \ processors/getcs-proc.c \ processors/sync-repo-proc.c \ processors/getcommit-v2-proc.c \ processors/sendcommit-v3-proc.c \ processors/sendcommit-v3-new-proc.c \ processors/getcs-v2-proc.c \ processors/checkbl-proc.c \ processors/getcommit-v3-proc.c \ processors/checkff-proc.c \ processors/getca-proc.c \ processors/check-protocol-proc.c \ processors/sendcommit-v4-proc.c \ processors/sendfs-v2-proc.c \ processors/getfs-v2-proc.c seaf_daemon_SOURCES = seaf-daemon.c $(common_src) seaf_daemon_LDADD = $(top_builddir)/lib/libseafile_common.la \ @GLIB2_LIBS@ @GOBJECT_LIBS@ @SSL_LIBS@ @GNUTLS_LIBS@ @NETTLE_LIBS@ \ @LIB_RT@ @LIB_UUID@ -lsqlite3 @LIBEVENT_LIBS@ \ $(top_builddir)/common/cdc/libcdc.la \ $(top_builddir)/common/index/libindex.la @LIB_WS32@ @LIB_CRYPT32@ \ @SEARPC_LIBS@ @CCNET_LIBS@ @JANSSON_LIBS@ @LIB_MAC@ @ZLIB_LIBS@ @CURL_LIBS@ @BPWRAPPER_LIBS@ seaf_daemon_LDFLAGS = @CONSOLE@ seafile-6.1.5/daemon/block-tx-client.c000066400000000000000000000741541323477647300175740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "block-tx-client.h" #ifndef USE_GPL_CRYPTO #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include "net.h" #ifndef WIN32 #include #endif #include #include #include #include "seafile-session.h" #include "block-tx-utils.h" #include "utils.h" /* * Handshake: * * protocol-signature + version + session-key(encrypted with RSA public key) * --------------------------------> * * OK + version * <------------------------------- * * Following communication is encrypted with session-key * * session-token for authentication * --------------------------------> * * OK * <-------------------------------- * * Reqeust header + content * ---------------------------------> * * Response header + content * <-------------------------------- * * ... ... * * Connection closed */ enum { RECV_STATE_HANDSHAKE = 0, RECV_STATE_AUTH, RECV_STATE_HEADER, RECV_STATE_CONTENT, RECV_STATE_DONE, }; struct _BlockTxClient { BlockTxInfo *info; BlockTxClientDoneCB cb; evutil_socket_t data_fd; struct evbuffer *recv_buf; int recv_state; char *curr_block_id; /* Used by get block */ BlockHandle *block; unsigned char key[ENC_KEY_SIZE]; unsigned char iv[ENC_BLOCK_SIZE]; unsigned char key_v2[ENC_KEY_SIZE]; unsigned char iv_v2[ENC_BLOCK_SIZE]; FrameParser parser; gboolean break_loop; int version; }; typedef struct _BlockTxClient BlockTxClient; /* Connection establishment. */ static int dns_lookup (const char *addr_str, struct sockaddr_in *sa, ev_socklen_t *sa_len) { struct evutil_addrinfo hints; struct evutil_addrinfo *answer = NULL; int err; /* Build the hints to tell getaddrinfo how to act. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; /* only use IPv4 now. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */ /* Only return addresses we can use. */ hints.ai_flags = EVUTIL_AI_ADDRCONFIG; /* Look up the hostname. */ err = evutil_getaddrinfo(addr_str, NULL, &hints, &answer); if (err != 0) { seaf_warning("Error while resolving '%s': %s\n", addr_str, evutil_gai_strerror(err)); return -1; } *sa = *((struct sockaddr_in *)answer->ai_addr); *sa_len = (ev_socklen_t)answer->ai_addrlen; evutil_freeaddrinfo (answer); return 0; } static evutil_socket_t connect_chunk_server (ChunkServer *cs) { struct sockaddr_in sa; ev_socklen_t sa_len; evutil_socket_t data_fd; ev_socklen_t optlen; if (dns_lookup (cs->addr, &sa, &sa_len) < 0) { return -1; } sa.sin_family = AF_INET; sa.sin_port = htons(cs->port); data_fd = socket (AF_INET, SOCK_STREAM, 0); if (data_fd < 0) { seaf_warning ("socket error: %s.\n", strerror(errno)); return -1; } #ifdef WIN32 /* Set large enough TCP buffer size. * This greatly enhances sync speed for high latency network. * Windows by default use 8KB buffers, which is too small for such case. * Linux has auto-tuning for TCP buffers, so don't need to set manually. * OSX is TBD. */ #define DEFAULT_SNDBUF_SIZE (1 << 16) /* 64KB */ /* Set send buffer size. */ int sndbuf_size; optlen = sizeof(int); getsockopt (data_fd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, &optlen); if (sndbuf_size < DEFAULT_SNDBUF_SIZE) { sndbuf_size = DEFAULT_SNDBUF_SIZE; optlen = sizeof(int); setsockopt (data_fd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, optlen); } #endif /* Disable Nagle's algorithm. */ int val = 1; optlen = sizeof(int); setsockopt (data_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, optlen); if (connect (data_fd, (struct sockaddr *)&sa, sa_len) < 0) { seaf_warning ("connect error: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); evutil_closesocket (data_fd); return -1; } return data_fd; } /* Handshake */ static int send_handshake (evutil_socket_t data_fd, BlockTxInfo *info) { HandshakeRequest *req; if (sendn (data_fd, BLOCK_PROTOCOL_SIGNATURE, 37) < 0) { seaf_warning ("Failed to send protocol signature: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); info->result = BLOCK_CLIENT_NET_ERROR; return -1; } int req_size = sizeof(HandshakeRequest) + info->enc_key_len; req = (HandshakeRequest *) g_malloc (req_size); req->version = htonl(BLOCK_PROTOCOL_VERSION); req->key_len = htonl(info->enc_key_len); memcpy (req->enc_session_key, info->enc_session_key, info->enc_key_len); if (sendn (data_fd, req, req_size) < 0) { seaf_warning ("Failed to send handshake: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(data_fd))); info->result = BLOCK_CLIENT_NET_ERROR; g_free (req); return -1; } g_free (req); return 0; } static void init_frame_parser (BlockTxClient *client) { FrameParser *parser = &client->parser; if (client->version == 1) { memcpy (parser->key, client->key, ENC_BLOCK_SIZE); memcpy (parser->iv, client->iv, ENC_BLOCK_SIZE); } else if (client->version == 2) { memcpy (parser->key_v2, client->key_v2, ENC_KEY_SIZE); memcpy (parser->iv_v2, client->iv_v2, ENC_BLOCK_SIZE); } parser->version = client->version; parser->cbarg = client; } static int send_authentication (BlockTxClient *client); static int handle_handshake_response (BlockTxClient *client) { BlockTxInfo *info = client->info; struct evbuffer *input = client->recv_buf; HandshakeResponse rsp; if (evbuffer_get_length (input) < sizeof(rsp)) return 0; evbuffer_remove (input, &rsp, sizeof(rsp)); rsp.status = ntohl(rsp.status); rsp.version = ntohl(rsp.version); if (rsp.status == STATUS_OK) { seaf_debug ("Handshake OK.\n"); client->version = MIN (rsp.version, BLOCK_PROTOCOL_VERSION); if (client->version == 1) blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key), client->key, client->iv); else if (client->version == 2) blocktx_generate_encrypt_key (info->session_key, sizeof(info->session_key), client->key_v2, client->iv_v2); else { seaf_warning ("Bad block protocol version %d.\n", rsp.version); info->result = BLOCK_CLIENT_FAILED; return -1; } seaf_debug ("Block protocol version %d.\n", client->version); init_frame_parser (client); if (send_authentication (client) < 0) return -1; return 0; } else if (rsp.status == STATUS_VERSION_MISMATCH) { seaf_warning ("The server refuse to accpet protocol version %d.\n" "Remote version is %d.\n", BLOCK_PROTOCOL_VERSION, rsp.version); /* this is a hard error. */ info->result = BLOCK_CLIENT_FAILED; return -1; } else if (rsp.status == STATUS_INTERNAL_SERVER_ERROR) { seaf_warning ("Internal server error.\n"); info->result = BLOCK_CLIENT_SERVER_ERROR; return -1; } seaf_warning ("Bad status code %d in handshake.\n", rsp.status); info->result = BLOCK_CLIENT_FAILED; return -1; } /* Authentication */ static int transfer_next_block (BlockTxClient *client); static int handle_auth_rsp_content_cb (char *content, int clen, void *cbarg) { BlockTxClient *client = cbarg; AuthResponse *rsp; if (clen != sizeof(AuthResponse)) { seaf_warning ("Invalid auth respnose length %d.\n", clen); client->info->result = BLOCK_CLIENT_FAILED; return -1; } rsp = (AuthResponse *)content; rsp->status = ntohl (rsp->status); if (rsp->status == STATUS_OK) { seaf_debug ("Auth OK.\n"); if (!client->info->transfer_once) { int rsp = BLOCK_CLIENT_READY; pipewrite (client->info->done_pipe[1], (char*)&rsp, sizeof(rsp)); } /* If in interactive mode, wait for TRANSFER command to start transfer. */ if (client->info->transfer_once) return transfer_next_block (client); } else if (rsp->status == STATUS_ACCESS_DENIED) { seaf_warning ("Authentication failed.\n"); /* this is a hard error. */ client->info->result = BLOCK_CLIENT_FAILED; return -1; } else if (rsp->status == STATUS_INTERNAL_SERVER_ERROR) { seaf_warning ("Server error when handling auth.\n"); client->info->result = BLOCK_CLIENT_SERVER_ERROR; return -1; } else { seaf_warning ("Bad status code %d in handshake.\n", rsp->status); client->info->result = BLOCK_CLIENT_FAILED; return -1; } return 0; } static int handle_auth_response (BlockTxClient *client) { return handle_one_frame (client->recv_buf, &client->parser); } static int send_authentication (BlockTxClient *client) { TransferTask *task = client->info->task; EVP_CIPHER_CTX *ctx; int ret = 0; if (client->version == 1) blocktx_encrypt_init (&ctx, client->key, client->iv); else if (client->version == 2) blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2); seaf_debug ("session token length is %d.\n", strlen(task->session_token)); if (send_encrypted_data_frame_begin (client->data_fd, strlen(task->session_token) + 1) < 0) { seaf_warning ("Send auth request: failed to begin.\n"); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } if (send_encrypted_data (ctx, client->data_fd, task->session_token, strlen(task->session_token) + 1) < 0) { seaf_warning ("Send auth request: failed to send data.\n"); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } if (send_encrypted_data_frame_end (ctx, client->data_fd) < 0) { seaf_warning ("Send auth request: failed to end.\n"); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } seaf_debug ("recv_state set to AUTH.\n"); client->parser.content_cb = handle_auth_rsp_content_cb; client->recv_state = RECV_STATE_AUTH; out: EVP_CIPHER_CTX_free (ctx); return ret; } /* Block header */ static int send_block_header (BlockTxClient *client, int command) { RequestHeader header; EVP_CIPHER_CTX *ctx; int ret = 0; header.command = htonl (command); memcpy (header.block_id, client->curr_block_id, 40); if (client->version == 1) blocktx_encrypt_init (&ctx, client->key, client->iv); else if (client->version == 2) blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2); if (send_encrypted_data_frame_begin (client->data_fd, sizeof(header)) < 0) { seaf_warning ("Send block header %s: failed to begin.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } if (send_encrypted_data (ctx, client->data_fd, &header, sizeof(header)) < 0) { seaf_warning ("Send block header %s: failed to send data.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } if (send_encrypted_data_frame_end (ctx, client->data_fd) < 0) { seaf_warning ("Send block header %s: failed to end.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } out: EVP_CIPHER_CTX_free (ctx); return ret; } static int handle_block_header_content_cb (char *content, int clen, void *cbarg) { BlockTxClient *client = cbarg; ResponseHeader *hdr; TransferTask *task = client->info->task; if (clen != sizeof(ResponseHeader)) { seaf_warning ("Invalid block response header length %d.\n", clen); client->info->result = BLOCK_CLIENT_FAILED; return -1; } hdr = (ResponseHeader *)content; hdr->status = ntohl (hdr->status); if (task->type == TASK_TYPE_UPLOAD) { switch (hdr->status) { case STATUS_OK: seaf_debug ("Put block %s succeeded.\n", client->curr_block_id); if (transfer_next_block (client) < 0) return -1; return 0; case STATUS_INTERNAL_SERVER_ERROR: client->info->result = BLOCK_CLIENT_SERVER_ERROR; return -1; default: seaf_warning ("Unexpected response: %d.\n", hdr->status); client->info->result = BLOCK_CLIENT_FAILED; return -1; } } else { switch (hdr->status) { case STATUS_OK: client->block = seaf_block_manager_open_block (seaf->block_mgr, task->repo_id, task->repo_version, client->curr_block_id, BLOCK_WRITE); if (!client->block) { seaf_warning ("Failed to open block %s for write.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_FAILED; return -1; } seaf_debug ("recv_state set to CONTENT.\n"); client->recv_state = RECV_STATE_CONTENT; return 0; case STATUS_INTERNAL_SERVER_ERROR: client->info->result = BLOCK_CLIENT_SERVER_ERROR; return -1; case STATUS_NOT_FOUND: seaf_warning ("Block %s is not found on server.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_FAILED; return -1; default: seaf_warning ("Unexpected response: %d.\n", hdr->status); client->info->result = BLOCK_CLIENT_FAILED; return -1; } } } static int handle_block_header (BlockTxClient *client) { return handle_one_frame (client->recv_buf, &client->parser); } /* Block content */ #define SEND_BUFFER_SIZE 4096 static int send_encrypted_block (BlockTxClient *client, BlockHandle *handle, const char *block_id) { BlockTxInfo *info = client->info; BlockMetadata *md; int size, n, remain; int ret = 0; EVP_CIPHER_CTX *ctx; char send_buf[SEND_BUFFER_SIZE]; md = seaf_block_manager_stat_block_by_handle (seaf->block_mgr, handle); if (!md) { seaf_warning ("Failed to stat block %s.\n", block_id); client->info->result = BLOCK_CLIENT_FAILED; ret = -1; goto out; } size = md->size; g_free (md); if (client->version == 1) blocktx_encrypt_init (&ctx, client->key, client->iv); else if (client->version == 2) blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2); if (send_encrypted_data_frame_begin (client->data_fd, size) < 0) { seaf_warning ("Send block %s: failed to begin.\n", block_id); info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } remain = size; while (remain > 0) { if (info->task->state == TASK_STATE_CANCELED) { info->result = BLOCK_CLIENT_CANCELED; ret = -1; goto out; } n = seaf_block_manager_read_block (seaf->block_mgr, handle, send_buf, SEND_BUFFER_SIZE); if (n < 0) { seaf_warning ("Failed to read block %s.\n", block_id); info->result = BLOCK_CLIENT_FAILED; ret = -1; goto out; } if (send_encrypted_data (ctx, client->data_fd, send_buf, n) < 0) { seaf_warning ("Send block %s: failed to send data.\n", block_id); info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } /* Update global transferred bytes. */ g_atomic_int_add (&(info->task->tx_bytes), n); g_atomic_int_add (&(seaf->sync_mgr->sent_bytes), n); /* If uploaded bytes exceeds the limit, wait until the counter * is reset. We check the counter every 100 milliseconds, so we * can waste up to 100 milliseconds without sending data after * the counter is reset. */ while (1) { gint sent = g_atomic_int_get(&(seaf->sync_mgr->sent_bytes)); if (seaf->sync_mgr->upload_limit > 0 && sent > seaf->sync_mgr->upload_limit) /* 100 milliseconds */ g_usleep (100000); else break; } remain -= n; } if (send_encrypted_data_frame_end (ctx, client->data_fd) < 0) { seaf_warning ("Send block %s: failed to end.\n", block_id); info->result = BLOCK_CLIENT_NET_ERROR; ret = -1; goto out; } out: EVP_CIPHER_CTX_free (ctx); return ret; } static int send_block_content (BlockTxClient *client) { TransferTask *task = client->info->task; BlockHandle *handle = NULL; int ret = 0; handle = seaf_block_manager_open_block (seaf->block_mgr, task->repo_id, task->repo_version, client->curr_block_id, BLOCK_READ); if (!handle) { seaf_warning ("Failed to open block %s.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_FAILED; return -1; } ret = send_encrypted_block (client, handle, client->curr_block_id); seaf_block_manager_close_block (seaf->block_mgr, handle); seaf_block_manager_block_handle_free (seaf->block_mgr, handle); return ret; } static int save_block_content_cb (char *content, int clen, int end, void *cbarg) { BlockTxClient *client = cbarg; TransferTask *task = client->info->task; int n; n = seaf_block_manager_write_block (seaf->block_mgr, client->block, content, clen); if (n < 0) { seaf_warning ("Failed to write block %s.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_FAILED; return -1; } /* Update global transferred bytes. */ g_atomic_int_add (&(task->tx_bytes), clen); g_atomic_int_add (&(seaf->sync_mgr->recv_bytes), clen); while (1) { gint recv_bytes = g_atomic_int_get (&(seaf->sync_mgr->recv_bytes)); if (seaf->sync_mgr->download_limit > 0 && recv_bytes > seaf->sync_mgr->download_limit) { g_usleep (100000); } else { break; } } if (end) { seaf_block_manager_close_block (seaf->block_mgr, client->block); if (seaf_block_manager_commit_block (seaf->block_mgr, client->block) < 0) { seaf_warning ("Failed to commit block %s.\n", client->curr_block_id); client->info->result = BLOCK_CLIENT_FAILED; return -1; } seaf_block_manager_block_handle_free (seaf->block_mgr, client->block); /* Set this handle to invalid. */ client->block = NULL; seaf_debug ("Get block %s succeeded.\n", client->curr_block_id); if (transfer_next_block (client) < 0) return -1; } return 0; } static int handle_block_content (BlockTxClient *client) { return handle_frame_fragments (client->recv_buf, &client->parser); } static int transfer_next_block (BlockTxClient *client) { TransferTask *task = client->info->task; if (client->curr_block_id) { g_queue_pop_head (task->block_ids); g_free (client->curr_block_id); client->curr_block_id = NULL; } if (g_queue_get_length (task->block_ids) == 0) { seaf_debug ("Transfer blocks done.\n"); client->info->result = BLOCK_CLIENT_SUCCESS; client->break_loop = TRUE; return 0; } client->curr_block_id = g_queue_peek_head (task->block_ids); if (task->type == TASK_TYPE_UPLOAD) { seaf_debug ("Put block %s.\n", client->curr_block_id); if (send_block_header (client, REQUEST_COMMAND_PUT) < 0) { seaf_warning ("Failed to send block header for PUT %s.\n", client->curr_block_id); return -1; } if (send_block_content (client) < 0) { seaf_warning ("Failed to send block content for %s.\n", client->curr_block_id); return -1; } seaf_debug ("recv_state set to HEADER.\n"); client->parser.content_cb = handle_block_header_content_cb; client->recv_state = RECV_STATE_HEADER; } else { seaf_debug ("Get block %s.\n", client->curr_block_id); if (send_block_header (client, REQUEST_COMMAND_GET) < 0) { seaf_warning ("Failed to send block header for GET %s.\n", client->curr_block_id); return -1; } seaf_debug ("recv_state set to HEADER.\n"); client->parser.content_cb = handle_block_header_content_cb; client->parser.fragment_cb = save_block_content_cb; client->recv_state = RECV_STATE_HEADER; } return 0; } static void recv_data_cb (BlockTxClient *client) { int ret = 0; /* Let evbuffer determine how much data can be read. */ int n = evbuffer_read (client->recv_buf, client->data_fd, -1); if (n == 0) { seaf_warning ("Data connection is closed by the server.\n"); client->break_loop = TRUE; client->info->result = BLOCK_CLIENT_NET_ERROR; return; } else if (n < 0) { seaf_warning ("Read data connection error: %s.\n", evutil_socket_error_to_string(evutil_socket_geterror(client->data_fd))); client->break_loop = TRUE; client->info->result = BLOCK_CLIENT_NET_ERROR; return; } switch (client->recv_state) { case RECV_STATE_HANDSHAKE: ret = handle_handshake_response (client); break; case RECV_STATE_AUTH: ret = handle_auth_response (client); break; case RECV_STATE_HEADER: ret = handle_block_header (client); if (ret < 0) break; if (client->recv_state == RECV_STATE_CONTENT && client->info->task->type == TASK_TYPE_DOWNLOAD) ret = handle_block_content (client); break; case RECV_STATE_CONTENT: ret = handle_block_content (client); break; } if (ret < 0) client->break_loop = TRUE; } static void shutdown_client (BlockTxClient *client) { if (client->block) { seaf_block_manager_close_block (seaf->block_mgr, client->block); seaf_block_manager_block_handle_free (seaf->block_mgr, client->block); client->block = NULL; } if (client->parser.enc_init) EVP_CIPHER_CTX_free (client->parser.ctx); evbuffer_free (client->recv_buf); evutil_closesocket (client->data_fd); client->recv_state = RECV_STATE_DONE; } static gboolean handle_command (BlockTxClient *client, int command) { gboolean ret = FALSE; int rsp; switch (command) { case BLOCK_CLIENT_CMD_TRANSFER: /* Ignore TRANSFER command if client has been shutdown. */ if (client->recv_state == RECV_STATE_DONE) { seaf_debug ("Client was shutdown, ignore transfer command.\n"); break; } if (transfer_next_block (client) < 0) { rsp = client->info->result; pipewrite (client->info->done_pipe[1], (char*)&rsp, sizeof(rsp)); shutdown_client (client); client->break_loop = FALSE; } break; case BLOCK_CLIENT_CMD_CANCEL: if (client->recv_state == RECV_STATE_DONE) { seaf_debug ("Client was shutdown, ignore cancel command.\n"); break; } seaf_debug ("Canceled command received.\n"); client->info->result = BLOCK_CLIENT_CANCELED; if (client->info->transfer_once) { shutdown_client (client); ret = TRUE; } else { rsp = client->info->result; pipewrite (client->info->done_pipe[1], (char*)&rsp, sizeof(rsp)); shutdown_client (client); client->break_loop = FALSE; ret = FALSE; } break; case BLOCK_CLIENT_CMD_END: client->info->result = BLOCK_CLIENT_ENDED; rsp = client->info->result; pipewrite (client->info->done_pipe[1], (char*)&rsp, sizeof(rsp)); /* Don't need to shutdown_client() if it's already called. */ if (client->recv_state != RECV_STATE_DONE) shutdown_client (client); client->break_loop = FALSE; ret = TRUE; break; } return ret; } static gboolean do_break_loop (BlockTxClient *client) { if (client->info->transfer_once) { shutdown_client (client); return TRUE; } else { int rsp = client->info->result; pipewrite (client->info->done_pipe[1], (char*)&rsp, sizeof(rsp)); if (client->info->result != BLOCK_CLIENT_SUCCESS) shutdown_client (client); client->break_loop = FALSE; return FALSE; } } #define RECV_TIMEOUT_SEC 45 static gboolean client_thread_loop (BlockTxClient *client) { BlockTxInfo *info = client->info; fd_set fds; int max_fd = MAX (info->cmd_pipe[0], client->data_fd); int rc; gboolean restart = FALSE; struct timeval tmo; while (1) { FD_ZERO (&fds); FD_SET (info->cmd_pipe[0], &fds); /* Stop receiving any data after the client was shutdown. */ if (client->recv_state != RECV_STATE_DONE) { FD_SET (client->data_fd, &fds); max_fd = MAX (info->cmd_pipe[0], client->data_fd); } else max_fd = info->cmd_pipe[0]; /* If the client is already shutdown, no need to add timeout. */ if (client->recv_state != RECV_STATE_DONE) { tmo.tv_sec = RECV_TIMEOUT_SEC; tmo.tv_usec = 0; rc = select (max_fd + 1, &fds, NULL, NULL, &tmo); } else { rc = select (max_fd + 1, &fds, NULL, NULL, NULL); } if (rc < 0 && errno == EINTR) { continue; } else if (rc < 0) { seaf_warning ("select error: %s.\n", strerror(errno)); client->info->result = BLOCK_CLIENT_FAILED; break; } else if (rc == 0) { /* timeout */ if (info->task->type == TASK_TYPE_DOWNLOAD) { seaf_warning ("Recv timeout.\n"); client->info->result = BLOCK_CLIENT_NET_ERROR; if (do_break_loop (client)) break; } continue; } if (client->recv_state != RECV_STATE_DONE && FD_ISSET (client->data_fd, &fds)) { recv_data_cb (client); if (client->break_loop && do_break_loop (client)) break; } if (FD_ISSET (info->cmd_pipe[0], &fds)) { int cmd; piperead (info->cmd_pipe[0], (char*)&cmd, sizeof(int)); if (cmd == BLOCK_CLIENT_CMD_RESTART) { restart = TRUE; break; } if (handle_command (client, cmd)) break; } } return restart; } static void * block_tx_client_thread (void *vdata) { BlockTxClient *client = vdata; BlockTxInfo *info = client->info; BlockTxClientDoneCB cb = client->cb; evutil_socket_t data_fd; gboolean restart; retry: data_fd = connect_chunk_server (info->cs); if (data_fd < 0) { info->result = BLOCK_CLIENT_NET_ERROR; if (!info->transfer_once) { pipewrite (info->done_pipe[1], (char*)&info->result, sizeof(info->result)); /* Transfer manager always expects an ENDED response. */ int rsp = BLOCK_CLIENT_ENDED; pipewrite (info->done_pipe[1], (char*)&rsp, sizeof(rsp)); } return vdata; } client->data_fd = data_fd; if (send_handshake (data_fd, info) < 0) { if (!info->transfer_once) { pipewrite (info->done_pipe[1], (char*)&info->result, sizeof(info->result)); int rsp = BLOCK_CLIENT_ENDED; pipewrite (info->done_pipe[1], (char*)&rsp, sizeof(rsp)); } evutil_closesocket (client->data_fd); return vdata; } client->recv_buf = evbuffer_new (); restart = client_thread_loop (client); if (restart) { seaf_message ("Restarting block tx client.\n"); memset (client, 0, sizeof(BlockTxClient)); client->info = info; client->cb = cb; client->info->result = BLOCK_CLIENT_UNKNOWN; goto retry; } return vdata; } static void block_tx_client_thread_done (void *vdata) { BlockTxClient *client = vdata; client->cb (client->info); g_free (client); } int block_tx_client_start (BlockTxInfo *info, BlockTxClientDoneCB cb) { BlockTxClient *client = g_new0 (BlockTxClient, 1); int ret = 0; client->info = info; client->cb = cb; ret = ccnet_job_manager_schedule_job (seaf->job_mgr, block_tx_client_thread, block_tx_client_thread_done, client); if (ret < 0) { seaf_warning ("Failed to start block tx client thread.\n"); return -1; } return 0; } void block_tx_client_run_command (BlockTxInfo *info, int command) { pipewrite (info->cmd_pipe[1], (char*)&command, sizeof(int)); } #else int block_tx_client_start (BlockTxInfo *info, BlockTxClientDoneCB cb) { return 0; } void block_tx_client_run_command (BlockTxInfo *info, int command) { return; } #endif seafile-6.1.5/daemon/block-tx-client.h000066400000000000000000000023041323477647300175650ustar00rootroot00000000000000#ifndef BLOCK_TX_CLIENT_H #define BLOCK_TX_CLIENT_H #include "transfer-mgr.h" typedef void (*BlockTxClientDoneCB) (BlockTxInfo *); /* * There are two modes to use block-tx-client: * * 1. In upload, the client is set to one-time mode. * After all blocks are uploaded, the client done callback is called. * * 2. In download, the client is set to interactive mode. * The block tx client first has to connect to the server and do authentication. * After authentication is done, block-tx-client writes a READY reply to done_pipe. * Transfer manager waits on the done_pipe for the READY reply. * Transfer manager then initiates multiple batches of blocks for download. * After each batch is downloaded, the block client writes to info->done_pipe * to notify transfer manager. * After all blocks are downloaded, transfer manager send a END command to * block client. The block client exits and returns an ENDED response code. */ int block_tx_client_start (BlockTxInfo *info, BlockTxClientDoneCB cb); enum { BLOCK_CLIENT_CMD_TRANSFER = 0, BLOCK_CLIENT_CMD_CANCEL, BLOCK_CLIENT_CMD_END, BLOCK_CLIENT_CMD_RESTART, }; void block_tx_client_run_command (BlockTxInfo *info, int command); #endif seafile-6.1.5/daemon/change-set.c000066400000000000000000000533531323477647300166110ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "seafile-session.h" #include "utils.h" #include "log.h" #include "index/index.h" #include "diff-simple.h" #include "change-set.h" struct _ChangeSetDir { int version; char dir_id[41]; /* A hash table of dirents for fast lookup and insertion. */ GHashTable *dents; #if defined WIN32 || defined __APPLE__ /* Case-insensitive hash table. */ GHashTable *dents_i; #endif }; typedef struct _ChangeSetDir ChangeSetDir; struct _ChangeSetDirent { guint32 mode; char id[41]; char *name; gint64 mtime; char *modifier; gint64 size; /* Only used for directory. Most of time this is NULL * unless we change the subdir too. */ ChangeSetDir *subdir; }; typedef struct _ChangeSetDirent ChangeSetDirent; /* Change set dirent. */ static ChangeSetDirent * changeset_dirent_new (const char *id, guint32 mode, const char *name, gint64 mtime, const char *modifier, gint64 size) { ChangeSetDirent *dent = g_new0 (ChangeSetDirent, 1); dent->mode = mode; memcpy (dent->id, id, 40); dent->name = g_strdup(name); dent->mtime = mtime; dent->modifier = g_strdup(modifier); dent->size = size; return dent; } static ChangeSetDirent * seaf_dirent_to_changeset_dirent (SeafDirent *seaf_dent) { return changeset_dirent_new (seaf_dent->id, seaf_dent->mode, seaf_dent->name, seaf_dent->mtime, seaf_dent->modifier, seaf_dent->size); } static SeafDirent * changeset_dirent_to_seaf_dirent (int version, ChangeSetDirent *dent) { return seaf_dirent_new (version, dent->id, dent->mode, dent->name, dent->mtime, dent->modifier, dent->size); } static void changeset_dir_free (ChangeSetDir *dir); static void changeset_dirent_free (ChangeSetDirent *dent) { if (!dent) return; g_free (dent->name); g_free (dent->modifier); /* Recursively free subdir. */ if (dent->subdir) changeset_dir_free (dent->subdir); g_free (dent); } /* Change set dir. */ static void add_dent_to_dir (ChangeSetDir *dir, ChangeSetDirent *dent) { g_hash_table_insert (dir->dents, g_strdup(dent->name), dent); #if defined WIN32 || defined __APPLE__ g_hash_table_insert (dir->dents_i, g_utf8_strdown(dent->name, -1), dent); #endif } static void remove_dent_from_dir (ChangeSetDir *dir, const char *dname) { char *key; if (g_hash_table_lookup_extended (dir->dents, dname, (gpointer*)&key, NULL)) { g_hash_table_steal (dir->dents, dname); g_free (key); } #if defined WIN32 || defined __APPLE__ char *dname_i = g_utf8_strdown (dname, -1); g_hash_table_remove (dir->dents_i, dname_i); g_free (dname_i); #endif } static ChangeSetDir * changeset_dir_new (int version, const char *id, GList *dirents) { ChangeSetDir *dir = g_new0 (ChangeSetDir, 1); GList *ptr; SeafDirent *dent; ChangeSetDirent *changeset_dent; dir->version = version; if (id) memcpy (dir->dir_id, id, 40); dir->dents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)changeset_dirent_free); #if defined WIN32 || defined __APPLE__ dir->dents_i = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); #endif for (ptr = dirents; ptr; ptr = ptr->next) { dent = ptr->data; changeset_dent = seaf_dirent_to_changeset_dirent(dent); add_dent_to_dir (dir, changeset_dent); } return dir; } static void changeset_dir_free (ChangeSetDir *dir) { if (!dir) return; g_hash_table_destroy (dir->dents); #if defined WIN32 || defined __APPLE__ g_hash_table_destroy (dir->dents_i); #endif g_free (dir); } static ChangeSetDir * seaf_dir_to_changeset_dir (SeafDir *seaf_dir) { return changeset_dir_new (seaf_dir->version, seaf_dir->dir_id, seaf_dir->entries); } static gint compare_dents (gconstpointer a, gconstpointer b) { const SeafDirent *denta = a, *dentb = b; return strcmp(dentb->name, denta->name); } static SeafDir * changeset_dir_to_seaf_dir (ChangeSetDir *dir) { GList *dents = NULL, *seaf_dents = NULL; GList *ptr; ChangeSetDirent *dent; SeafDirent *seaf_dent; SeafDir *seaf_dir; dents = g_hash_table_get_values (dir->dents); for (ptr = dents; ptr; ptr = ptr->next) { dent = ptr->data; seaf_dent = changeset_dirent_to_seaf_dirent (dir->version, dent); seaf_dents = g_list_prepend (seaf_dents, seaf_dent); } /* Sort it in descending order. */ seaf_dents = g_list_sort (seaf_dents, compare_dents); /* seaf_dir_new() computes the dir id. */ seaf_dir = seaf_dir_new (NULL, seaf_dents, dir->version); g_list_free (dents); return seaf_dir; } /* Change set. */ #define CASE_CONFLICT_PATTERN " \\(case conflict \\d+\\)" ChangeSet * changeset_new (const char *repo_id) { SeafRepo *repo; SeafCommit *commit = NULL; SeafDir *seaf_dir = NULL; ChangeSetDir *changeset_dir = NULL; ChangeSet *changeset = NULL; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to find repo %s.\n", repo_id); return NULL; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo->version, repo->head->commit_id); if (!commit) { seaf_warning ("Failed to find head commit %s for repo %s.\n", repo->head->commit_id, repo_id); return NULL; } seaf_dir = seaf_fs_manager_get_seafdir_sorted (seaf->fs_mgr, repo_id, repo->version, commit->root_id); if (!seaf_dir) { seaf_warning ("Failed to find root dir %s in repo %s\n", repo->root_id, repo_id); goto out; } changeset_dir = seaf_dir_to_changeset_dir (seaf_dir); if (!changeset_dir) goto out; GError *error = NULL; GRegex *case_conflict_pattern = g_regex_new(CASE_CONFLICT_PATTERN, 0, 0, &error); if (error) { seaf_warning ("Failed to create regex '%s': %s\n", CASE_CONFLICT_PATTERN, error->message); goto out; } changeset = g_new0 (ChangeSet, 1); memcpy (changeset->repo_id, repo_id, 36); changeset->tree_root = changeset_dir; changeset->case_conflict_pattern = case_conflict_pattern; out: seaf_commit_unref (commit); seaf_dir_free (seaf_dir); return changeset; } void changeset_free (ChangeSet *changeset) { if (!changeset) return; g_list_free_full (changeset->diff, (GDestroyNotify)diff_entry_free); changeset_dir_free (changeset->tree_root); g_regex_unref (changeset->case_conflict_pattern); g_free (changeset); } static void update_file (ChangeSetDirent *dent, unsigned char *sha1, SeafStat *st, const char *modifier) { if (!sha1 || !st || !S_ISREG(st->st_mode)) return; dent->mode = create_ce_mode(st->st_mode); dent->mtime = (gint64)st->st_mtime; dent->size = (gint64)st->st_size; rawdata_to_hex (sha1, dent->id, 20); g_free (dent->modifier); dent->modifier = g_strdup(modifier); } static void create_new_dent (ChangeSetDir *dir, const char *dname, unsigned char *sha1, SeafStat *st, const char *modifier, ChangeSetDirent *in_new_dent) { if (in_new_dent) { g_free (in_new_dent->name); in_new_dent->name = g_strdup(dname); add_dent_to_dir (dir, in_new_dent); return; } char id[41]; rawdata_to_hex (sha1, id, 20); ChangeSetDirent *new_dent; new_dent = changeset_dirent_new (id, create_ce_mode(st->st_mode), dname, st->st_mtime, modifier, st->st_size); add_dent_to_dir (dir, new_dent); } static ChangeSetDir * create_intermediate_dir (ChangeSetDir *parent, const char *dname) { ChangeSetDirent *dent; dent = changeset_dirent_new (EMPTY_SHA1, S_IFDIR, dname, 0, NULL, 0); dent->subdir = changeset_dir_new (parent->version, EMPTY_SHA1, NULL); add_dent_to_dir (parent, dent); return dent->subdir; } #if defined WIN32 || defined __APPLE__ static void handle_case_conflict (ChangeSet *changeset, ChangeSetDir *dir, const char *dname) { char *conflict_dname; ChangeSetDirent *dent; GError *error = NULL; if (g_regex_match (changeset->case_conflict_pattern, dname, 0, NULL)) { conflict_dname = g_regex_replace_literal (changeset->case_conflict_pattern, dname, -1, 0, "", 0, &error); if (!conflict_dname) { seaf_warning ("Failed to replace regex for %s: %s\n", dname, error->message); return; } dent = g_hash_table_lookup (dir->dents, conflict_dname); if (dent) { remove_dent_from_dir (dir, conflict_dname); changeset_dirent_free (dent); } g_free (conflict_dname); } } #endif static void add_to_tree (ChangeSet *changeset, unsigned char *sha1, SeafStat *st, const char *modifier, const char *path, ChangeSetDirent *new_dent) { char *repo_id = changeset->repo_id; ChangeSetDir *root = changeset->tree_root; char **parts, *dname; int n, i; ChangeSetDir *dir; ChangeSetDirent *dent; SeafDir *seaf_dir; parts = g_strsplit (path, "/", 0); n = g_strv_length(parts); dir = root; for (i = 0; i < n; i++) { #if defined WIN32 || defined __APPLE__ try_again: #endif dname = parts[i]; dent = g_hash_table_lookup (dir->dents, dname); if (dent) { if (S_ISDIR(dent->mode)) { if (i == (n-1)) /* Don't need to update empty dir */ break; if (!dent->subdir) { seaf_dir = seaf_fs_manager_get_seafdir(seaf->fs_mgr, repo_id, root->version, dent->id); if (!seaf_dir) { seaf_warning ("Failed to load seafdir %s:%s\n", repo_id, dent->id); break; } dent->subdir = seaf_dir_to_changeset_dir (seaf_dir); seaf_dir_free (seaf_dir); } dir = dent->subdir; } else if (S_ISREG(dent->mode)) { if (i == (n-1)) { /* File exists, update it. */ update_file (dent, sha1, st, modifier); break; } } } else { #if defined WIN32 || defined __APPLE__ /* Only effective for add operation, not applicable to rename. */ if (!new_dent) { char *search_key = g_utf8_strdown (dname, -1); dent = g_hash_table_lookup (dir->dents_i, search_key); g_free (search_key); if (dent) { remove_dent_from_dir (dir, dent->name); g_free (dent->name); dent->name = g_strdup(dname); add_dent_to_dir (dir, dent); goto try_again; } handle_case_conflict (changeset, dir, dname); } #endif if (i == (n-1)) { create_new_dent (dir, dname, sha1, st, modifier, new_dent); } else { dir = create_intermediate_dir (dir, dname); } } } g_strfreev (parts); } static ChangeSetDirent * delete_from_tree (ChangeSet *changeset, const char *path, gboolean *parent_empty) { char *repo_id = changeset->repo_id; ChangeSetDir *root = changeset->tree_root; char **parts, *dname; int n, i; ChangeSetDir *dir; ChangeSetDirent *dent, *ret = NULL; SeafDir *seaf_dir; *parent_empty = FALSE; parts = g_strsplit (path, "/", 0); n = g_strv_length(parts); dir = root; for (i = 0; i < n; i++) { dname = parts[i]; dent = g_hash_table_lookup (dir->dents, dname); if (!dent) break; if (S_ISDIR(dent->mode)) { if (i == (n-1)) { /* Remove from hash table without freeing dent. */ remove_dent_from_dir (dir, dname); if (g_hash_table_size (dir->dents) == 0) *parent_empty = TRUE; ret = dent; break; } if (!dent->subdir) { seaf_dir = seaf_fs_manager_get_seafdir(seaf->fs_mgr, repo_id, root->version, dent->id); if (!seaf_dir) { seaf_warning ("Failed to load seafdir %s:%s\n", repo_id, dent->id); break; } dent->subdir = seaf_dir_to_changeset_dir (seaf_dir); seaf_dir_free (seaf_dir); } dir = dent->subdir; } else if (S_ISREG(dent->mode)) { if (i == (n-1)) { /* Remove from hash table without freeing dent. */ remove_dent_from_dir (dir, dname); if (g_hash_table_size (dir->dents) == 0) *parent_empty = TRUE; ret = dent; break; } } } g_strfreev (parts); return ret; } static void apply_to_tree (ChangeSet *changeset, char status, unsigned char *sha1, SeafStat *st, const char *modifier, const char *path, const char *new_path) { ChangeSetDirent *dent, *dent_dst; gboolean dummy; switch (status) { case DIFF_STATUS_ADDED: case DIFF_STATUS_MODIFIED: case DIFF_STATUS_DIR_ADDED: add_to_tree (changeset, sha1, st, modifier, path, NULL); break; case DIFF_STATUS_RENAMED: dent = delete_from_tree (changeset, path, &dummy); if (!dent) break; dent_dst = delete_from_tree (changeset, new_path, &dummy); changeset_dirent_free (dent_dst); add_to_tree (changeset, NULL, NULL, NULL, new_path, dent); break; } } void add_to_changeset (ChangeSet *changeset, char status, unsigned char *sha1, SeafStat *st, const char *modifier, const char *path, const char *new_path) { DiffEntry *de; unsigned char allzero[20] = {0}; de = diff_entry_new (DIFF_TYPE_INDEX, status, allzero, path); changeset->diff = g_list_prepend (changeset->diff, de); apply_to_tree (changeset, status, sha1, st, modifier, path, new_path); } static void remove_from_changeset_recursive (ChangeSet *changeset, const char *path, gboolean remove_parent, const char *top_dir) { ChangeSetDirent *dent; gboolean parent_empty = FALSE; dent = delete_from_tree (changeset, path, &parent_empty); changeset_dirent_free (dent); if (remove_parent && parent_empty) { char *parent = g_strdup(path); char *slash = strrchr (parent, '/'); if (slash) { *slash = '\0'; if (strlen(parent) >= strlen(top_dir)) { /* Recursively remove parent dirs. */ remove_from_changeset_recursive (changeset, parent, remove_parent, top_dir); } } g_free (parent); } } void remove_from_changeset (ChangeSet *changeset, char status, const char *path, gboolean remove_parent, const char *top_dir, gboolean add_to_diff) { DiffEntry *de; unsigned char allzero[20] = {0}; if (add_to_diff) { de = diff_entry_new (DIFF_TYPE_INDEX, status, allzero, path); changeset->diff = g_list_prepend (changeset->diff, de); } remove_from_changeset_recursive (changeset, path, remove_parent, top_dir); } static char * commit_tree_recursive (const char *repo_id, ChangeSetDir *dir, gint64 *new_mtime) { ChangeSetDirent *dent; GHashTableIter iter; gpointer key, value; char *new_id; gint64 subdir_new_mtime; gint64 dir_mtime = 0; SeafDir *seaf_dir; char *ret = NULL; g_hash_table_iter_init (&iter, dir->dents); while (g_hash_table_iter_next (&iter, &key, &value)) { dent = value; if (dent->subdir) { new_id = commit_tree_recursive (repo_id, dent->subdir, &subdir_new_mtime); if (!new_id) return NULL; memcpy (dent->id, new_id, 40); dent->mtime = subdir_new_mtime; g_free (new_id); } if (dir_mtime < dent->mtime) dir_mtime = dent->mtime; } seaf_dir = changeset_dir_to_seaf_dir (dir); memcpy (dir->dir_id, seaf_dir->dir_id, 40); if (!seaf_fs_manager_object_exists (seaf->fs_mgr, repo_id, dir->version, seaf_dir->dir_id)) { if (seaf_dir_save (seaf->fs_mgr, repo_id, dir->version, seaf_dir) < 0) { seaf_warning ("Failed to save dir object %s to repo %s.\n", seaf_dir->dir_id, repo_id); goto out; } } ret = g_strdup(seaf_dir->dir_id); out: if (ret != NULL) *new_mtime = dir_mtime; seaf_dir_free (seaf_dir); return ret; } /* * This function does two things: * - calculate dir id from bottom up; * - create and save seaf dir objects. * It returns root dir id of the new commit. */ char * commit_tree_from_changeset (ChangeSet *changeset) { gint64 mtime; char *root_id = commit_tree_recursive (changeset->repo_id, changeset->tree_root, &mtime); return root_id; } gboolean changeset_check_path (ChangeSet *changeset, const char *path, unsigned char *sha1, guint32 mode, gint64 mtime) { ChangeSetDir *root = changeset->tree_root; char **parts, *dname; int n, i; ChangeSetDir *dir; ChangeSetDirent *dent; gboolean ret = FALSE; char id[41]; rawdata_to_hex (sha1, id, 20); parts = g_strsplit (path, "/", 0); n = g_strv_length(parts); dir = root; for (i = 0; i < n; i++) { dname = parts[i]; dent = g_hash_table_lookup (dir->dents, dname); if (!dent) { seaf_message ("Changeset mismatch: path component %s of %s not found\n", dname, path); break; } if (S_ISDIR(dent->mode)) { if (i == (n-1)) { if (dent->mode != mode) { seaf_message ("Changeset mismatch: %s is not a dir\n", path); break; } else if (strcmp (dent->id, EMPTY_SHA1) != 0) { seaf_message ("Changeset mismatch: %s is not a empty dir\n", path); break; } ret = TRUE; break; } if (!dent->subdir) { seaf_message ("Changeset mismatch: path component %s of %s is not in changeset\n", dname, path); break; } dir = dent->subdir; } else if (S_ISREG(dent->mode)) { if (i == (n-1)) { if (dent->mode != mode) { seaf_message ("Changeset mismatch: %s mode mismatch, " "index: %u, changeset: %u\n", path, mode, dent->mode); break; } else if (dent->mtime != mtime) { seaf_message ("Changeset mismatch: %s mtime mismatch, " "index: %"G_GINT64_FORMAT ", changeset: %"G_GINT64_FORMAT"\n", path, mtime, dent->mtime); break; } else if (strcmp (dent->id, id) != 0) { seaf_message ("Changeset mismatch: %s id mismatch, " "index: %s, changeset: %s\n", path, id, dent->id); break; } ret = TRUE; break; } /* We find a file in the middle of the path, this is invalid. */ seaf_message ("Changeset mismatch: path component %s of %s is a file\n", dname, path); break; } } g_strfreev (parts); return ret; } seafile-6.1.5/daemon/change-set.h000066400000000000000000000027371323477647300166160ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_CHANGE_SET_H #define SEAF_CHANGE_SET_H #include #include "utils.h" struct _ChangeSetDir; struct _ChangeSet { char repo_id[37]; /* List of diff entries, used to generate commit description. */ GList *diff; /* A partial tree for all changed directories. */ struct _ChangeSetDir *tree_root; /* Used to match case conflict paths. */ GRegex *case_conflict_pattern; }; typedef struct _ChangeSet ChangeSet; ChangeSet * changeset_new (const char *repo_id); void changeset_free (ChangeSet *changeset); void add_to_changeset (ChangeSet *changeset, char status, unsigned char *sha1, SeafStat *st, const char *modifier, const char *path, const char *new_path); /* @remove_parent: remove the parent dir when it becomes empty. */ void remove_from_changeset (ChangeSet *changeset, char status, const char *path, gboolean remove_parent, const char *top_dir, gboolean add_to_diff); char * commit_tree_from_changeset (ChangeSet *changeset); gboolean changeset_check_path (ChangeSet *changeset, const char *path, unsigned char *sha1, guint32 mode, gint64 mtime); #endif seafile-6.1.5/daemon/clone-mgr.c000066400000000000000000002270451323477647300164570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" #include "seafile-error.h" #include "seafile-session.h" #include "index/index.h" #include "merge-recursive.h" #include "unpack-trees.h" #include "vc-utils.h" #include "utils.h" #include "seafile-config.h" #include "processors/checkff-proc.h" #define CLONE_DB "clone.db" #define CHECK_CONNECT_INTERVAL 5 static void on_repo_fetched (SeafileSession *seaf, TransferTask *tx_task, SeafCloneManager *mgr); static void on_repo_http_fetched (SeafileSession *seaf, HttpTxTask *tx_task, SeafCloneManager *mgr); static void on_checkout_done (CheckoutTask *task, SeafRepo *repo, void *data); static int start_index_or_transfer (SeafCloneManager *mgr, CloneTask *task, GError **error); static void start_connect_task_relay (CloneTask *task, GError **error); static void start_checkout (SeafRepo *repo, CloneTask *task); static void transition_state (CloneTask *task, int new_state); static void transition_to_error (CloneTask *task, int error); static int add_transfer_task (CloneTask *task, GError **error); static const char *state_str[] = { "init", "check server", "fetch", "done", "error", "canceling", "canceled", /* States only used by old protocol. */ "connect", "connect", /* Use "connect" for CHECK_PROTOCOL */ "index", "checkout", "merge", }; static const char *error_str[] = { "ok", "check server", "index", "fetch", "password", "checkout", "merge", "internal", }; static void start_clone (CloneTask *task) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (!repo) start_index_or_transfer (task->manager, task, NULL); else if (repo->head == NULL) start_checkout (repo, task); } static void mark_clone_done_v2 (SeafRepo *repo, CloneTask *task) { SeafBranch *local = NULL; seaf_repo_manager_set_repo_worktree (repo->manager, repo, task->worktree); local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("Cannot get branch local for repo %s(%.10s).\n", repo->name, repo->id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } /* Set repo head to mark checkout done. */ seaf_repo_set_head (repo, local); seaf_branch_unref (local); if (repo->encrypted) { if (seaf_repo_manager_set_repo_passwd (seaf->repo_mgr, repo, task->passwd) < 0) { seaf_warning ("[Clone mgr] failed to set passwd for %s.\n", repo->id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } } if (task->is_readonly) { seaf_repo_set_readonly (repo); } if (task->sync_wt_name) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_SYNC_WORKTREE_NAME, "true"); } if (task->server_url) repo->server_url = g_strdup(task->server_url); if (repo->auto_sync && (repo->sync_interval == 0)) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s(%.10s).\n", repo->name, repo->id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } } /* For compatibility, still set these two properties. * So that if we downgrade to an old version, the syncing can still work. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD, repo->head->commit_id); seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD, repo->head->commit_id); transition_state (task, CLONE_STATE_DONE); } static void start_clone_v2 (CloneTask *task) { GError *error = NULL; if (g_access (task->worktree, F_OK) != 0 && g_mkdir_with_parents (task->worktree, 0777) < 0) { seaf_warning ("[clone mgr] Failed to create worktree %s.\n", task->worktree); transition_to_error (task, CLONE_ERROR_FETCH); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (repo != NULL) { seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); seaf_repo_manager_set_repo_relay_id (seaf->repo_mgr, repo, task->peer_id); if (task->server_url) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_SERVER_URL, task->server_url); } mark_clone_done_v2 (repo, task); return; } if (add_transfer_task (task, &error) == 0) transition_state (task, CLONE_STATE_FETCH); else transition_to_error (task, CLONE_ERROR_FETCH); } static void check_protocol_done_cb (CcnetProcessor *processor, gboolean success, void *data) { CloneTask *task = data; if (success) task->server_side_merge = TRUE; else if (processor->failure == PROC_NO_SERVICE) /* Talking to an old server. */ task->server_side_merge = FALSE; if (task->server_side_merge) start_clone_v2 (task); else start_clone (task); } static int start_check_protocol_proc (const char *peer_id, CloneTask *task) { CcnetProcessor *processor; if (task->repo_version == 0) { task->server_side_merge = FALSE; start_clone (task); return 0; } processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-check-protocol", peer_id); if (!processor) { seaf_warning ("failed to create seafile-check-protocol proc.\n"); return -1; } if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start seafile-check-protocol proc.\n"); return -1; } g_signal_connect (processor, "done", (GCallback)check_protocol_done_cb, task); transition_state (task, CLONE_STATE_CHECK_PROTOCOL); return 0; } static void start_connect_task_relay (CloneTask *task, GError **error) { CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, task->peer_id); if (!peer) { /* clone from a new relay */ GString *buf = NULL; seaf_message ("add relay before clone, %s:%s\n", task->peer_addr, task->peer_port); buf = g_string_new(NULL); g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", task->peer_id, task->peer_addr, task->peer_port); ccnet_send_command (seaf->session, buf->str, NULL, NULL); transition_state (task, CLONE_STATE_CONNECT); g_string_free (buf, TRUE); } else { /* The peer is added to ccnet already and will be connected, * only need to transition the state */ transition_state (task, CLONE_STATE_CONNECT); } if (peer) g_object_unref (peer); } static void connect_non_http_server (CloneTask *task) { if (!ccnet_peer_is_ready (seaf->ccnetrpc_client, task->peer_id)) start_connect_task_relay (task, NULL); else start_check_protocol_proc (task->peer_id, task); } static void check_head_commit_done (HttpHeadCommit *result, void *user_data) { CloneTask *task = user_data; if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); return; } if (result->check_success && !result->is_corrupt && !result->is_deleted) { memcpy (task->server_head_id, result->head_commit, 40); start_clone_v2 (task); } else { transition_to_error (task, CLONE_ERROR_CHECK_SERVER); if (result->error_code != 0) task->err_detail = g_strdup(http_task_error_str(result->error_code)); } } static void http_check_head_commit (CloneTask *task) { int ret = http_tx_manager_check_head_commit (seaf->http_tx_mgr, task->repo_id, task->repo_version, task->effective_url, task->token, task->use_fileserver_port, check_head_commit_done, task); if (ret < 0) transition_to_error (task, CLONE_ERROR_CHECK_SERVER); } static char * http_fileserver_url (const char *url) { const char *host; char *colon; char *url_no_port; char *ret = NULL; /* Just return the url itself if it's invalid. */ if (strlen(url) <= strlen("http://")) return g_strdup(url); /* Skip protocol schem. */ host = url + strlen("http://"); colon = strrchr (host, ':'); if (colon) { url_no_port = g_strndup(url, colon - url); ret = g_strconcat(url_no_port, ":8082", NULL); g_free (url_no_port); } else { ret = g_strconcat(url, ":8082", NULL); } return ret; } static void check_http_fileserver_protocol_done (HttpProtocolVersion *result, void *user_data) { CloneTask *task = user_data; if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); return; } if (result->check_success && !result->not_supported) { task->http_protocol_version = result->version; task->effective_url = http_fileserver_url (task->server_url); task->use_fileserver_port = TRUE; task->http_sync = TRUE; http_check_head_commit (task); } else { /* Wait for periodic retry. */ transition_to_error (task, CLONE_ERROR_CHECK_SERVER); if (result->error_code != 0) task->err_detail = g_strdup(http_task_error_str(result->error_code)); } } static void check_http_protocol_done (HttpProtocolVersion *result, void *user_data) { CloneTask *task = user_data; if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); return; } if (result->check_success && !result->not_supported) { task->http_protocol_version = result->version; task->effective_url = g_strdup(task->server_url); task->http_sync = TRUE; http_check_head_commit (task); } else if (strncmp(task->server_url, "https", 5) != 0) { char *host_fileserver = http_fileserver_url(task->server_url); if (http_tx_manager_check_protocol_version (seaf->http_tx_mgr, host_fileserver, TRUE, check_http_fileserver_protocol_done, task) < 0) transition_to_error (task, CLONE_ERROR_CHECK_SERVER); g_free (host_fileserver); } else { /* Wait for periodic retry. */ transition_to_error (task, CLONE_ERROR_CHECK_SERVER); if (result->error_code != 0) task->err_detail = g_strdup(http_task_error_str(result->error_code)); } } static void check_http_protocol (CloneTask *task) { if (http_tx_manager_check_protocol_version (seaf->http_tx_mgr, task->server_url, FALSE, check_http_protocol_done, task) < 0) { transition_to_error (task, CLONE_ERROR_CHECK_SERVER); return; } transition_state (task, CLONE_STATE_CHECK_SERVER); } static CloneTask * clone_task_new (const char *repo_id, const char *peer_id, const char *repo_name, const char *token, const char *worktree, const char *passwd, const char *peer_addr, const char *peer_port, const char *email) { CloneTask *task = g_new0 (CloneTask, 1); memcpy (task->repo_id, repo_id, 37); memcpy (task->peer_id, peer_id, 41); task->token = g_strdup (token); task->worktree = g_strdup(worktree); task->peer_addr = g_strdup(peer_addr); task->peer_port = g_strdup(peer_port); task->email = g_strdup(email); if (repo_name) task->repo_name = g_strdup(repo_name); if (passwd) task->passwd = g_strdup (passwd); return task; } static void clone_task_free (CloneTask *task) { g_free (task->tx_id); g_free (task->worktree); g_free (task->passwd); g_free (task->token); g_free (task->repo_name); g_free (task->peer_addr); g_free (task->peer_port); g_free (task->email); g_free (task->random_key); g_free (task->server_url); g_free (task->effective_url); g_free (task->err_detail); g_free (task); } const char * clone_task_state_to_str (int state) { if (state < 0 || state >= N_CLONE_STATES) return NULL; return state_str[state]; } const char * clone_task_error_to_str (int error) { if (error < 0 || error >= N_CLONE_ERRORS) return NULL; return error_str[error]; } SeafCloneManager * seaf_clone_manager_new (SeafileSession *session) { SeafCloneManager *mgr = g_new0 (SeafCloneManager, 1); char *db_path = g_build_path ("/", session->seaf_dir, CLONE_DB, NULL); if (sqlite_open_db (db_path, &mgr->db) < 0) { g_critical ("[Clone mgr] Failed to open db\n"); g_free (db_path); g_free (mgr); return NULL; } mgr->seaf = session; mgr->tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)clone_task_free); return mgr; } static gboolean load_enc_info_cb (sqlite3_stmt *stmt, void *data) { CloneTask *task = data; int enc_version; const char *random_key; enc_version = sqlite3_column_int (stmt, 0); random_key = (const char *)sqlite3_column_text (stmt, 1); task->enc_version = enc_version; task->random_key = g_strdup (random_key); return FALSE; } static int load_clone_enc_info (CloneTask *task) { char sql[256]; snprintf (sql, sizeof(sql), "SELECT enc_version, random_key FROM CloneEncInfo WHERE repo_id='%s'", task->repo_id); if (sqlite_foreach_selected_row (task->manager->db, sql, load_enc_info_cb, task) < 0) return -1; return 0; } static gboolean load_version_info_cb (sqlite3_stmt *stmt, void *data) { CloneTask *task = data; int repo_version; repo_version = sqlite3_column_int (stmt, 0); task->repo_version = repo_version; return FALSE; } static void load_clone_repo_version_info (CloneTask *task) { char sql[256]; snprintf (sql, sizeof(sql), "SELECT repo_version FROM CloneVersionInfo WHERE repo_id='%s'", task->repo_id); sqlite_foreach_selected_row (task->manager->db, sql, load_version_info_cb, task); } static gboolean load_more_info_cb (sqlite3_stmt *stmt, void *data) { CloneTask *task = data; json_error_t jerror; json_t *object = NULL; const char *more_info; more_info = (const char *)sqlite3_column_text (stmt, 0); object = json_loads (more_info, 0, &jerror); if (!object) { seaf_warning ("Failed to load more sync info from json: %s.\n", jerror.text); return FALSE; } json_t *integer = json_object_get (object, "is_readonly"); task->is_readonly = json_integer_value (integer); json_t *string = json_object_get (object, "server_url"); if (string) task->server_url = g_strdup (json_string_value (string)); json_decref (object); return FALSE; } static void load_clone_more_info (CloneTask *task) { char sql[256]; snprintf (sql, sizeof(sql), "SELECT more_info FROM CloneTasksMoreInfo WHERE repo_id='%s'", task->repo_id); sqlite_foreach_selected_row (task->manager->db, sql, load_more_info_cb, task); } static gboolean restart_task (sqlite3_stmt *stmt, void *data) { SeafCloneManager *mgr = data; const char *repo_id, *repo_name, *token, *peer_id, *worktree, *passwd; const char *peer_addr, *peer_port, *email; CloneTask *task; SeafRepo *repo; repo_id = (const char *)sqlite3_column_text (stmt, 0); repo_name = (const char *)sqlite3_column_text (stmt, 1); token = (const char *)sqlite3_column_text (stmt, 2); peer_id = (const char *)sqlite3_column_text (stmt, 3); worktree = (const char *)sqlite3_column_text (stmt, 4); passwd = (const char *)sqlite3_column_text (stmt, 5); peer_addr = (const char *)sqlite3_column_text (stmt, 6); peer_port = (const char *)sqlite3_column_text (stmt, 7); email = (const char *)sqlite3_column_text (stmt, 8); task = clone_task_new (repo_id, peer_id, repo_name, token, worktree, passwd, peer_addr, peer_port, email); task->manager = mgr; /* Default to 1. */ task->enc_version = 1; if (passwd && load_clone_enc_info (task) < 0) { clone_task_free (task); return TRUE; } task->repo_version = 0; load_clone_repo_version_info (task); load_clone_more_info (task); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { transition_state (task, CLONE_STATE_DONE); return TRUE; } if (task->repo_version > 0) { if (task->server_url) { check_http_protocol (task); } else { transition_to_error (task, CLONE_ERROR_CHECK_SERVER); return TRUE; } } else { connect_non_http_server (task); } g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); return TRUE; } int seaf_clone_manager_init (SeafCloneManager *mgr) { const char *sql; sql = "CREATE TABLE IF NOT EXISTS CloneTasks " "(repo_id TEXT PRIMARY KEY, repo_name TEXT, " "token TEXT, dest_id TEXT," "worktree_parent TEXT, passwd TEXT, " "server_addr TEXT, server_port TEXT, email TEXT);"; if (sqlite_query_exec (mgr->db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS CloneTasksMoreInfo " "(repo_id TEXT PRIMARY KEY, more_info TEXT);"; if (sqlite_query_exec (mgr->db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS CloneEncInfo " "(repo_id TEXT PRIMARY KEY, enc_version INTEGER, random_key TEXT);"; if (sqlite_query_exec (mgr->db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS CloneVersionInfo " "(repo_id TEXT PRIMARY KEY, repo_version INTEGER);"; if (sqlite_query_exec (mgr->db, sql) < 0) return -1; sql = "CREATE TABLE IF NOT EXISTS CloneServerURL " "(repo_id TEXT PRIMARY KEY, server_url TEXT);"; if (sqlite_query_exec (mgr->db, sql) < 0) return -1; return 0; } static void continue_task_when_peer_connected (CloneTask *task) { if (ccnet_peer_is_ready (seaf->ccnetrpc_client, task->peer_id)) start_check_protocol_proc (task->peer_id, task); } static int check_connect_pulse (void *vmanager) { SeafCloneManager *mgr = vmanager; CloneTask *task; GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, mgr->tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (task->state == CLONE_STATE_ERROR && task->repo_version > 0) { g_free (task->err_detail); task->err_detail = NULL; task->error = 0; check_http_protocol (task); } else if (task->state == CLONE_STATE_CONNECT) { continue_task_when_peer_connected (task); } } return TRUE; } int seaf_clone_manager_start (SeafCloneManager *mgr) { ccnet_proc_factory_register_processor (seaf->session->proc_factory, "seafile-checkff", SEAFILE_TYPE_CHECKFF_PROC); mgr->check_timer = ccnet_timer_new (check_connect_pulse, mgr, CHECK_CONNECT_INTERVAL * 1000); char *sql = "SELECT * FROM CloneTasks"; if (sqlite_foreach_selected_row (mgr->db, sql, restart_task, mgr) < 0) return -1; g_signal_connect (seaf, "repo-fetched", (GCallback)on_repo_fetched, mgr); g_signal_connect (seaf, "repo-http-fetched", (GCallback)on_repo_http_fetched, mgr); return 0; } static int save_task_to_db (SeafCloneManager *mgr, CloneTask *task) { char *sql; if (task->passwd) sql = sqlite3_mprintf ("REPLACE INTO CloneTasks VALUES " "('%q', '%q', '%q', '%q', '%q', '%q', '%q', '%q', '%q')", task->repo_id, task->repo_name, task->token, task->peer_id, task->worktree, task->passwd, task->peer_addr, task->peer_port, task->email); else sql = sqlite3_mprintf ("REPLACE INTO CloneTasks VALUES " "('%q', '%q', '%q', '%q', '%q', NULL, '%q', '%q', '%q')", task->repo_id, task->repo_name, task->token, task->peer_id, task->worktree, task->peer_addr, task->peer_port, task->email); if (sqlite_query_exec (mgr->db, sql) < 0) { sqlite3_free (sql); return -1; } sqlite3_free (sql); if (task->passwd && task->enc_version == 2 && task->random_key) { sql = sqlite3_mprintf ("REPLACE INTO CloneEncInfo VALUES " "('%q', %d, '%q')", task->repo_id, task->enc_version, task->random_key); if (sqlite_query_exec (mgr->db, sql) < 0) { sqlite3_free (sql); return -1; } sqlite3_free (sql); } sql = sqlite3_mprintf ("REPLACE INTO CloneVersionInfo VALUES " "('%q', %d)", task->repo_id, task->repo_version); if (sqlite_query_exec (mgr->db, sql) < 0) { sqlite3_free (sql); return -1; } sqlite3_free (sql); if (task->is_readonly || task->server_url) { /* need to store more info */ json_t *object = NULL; gchar *info = NULL; object = json_object (); json_object_set_new (object, "is_readonly", json_integer (task->is_readonly)); if (task->server_url) json_object_set_new (object, "server_url", json_string(task->server_url)); info = json_dumps (object, 0); json_decref (object); sql = sqlite3_mprintf ("REPLACE INTO CloneTasksMoreInfo VALUES " "('%q', '%q')", task->repo_id, info); if (sqlite_query_exec (mgr->db, sql) < 0) { sqlite3_free (sql); g_free (info); return -1; } sqlite3_free (sql); g_free (info); } return 0; } static int remove_task_from_db (SeafCloneManager *mgr, const char *repo_id) { char sql[256]; snprintf (sql, sizeof(sql), "DELETE FROM CloneTasks WHERE repo_id='%s'", repo_id); if (sqlite_query_exec (mgr->db, sql) < 0) return -1; snprintf (sql, sizeof(sql), "DELETE FROM CloneEncInfo WHERE repo_id='%s'", repo_id); if (sqlite_query_exec (mgr->db, sql) < 0) return -1; snprintf (sql, sizeof(sql), "DELETE FROM CloneVersionInfo WHERE repo_id='%s'", repo_id); if (sqlite_query_exec (mgr->db, sql) < 0) return -1; snprintf (sql, sizeof(sql), "DELETE FROM CloneTasksMoreInfo WHERE repo_id='%s'", repo_id); if (sqlite_query_exec (mgr->db, sql) < 0) return -1; return 0; } static void transition_state (CloneTask *task, int new_state) { seaf_message ("Transition clone state for %.8s from [%s] to [%s].\n", task->repo_id, state_str[task->state], state_str[new_state]); if (new_state == CLONE_STATE_DONE || new_state == CLONE_STATE_CANCELED) { /* Remove from db but leave in memory. */ remove_task_from_db (task->manager, task->repo_id); } task->state = new_state; } static void transition_to_error (CloneTask *task, int error) { seaf_message ("Transition clone state for %.8s from [%s] to [error]: %s.\n", task->repo_id, state_str[task->state], error_str[error]); task->state = CLONE_STATE_ERROR; task->error = error; } static int add_transfer_task (CloneTask *task, GError **error) { if (!task->http_sync) { task->tx_id = seaf_transfer_manager_add_download (seaf->transfer_mgr, task->repo_id, task->repo_version, task->peer_id, "fetch_head", "master", task->token, task->server_side_merge, task->passwd, task->worktree, task->email, error); if (!task->tx_id) return -1; } else { int ret = http_tx_manager_add_download (seaf->http_tx_mgr, task->repo_id, task->repo_version, task->effective_url, task->token, task->server_head_id, TRUE, task->passwd, task->worktree, task->http_protocol_version, task->email, task->use_fileserver_port, task->repo_name, error); if (ret < 0) return -1; task->tx_id = g_strdup(task->repo_id); } return 0; } typedef struct { CloneTask *task; gboolean success; } IndexAux; static void * index_files_job (void *data) { IndexAux *aux = data; CloneTask *task = aux->task; if (seaf_repo_index_worktree_files (task->repo_id, task->repo_version, task->email, task->worktree, task->passwd, task->enc_version, task->random_key, task->root_id) == 0) aux->success = TRUE; return data; } static void index_files_done (void *result) { IndexAux *aux = result; CloneTask *task = aux->task; if (!aux->success) { transition_to_error (task, CLONE_ERROR_INDEX); goto out; } if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); goto out; } if (add_transfer_task (task, NULL) < 0) { transition_to_error (task, CLONE_ERROR_FETCH); goto out; } transition_state (task, CLONE_STATE_FETCH); out: g_free (aux); return; } #ifndef WIN32 static gboolean is_non_empty_directory (const char *path) { GDir *dir; GError *error = NULL; gboolean ret = FALSE; dir = g_dir_open (path, 0, &error); if (dir != NULL && g_dir_read_name (dir) != NULL) ret = TRUE; if (dir) g_dir_close (dir); return ret; } #else static int check_empty_cb (wchar_t *parent, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { gboolean *res = user_data; *res = TRUE; *stop = TRUE; return 0; } static gboolean is_non_empty_directory (const char *path) { wchar_t *wpath = win32_long_path (path); gboolean ret = FALSE; traverse_directory_win32 (wpath, check_empty_cb, &ret); return ret; } #endif /* WIN32 */ static int start_index_or_transfer (SeafCloneManager *mgr, CloneTask *task, GError **error) { IndexAux *aux; int ret = 0; if (is_non_empty_directory (task->worktree)) { transition_state (task, CLONE_STATE_INDEX); aux = g_new0 (IndexAux, 1); aux->task = task; ccnet_job_manager_schedule_job (seaf->job_mgr, index_files_job, index_files_done, aux); } else { ret = add_transfer_task (task, error); if (ret == 0) transition_state (task, CLONE_STATE_FETCH); else transition_to_error (task, CLONE_ERROR_FETCH); } return ret; } static gboolean is_duplicate_task (SeafCloneManager *mgr, const char *repo_id) { CloneTask *task = g_hash_table_lookup (mgr->tasks, repo_id); if (task != NULL && task->state != CLONE_STATE_DONE && task->state != CLONE_STATE_CANCELED) return TRUE; return FALSE; } static gboolean is_worktree_of_repo (SeafCloneManager *mgr, const char *path) { GList *repos, *ptr; SeafRepo *repo; GHashTableIter iter; gpointer key, value; CloneTask *task; repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, -1, -1); for (ptr = repos; ptr != NULL; ptr = ptr->next) { repo = ptr->data; if (g_strcmp0 (path, repo->worktree) == 0) { g_list_free (repos); return TRUE; } } g_list_free (repos); g_hash_table_iter_init (&iter, mgr->tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (task->state == CLONE_STATE_DONE || task->state == CLONE_STATE_CANCELED) continue; if (g_strcmp0 (path, task->worktree) == 0) return TRUE; } return FALSE; } static char * try_worktree (const char *worktree) { char *tmp; unsigned int cnt; /* There is a repo name conflict, so we try to add a postfix */ cnt = 1; while (1) { tmp = g_strdup_printf("%s-%d", worktree, cnt++); if (g_access(tmp, F_OK) < 0) { return tmp; } if (cnt == -1U) { /* we have tried too much times, so give up */ g_free(tmp); return NULL; } g_free(tmp); } /* XXX: never reach here */ } static inline void remove_trail_slash (char *path) { int tail = strlen (path) - 1; while (tail >= 0 && (path[tail] == '/' || path[tail] == '\\')) path[tail--] = '\0'; } static char * make_worktree (SeafCloneManager *mgr, const char *worktree, gboolean dry_run, GError **error) { char *wt = g_strdup (worktree); SeafStat st; int rc; char *ret; remove_trail_slash (wt); rc = seaf_stat (wt, &st); if (rc < 0) { ret = wt; return ret; } else if (!S_ISDIR(st.st_mode)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Invalid local directory"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); return ret; } /* OK, wt is an existing dir. Let's see if it's the worktree for * another repo. */ if (is_worktree_of_repo (mgr, wt)) { if (!dry_run) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Already in sync"); g_free (wt); return NULL; } ret = try_worktree (wt); g_free (wt); } else { return wt; } return ret; } /* * Generate a conflict-free path to be used as worktree. * This worktree path can be used as the @worktree parameter * for seaf_clone_manager_add_task(). */ char * seaf_clone_manager_gen_default_worktree (SeafCloneManager *mgr, const char *worktree_parent, const char *repo_name) { char *wt = g_build_filename (worktree_parent, repo_name, NULL); char *worktree; worktree = make_worktree (mgr, wt, TRUE, NULL); if (!worktree) return wt; g_free (wt); return worktree; } inline static gboolean is_separator (char c) { return (c == '/' || c == '\\'); } /* * Returns < 0 if dira includes dirb or dira == dirb; * Returns 0 if no inclusive relationship; * Returns > 0 if dirb includes dira. */ static int check_dir_inclusiveness (const char *dira, const char *dirb) { char *a, *b; char *p1, *p2; int ret = 0; a = g_strdup(dira); b = g_strdup(dirb); remove_trail_slash (a); remove_trail_slash (b); p1 = a; p2 = b; while (*p1 != 0 && *p2 != 0) { /* Go to the last one in a path separator sequence. */ while (is_separator(*p1) && is_separator(p1[1])) ++p1; while (is_separator(*p2) && is_separator(p2[1])) ++p2; if (!(is_separator(*p1) && is_separator(*p2)) && *p1 != *p2) goto out; ++p1; ++p2; } /* Example: * p1 * a: /abc/def/ghi * p2 * b: /abc/def */ if (*p1 == 0 && *p2 == 0) ret = -1; else if (*p1 != 0 && is_separator(*p1)) ret = 1; else if (*p2 != 0 && is_separator(*p2)) ret = -1; out: g_free (a); g_free (b); return ret; } gboolean seaf_clone_manager_check_worktree_path (SeafCloneManager *mgr, const char *path, GError **error) { GList *repos, *ptr; SeafRepo *repo; GHashTableIter iter; gpointer key, value; CloneTask *task; if (check_dir_inclusiveness (path, seaf->seaf_dir) != 0 || /* It's OK if path is included by the default worktree parent. */ check_dir_inclusiveness (path, seaf->worktree_dir) < 0 || check_dir_inclusiveness (path, seaf->session->config_dir) != 0) { seaf_warning ("Worktree path conflicts with seafile system path.\n"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Worktree conflicts system path"); return FALSE; } repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, -1, -1); for (ptr = repos; ptr != NULL; ptr = ptr->next) { repo = ptr->data; if (repo->worktree != NULL && check_dir_inclusiveness (path, repo->worktree) != 0) { seaf_warning ("Worktree path conflict with repo %s.\n", repo->name); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Worktree conflicts existing repo"); g_list_free (repos); return FALSE; } } g_list_free (repos); g_hash_table_iter_init (&iter, mgr->tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (task->state == CLONE_STATE_DONE || task->state == CLONE_STATE_CANCELED) continue; if (check_dir_inclusiveness (path, task->worktree) != 0) { seaf_warning ("Worktree path conflict with clone %.8s.\n", task->repo_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Worktree conflicts existing repo"); return FALSE; } } return TRUE; } static char * canonical_server_url (const char *url_in) { char *url = g_strdup(url_in); int len = strlen(url); if (url[len - 1] == '/') url[len - 1] = 0; return url; } static char * add_task_common (SeafCloneManager *mgr, const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *token, const char *passwd, int enc_version, const char *random_key, const char *worktree, const char *peer_addr, const char *peer_port, const char *email, const char *more_info, gboolean sync_wt_name, GError **error) { CloneTask *task; task = clone_task_new (repo_id, peer_id, repo_name, token, worktree, passwd, peer_addr, peer_port, email); task->manager = mgr; task->enc_version = enc_version; task->random_key = g_strdup (random_key); task->repo_version = repo_version; task->sync_wt_name = sync_wt_name; if (more_info) { json_error_t jerror; json_t *object = NULL; object = json_loads (more_info, 0, &jerror); if (!object) { seaf_warning ("Failed to load more sync info from json: %s.\n", jerror.text); clone_task_free (task); return NULL; } json_t *integer = json_object_get (object, "is_readonly"); task->is_readonly = json_integer_value (integer); json_t *string = json_object_get (object, "server_url"); if (string) task->server_url = canonical_server_url (json_string_value (string)); json_decref (object); } if (save_task_to_db (mgr, task) < 0) { seaf_warning ("[Clone mgr] failed to save task.\n"); clone_task_free (task); return NULL; } if (task->repo_version > 0) { if (task->server_url) { check_http_protocol (task); } else { clone_task_free (task); return NULL; } } else { connect_non_http_server (task); } /* The old task for this repo will be freed. */ g_hash_table_insert (mgr->tasks, g_strdup(task->repo_id), task); return g_strdup(repo_id); } static gboolean check_encryption_args (const char *magic, int enc_version, const char *random_key, GError **error) { if (!magic) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Magic must be specified"); return FALSE; } if (enc_version != 1 && enc_version != 2) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Unsupported enc version"); return FALSE; } if (enc_version == 2) { if (!random_key || strlen(random_key) != 96) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Random key not specified"); return FALSE; } } return TRUE; } static gboolean is_wt_repo_name_same (const char *worktree, const char *repo_name) { char *basename = g_path_get_basename (worktree); gboolean ret = FALSE; ret = (strcmp (basename, repo_name) == 0); g_free (basename); return ret; } char * seaf_clone_manager_add_task (SeafCloneManager *mgr, const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *magic, int enc_version, const char *random_key, const char *worktree_in, const char *peer_addr, const char *peer_port, const char *email, const char *more_info, GError **error) { SeafRepo *repo; char *worktree; char *ret; gboolean sync_wt_name = FALSE; if (!seaf->started) { seaf_message ("System not started, skip adding clone task.\n"); return NULL; } #ifdef USE_GPL_CRYPTO if (repo_version == 0 || (passwd && enc_version < 2)) { seaf_warning ("Don't support syncing old version libraries.\n"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Don't support syncing old version libraries"); return NULL; } #endif if (passwd && !check_encryption_args (magic, enc_version, random_key, error)) return NULL; /* After a repo was unsynced, the sync task may still be blocked in the * network, so the repo is not actually deleted yet. * In this case just return an error to the user. */ SyncInfo *sync_info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); if (sync_info && sync_info->in_sync) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } if (is_duplicate_task (mgr, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } if (passwd && seafile_verify_repo_passwd(repo_id, passwd, magic, enc_version) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return NULL; } if (!seaf_clone_manager_check_worktree_path (mgr, worktree_in, error)) return NULL; /* Return error if worktree_in conflicts with another repo or * is not a directory. */ worktree = make_worktree (mgr, worktree_in, FALSE, error); if (!worktree) { return NULL; } /* Don't sync worktree folder name with library name later if they're not the same * at the beginning. */ sync_wt_name = is_wt_repo_name_same (worktree, repo_name); /* If a repo was unsynced and then downloaded again, there may be * a garbage record for this repo. We don't want the downloaded blocks * be removed by GC. */ if (repo_version > 0) seaf_repo_manager_remove_garbage_repo (seaf->repo_mgr, repo_id); /* Delete orphan information in the db in case the repo was corrupt. */ if (!repo) seaf_repo_manager_remove_repo_ondisk (seaf->repo_mgr, repo_id, FALSE); ret = add_task_common (mgr, repo_id, repo_version, peer_id, repo_name, token, passwd, enc_version, random_key, worktree, peer_addr, peer_port, email, more_info, sync_wt_name, error); g_free (worktree); return ret; } static char * make_worktree_for_download (SeafCloneManager *mgr, const char *wt_tmp, GError **error) { char *worktree; if (g_access (wt_tmp, F_OK) == 0) { worktree = try_worktree (wt_tmp); } else { worktree = g_strdup(wt_tmp); } if (!seaf_clone_manager_check_worktree_path (mgr, worktree, error)) { g_free (worktree); return NULL; } return worktree; } char * seaf_clone_manager_add_download_task (SeafCloneManager *mgr, const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *magic, int enc_version, const char *random_key, const char *wt_parent, const char *peer_addr, const char *peer_port, const char *email, const char *more_info, GError **error) { SeafRepo *repo; char *wt_tmp, *worktree; char *ret; if (!seaf->started) { seaf_message ("System not started, skip adding clone task.\n"); return NULL; } #ifdef USE_GPL_CRYPTO if (repo_version == 0 || (passwd && enc_version < 2)) { seaf_warning ("Don't support syncing old version libraries.\n"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Don't support syncing old version libraries"); return NULL; } #endif if (passwd && !check_encryption_args (magic, enc_version, random_key, error)) return NULL; /* After a repo was unsynced, the sync task may still be blocked in the * network, so the repo is not actually deleted yet. * In this case just return an error to the user. */ SyncInfo *sync_info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo_id); if (sync_info && sync_info->in_sync) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (repo != NULL && repo->head != NULL) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Repo already exists"); return NULL; } if (is_duplicate_task (mgr, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } if (passwd && seafile_verify_repo_passwd(repo_id, passwd, magic, enc_version) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Incorrect password"); return NULL; } IgnoreReason reason; if (should_ignore_on_checkout (repo_name, &reason)) { if (reason == IGNORE_REASON_END_SPACE_PERIOD) g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Library name ends with space or period character"); else g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Library name contains invalid characters such as ':', '*', '|', '?'"); return NULL; } wt_tmp = g_build_filename (wt_parent, repo_name, NULL); worktree = make_worktree_for_download (mgr, wt_tmp, error); if (!worktree) { g_free (wt_tmp); return NULL; } /* If a repo was unsynced and then downloaded again, there may be * a garbage record for this repo. We don't want the downloaded blocks * be removed by GC. */ if (repo_version > 0) seaf_repo_manager_remove_garbage_repo (seaf->repo_mgr, repo_id); /* Delete orphan information in the db in case the repo was corrupt. */ if (!repo) seaf_repo_manager_remove_repo_ondisk (seaf->repo_mgr, repo_id, FALSE); ret = add_task_common (mgr, repo_id, repo_version, peer_id, repo_name, token, passwd, enc_version, random_key, worktree, peer_addr, peer_port, email, more_info, TRUE, error); g_free (worktree); g_free (wt_tmp); return ret; } int seaf_clone_manager_cancel_task (SeafCloneManager *mgr, const char *repo_id) { CloneTask *task; if (!seaf->started) { seaf_message ("System not started, skip canceling clone task.\n"); return -1; } task = g_hash_table_lookup (mgr->tasks, repo_id); if (!task) return -1; switch (task->state) { case CLONE_STATE_INIT: case CLONE_STATE_CONNECT: case CLONE_STATE_ERROR: transition_state (task, CLONE_STATE_CANCELED); break; case CLONE_STATE_CHECK_SERVER: transition_state (task, CLONE_STATE_CANCEL_PENDING); case CLONE_STATE_FETCH: if (!task->http_sync) seaf_transfer_manager_cancel_task (seaf->transfer_mgr, task->tx_id, TASK_TYPE_DOWNLOAD); else http_tx_manager_cancel_task (seaf->http_tx_mgr, task->repo_id, HTTP_TASK_TYPE_DOWNLOAD); transition_state (task, CLONE_STATE_CANCEL_PENDING); break; case CLONE_STATE_INDEX: case CLONE_STATE_CHECKOUT: case CLONE_STATE_MERGE: case CLONE_STATE_CHECK_PROTOCOL: /* We cannot cancel an in-progress checkout, just * wait until it finishes. */ transition_state (task, CLONE_STATE_CANCEL_PENDING); break; case CLONE_STATE_CANCEL_PENDING: break; default: seaf_warning ("[Clone mgr] cannot cancel a not-running task.\n"); return -1; } return 0; } int seaf_clone_manager_remove_task (SeafCloneManager *mgr, const char *repo_id) { CloneTask *task; if (!seaf->started) { seaf_message ("System not started, skip removing clone task.\n"); return -1; } task = g_hash_table_lookup (mgr->tasks, repo_id); if (!task) return -1; if (task->state != CLONE_STATE_DONE && task->state != CLONE_STATE_CANCELED) { seaf_warning ("[Clone mgr] cannot remove running task.\n"); return -1; } if (task->tx_id) seaf_transfer_manager_remove_task (seaf->transfer_mgr, task->tx_id, TASK_TYPE_DOWNLOAD); /* On-disk task should have been removed. */ g_hash_table_remove (mgr->tasks, repo_id); return 0; } CloneTask * seaf_clone_manager_get_task (SeafCloneManager *mgr, const char *repo_id) { return (CloneTask *) g_hash_table_lookup (mgr->tasks, repo_id); } GList * seaf_clone_manager_get_tasks (SeafCloneManager *mgr) { return g_hash_table_get_values (mgr->tasks); } typedef struct { gboolean is_fast_forward; gboolean check_ff_in_thread; CloneTask *task; SeafRepo *repo; gboolean success; } MergeAux; typedef struct { gboolean fast_forward; char root_id[41]; } CompareAux; static gboolean compare_root (SeafCommit *commit, void *data, gboolean *stop) { CompareAux *aux = data; /* If we've found a match in another branch, stop traversing. */ if (aux->fast_forward) { *stop = TRUE; return TRUE; } if (strcmp (commit->root_id, aux->root_id) == 0) { aux->fast_forward = TRUE; *stop = TRUE; } return TRUE; } static gboolean check_fast_forward (SeafCommit *head, const char *root_id) { CompareAux *aux = g_new0 (CompareAux, 1); gboolean ret; memcpy (aux->root_id, root_id, 41); if (!seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, head->repo_id, head->version, head->commit_id, compare_root, aux, FALSE)) { g_free (aux); return FALSE; } ret = aux->fast_forward; g_free (aux); return ret; } #if 0 static int print_index (struct index_state *istate) { int i; struct cache_entry *ce; char id[41]; g_message ("Totally %u entries in index, version %u.\n", istate->cache_nr, istate->version); for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; rawdata_to_hex (ce->sha1, id, 20); g_message ("%s, %s, %o, %"G_GUINT64_FORMAT", %s, %d\n", ce->name, id, ce->ce_mode, ce->ce_mtime.sec, ce->modifier, ce_stage(ce)); } return 0; } #endif static int real_merge (SeafRepo *repo, SeafCommit *head, CloneTask *task) { struct merge_options opts; char index_path[SEAF_PATH_MAX]; struct index_state istate; char *root_id = NULL; int clean; int ret = 0; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", repo->manager->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); return -1; } init_merge_options (&opts); memcpy (opts.repo_id, repo->id, 36); opts.version = repo->version; opts.index = &istate; opts.worktree = task->worktree; opts.ancestor = "common ancestor"; opts.branch1 = seaf->session->base.user_name; opts.branch2 = head->creator_name; opts.remote_head = head->commit_id; /* Don't need to check locked files on windows. */ opts.force_merge = TRUE; if (repo->encrypted) { opts.crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } /* Merge the downloaded branch with the current worktree contents. * EMPTY_SHA1 represents an empty common ancestor tree. */ merge_recursive (&opts, task->root_id, head->root_id, EMPTY_SHA1, &clean, &root_id); g_free (root_id); if (update_index (&istate, index_path) < 0) { seaf_warning ("Failed to update index.\n"); ret = -1; } discard_index (&istate); g_free (opts.crypt); clear_merge_options (&opts); return ret; } static int fast_forward_checkout (SeafRepo *repo, SeafCommit *head, CloneTask *task) { SeafRepoManager *mgr = repo->manager; char index_path[SEAF_PATH_MAX]; struct tree_desc trees[2]; struct unpack_trees_options topts; struct index_state istate; int ret = 0; if (strcmp (head->root_id, task->root_id) == 0) return 0; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); return -1; } repo->index_corrupted = FALSE; fill_tree_descriptor (repo->id, repo->version, &trees[0], task->root_id); fill_tree_descriptor (repo->id, repo->version, &trees[1], head->root_id); memset(&topts, 0, sizeof(topts)); memcpy (topts.repo_id, repo->id, 36); topts.version = repo->version; topts.base = task->worktree; topts.head_idx = -1; topts.src_index = &istate; topts.update = 1; topts.merge = 1; topts.fn = twoway_merge; if (repo->encrypted) { topts.crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } if (unpack_trees (2, trees, &topts) < 0) { seaf_warning ("Failed to merge commit %s with work tree.\n", head->commit_id); ret = -1; goto out; } if (update_worktree (&topts, FALSE, head->commit_id, head->creator_name, NULL) < 0) { seaf_warning ("Failed to update worktree.\n"); /* Still finishe checkout even have I/O errors. */ } discard_index (&istate); istate = topts.result; if (update_index (&istate, index_path) < 0) { seaf_warning ("Failed to update index.\n"); ret = -1; } out: tree_desc_free (&trees[0]); tree_desc_free (&trees[1]); g_free (topts.crypt); discard_index (&istate); return ret; } static int create_index_branch (SeafRepo *repo, const char *root_id) { SeafCommit *commit = NULL; SeafBranch *branch = NULL; int ret = 0; commit = seaf_commit_new (NULL, repo->id, root_id, repo->email ? repo->email : seaf->session->base.user_name, seaf->session->base.id, "Temp commit for index", 0); seaf_repo_to_commit (repo, commit); if (seaf_commit_manager_add_commit (seaf->commit_mgr, commit) < 0) { seaf_warning ("Failed to add commit.\n"); ret = -1; goto out; } branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "index"); if (!branch) { branch = seaf_branch_new ("index", repo->id, commit->commit_id); if (seaf_branch_manager_add_branch (seaf->branch_mgr, branch) < 0) { seaf_warning ("Failed to add branch.\n"); ret = -1; goto out; } } else { seaf_branch_set_commit (branch, commit->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, branch); } out: seaf_commit_unref (commit); seaf_branch_unref (branch); return ret; } static void * merge_job (void *data) { MergeAux *aux = data; CloneTask *task = aux->task; SeafRepo *repo = aux->repo; SeafBranch *local = NULL; SeafCommit *head = NULL; gboolean is_ff; local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { aux->success = FALSE; goto out; } head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, local->commit_id); if (!head) { aux->success = FALSE; goto out; } if (aux->check_ff_in_thread) is_ff = check_fast_forward (head, task->root_id); else is_ff = aux->is_fast_forward; if (is_ff) { seaf_debug ("[clone mgr] Fast forward.\n"); if (fast_forward_checkout (repo, head, task) < 0) goto out; } else { if (real_merge (repo, head, task) < 0) goto out; /* Create a temp branch "index" which references to task->root_id, * so that new changes from the worktree won't be removed by GC. * This branch should be deleted on the first commit operation of * the repo. */ if (create_index_branch (repo, task->root_id) < 0) goto out; } /* Save head id for GC. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD, head->commit_id); seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD, head->commit_id); aux->success = TRUE; out: seaf_branch_unref (local); seaf_commit_unref (head); return aux; } static void merge_job_done (void *data) { MergeAux *aux = data; CloneTask *task = aux->task; SeafRepo *repo = aux->repo; SeafBranch *local = NULL; if (!aux->success) { goto error; } seaf_repo_manager_set_repo_worktree (repo->manager, repo, task->worktree); local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("Cannot get branch local for repo %s(%.10s).\n", repo->name, repo->id); goto error; } /* Set repo head to mark checkout done. */ seaf_repo_set_head (repo, local); seaf_branch_unref (local); if (repo->auto_sync) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s(%.10s).\n", repo->name, repo->id); goto error; } } if (task->state == CLONE_STATE_CANCEL_PENDING) transition_state (task, CLONE_STATE_CANCELED); else if (task->state == CLONE_STATE_MERGE) { transition_state (task, CLONE_STATE_DONE); } g_free (aux); return; error: g_free (aux); transition_to_error (task, CLONE_ERROR_MERGE); return; } static void setup_repo_without_checkout (SeafRepo *repo, SeafBranch *local, CloneTask *task) { if (create_index_branch (repo, task->root_id) < 0) { transition_to_error (task, CLONE_ERROR_MERGE); return; } seaf_repo_manager_set_repo_worktree (repo->manager, repo, task->worktree); /* Set repo head to mark checkout done. */ seaf_repo_set_head (repo, local); if (repo->auto_sync) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s(%.10s).\n", repo->name, repo->id); } } /* Save head id for GC. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD, local->commit_id); seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD, local->commit_id); transition_state (task, CLONE_STATE_DONE); } static void checkff_done (CcnetProcessor *processor, gboolean success, void *data) { SeafileCheckffProc *proc = (SeafileCheckffProc *)processor; CloneTask *task = data; if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", task->repo_id); transition_to_error (task, CLONE_ERROR_MERGE); return; } MergeAux *aux = g_new0 (MergeAux, 1); aux->task = task; aux->repo = repo; /* If checkff proc fails, we're talking to an older server which doesn't support * this processor. In that case transfer manager should have downloaded * all history commits from the server. So we can still check ff locally in the * merge thread. */ if (success) { aux->is_fast_forward = proc->is_fast_forward; aux->check_ff_in_thread = FALSE; } else { aux->is_fast_forward = FALSE; aux->check_ff_in_thread = TRUE; } ccnet_job_manager_schedule_job (seaf->job_mgr, merge_job, merge_job_done, aux); } static int start_checkff_proc (CloneTask *task) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-checkff", task->peer_id); if (!processor) { seaf_warning ("failed to create checkff proc.\n"); return -1; } g_signal_connect (processor, "done", (GCallback)checkff_done, task); if (ccnet_processor_startl (processor, task->repo_id, task->root_id, NULL) < 0) { seaf_warning ("failed to start checkff proc.\n"); return -1; } return 0; } static void index_files_before_merge_done (void *result) { IndexAux *aux = result; CloneTask *task = aux->task; if (!aux->success) { transition_to_error (task, CLONE_ERROR_MERGE); goto out; } if (task->state == CLONE_STATE_CANCEL_PENDING) { transition_state (task, CLONE_STATE_CANCELED); goto out; } if (start_checkff_proc (task) < 0) { transition_to_error (task, CLONE_ERROR_MERGE); goto out; } out: g_free (aux); } static void start_checkout (SeafRepo *repo, CloneTask *task) { if (repo->encrypted && task->passwd != NULL) { if (seaf_repo_manager_set_repo_passwd (seaf->repo_mgr, repo, task->passwd) < 0) { seaf_warning ("[Clone mgr] failed to set passwd for %s.\n", repo->id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } } else if (repo->encrypted) { seaf_warning ("[Clone mgr] Password is empty for encrypted repo %s.\n", repo->id); transition_to_error (task, CLONE_ERROR_PASSWD); return; } if (g_access (task->worktree, F_OK) != 0 && g_mkdir_with_parents (task->worktree, 0777) < 0) { seaf_warning ("[clone mgr] Failed to create worktree %s.\n", task->worktree); transition_to_error (task, CLONE_ERROR_CHECKOUT); return; } SeafBranch *local; SeafCommit *commit; local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("Cannot get branch local for repo %s(%.10s).\n", repo->name, repo->id); transition_to_error (task, CLONE_ERROR_CHECKOUT); return; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, local->commit_id); if (!commit) { seaf_warning ("Failed to get commit %s:%.8s.\n", repo->id, local->commit_id); transition_to_error (task, CLONE_ERROR_CHECKOUT); return; } /* If remote head's tree is empty, we don't need to checkout or merge. * The result would be the current state of worktree anyway. */ if (strcmp (commit->root_id, EMPTY_SHA1) == 0) { setup_repo_without_checkout (repo, local, task); seaf_branch_unref (local); seaf_commit_unref (commit); return; } seaf_branch_unref (local); seaf_commit_unref (commit); if (!is_non_empty_directory (task->worktree)) { transition_state (task, CLONE_STATE_CHECKOUT); seaf_repo_manager_add_checkout_task (seaf->repo_mgr, repo, task->worktree, on_checkout_done, task->manager); } else { transition_state (task, CLONE_STATE_MERGE); if (task->root_id[0] == 0) { /* If the task is restarted, root_id may not be calculated yet. */ IndexAux *aux = g_new0 (IndexAux, 1); aux->task = task; ccnet_job_manager_schedule_job (seaf->job_mgr, index_files_job, index_files_before_merge_done, aux); } else { /* Since we don't have complete history on the client, start a * processor to check if task->root_id exist in the history on the server. * That means there is no change in the worktree after the last unsync. */ if (start_checkff_proc (task) < 0) { transition_to_error (task, CLONE_ERROR_MERGE); return; } } } } static void check_folder_permissions (CloneTask *task); static void on_repo_fetched (SeafileSession *seaf, TransferTask *tx_task, SeafCloneManager *mgr) { CloneTask *task; /* Only handle clone task. */ if (!tx_task->is_clone) return; task = g_hash_table_lookup (mgr->tasks, tx_task->repo_id); g_return_if_fail (task != NULL); if (tx_task->state == TASK_STATE_CANCELED) { /* g_assert (task->state == CLONE_STATE_CANCEL_PENDING); */ transition_state (task, CLONE_STATE_CANCELED); return; } else if (tx_task->state == TASK_STATE_ERROR) { /* transition_to_error (task, CLONE_ERROR_FETCH); */ /* Always restart failed clone task. */ if (add_transfer_task (task, NULL) == 0) transition_state (task, CLONE_STATE_FETCH); else transition_to_error (task, CLONE_ERROR_FETCH); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, tx_task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", tx_task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); seaf_repo_manager_set_repo_relay_id (seaf->repo_mgr, repo, task->peer_id); if (task->server_url) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_SERVER_URL, task->server_url); } if (!task->server_side_merge) start_checkout (repo, task); else check_folder_permissions (task); } static void on_repo_http_fetched (SeafileSession *seaf, HttpTxTask *tx_task, SeafCloneManager *mgr) { CloneTask *task; /* Only handle clone task. */ if (!tx_task->is_clone) return; task = g_hash_table_lookup (mgr->tasks, tx_task->repo_id); g_return_if_fail (task != NULL); if (tx_task->state == HTTP_TASK_STATE_CANCELED) { /* g_assert (task->state == CLONE_STATE_CANCEL_PENDING); */ transition_state (task, CLONE_STATE_CANCELED); return; } else if (tx_task->state == HTTP_TASK_STATE_ERROR) { transition_to_error (task, CLONE_ERROR_FETCH); task->err_detail = g_strdup(http_task_error_str(tx_task->error)); return; } SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, tx_task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", tx_task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } seaf_repo_manager_set_repo_token (seaf->repo_mgr, repo, task->token); seaf_repo_manager_set_repo_email (seaf->repo_mgr, repo, task->email); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, task->peer_addr, task->peer_port); seaf_repo_manager_set_repo_relay_id (seaf->repo_mgr, repo, task->peer_id); if (task->server_url) { seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_SERVER_URL, task->server_url); } check_folder_permissions (task); } static void on_checkout_done (CheckoutTask *ctask, SeafRepo *repo, void *data) { SeafCloneManager *mgr = data; CloneTask *task = g_hash_table_lookup (mgr->tasks, repo->id); g_return_if_fail (task != NULL); if (!ctask->success) { transition_to_error (task, CLONE_ERROR_CHECKOUT); return; } if (task->state == CLONE_STATE_CANCEL_PENDING) transition_state (task, CLONE_STATE_CANCELED); else if (task->state == CLONE_STATE_CHECKOUT) { /* Save repo head if for GC. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD, repo->head->commit_id); seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD, repo->head->commit_id); transition_state (task, CLONE_STATE_DONE); } } static void check_folder_perms_done (HttpFolderPerms *result, void *user_data) { CloneTask *task = user_data; GList *ptr; HttpFolderPermRes *res; SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } if (!result->success) { goto out; } for (ptr = result->results; ptr; ptr = ptr->next) { res = ptr->data; seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_USER, res->user_perms); seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_GROUP, res->group_perms); seaf_repo_manager_update_folder_perm_timestamp (seaf->repo_mgr, res->repo_id, res->timestamp); } out: mark_clone_done_v2 (repo, task); } static void check_folder_permissions (CloneTask *task) { SeafRepo *repo = NULL; HttpFolderPermReq *req; GList *requests = NULL; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (repo == NULL) { seaf_warning ("[Clone mgr] cannot find repo %s after fetched.\n", task->repo_id); transition_to_error (task, CLONE_ERROR_INTERNAL); return; } if (!seaf_repo_manager_server_is_pro (seaf->repo_mgr, task->server_url)) { mark_clone_done_v2 (repo, task); return; } req = g_new0 (HttpFolderPermReq, 1); memcpy (req->repo_id, task->repo_id, 36); req->token = g_strdup(task->token); req->timestamp = 0; requests = g_list_append (requests, req); /* The requests list will be freed in http tx manager. */ if (http_tx_manager_get_folder_perms (seaf->http_tx_mgr, task->effective_url, task->use_fileserver_port, requests, check_folder_perms_done, task) < 0) transition_to_error (task, CLONE_ERROR_INTERNAL); } seafile-6.1.5/daemon/clone-mgr.h000066400000000000000000000121771323477647300164620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef CLONE_MGR_H #define CLONE_MGR_H #include #include "db.h" struct _SeafileSession; typedef struct _CloneTask CloneTask; typedef struct _SeafCloneManager SeafCloneManager; enum { CLONE_STATE_INIT, CLONE_STATE_CHECK_SERVER, CLONE_STATE_FETCH, CLONE_STATE_DONE, CLONE_STATE_ERROR, CLONE_STATE_CANCEL_PENDING, CLONE_STATE_CANCELED, /* States only used by non-http protocol. */ CLONE_STATE_CONNECT, CLONE_STATE_CHECK_PROTOCOL, CLONE_STATE_INDEX, CLONE_STATE_CHECKOUT, CLONE_STATE_MERGE, N_CLONE_STATES, }; enum { CLONE_OK, CLONE_ERROR_CHECK_SERVER, CLONE_ERROR_INDEX, CLONE_ERROR_FETCH, CLONE_ERROR_PASSWD, CLONE_ERROR_CHECKOUT, CLONE_ERROR_MERGE, CLONE_ERROR_INTERNAL, N_CLONE_ERRORS, }; struct _CloneTask { SeafCloneManager *manager; int state; int error; char *err_detail; char repo_id[37]; int repo_version; char peer_id[41]; char *peer_addr; char *peer_port; char *token; char *email; char *repo_name; /* For better display. */ char *tx_id; char *worktree; char *passwd; int enc_version; char *random_key; char root_id[41]; gboolean is_readonly; /* Set to true when the local folder name is the same as library name. * Worktree folder name will be kept in sync with library name if this is true. */ gboolean sync_wt_name; /* Http sync fields */ char *server_url; char *effective_url; gboolean use_fileserver_port; int http_protocol_version; gboolean http_sync; char server_head_id[41]; gboolean server_side_merge; }; const char * clone_task_state_to_str (int state); const char * clone_task_error_to_str (int error); struct _SeafCloneManager { struct _SeafileSession *seaf; sqlite3 *db; GHashTable *tasks; struct CcnetTimer *check_timer; }; SeafCloneManager * seaf_clone_manager_new (struct _SeafileSession *session); int seaf_clone_manager_init (SeafCloneManager *mgr); int seaf_clone_manager_start (SeafCloneManager *mgr); char * seaf_clone_manager_gen_default_worktree (SeafCloneManager *mgr, const char *worktree_parent, const char *repo_name); char * seaf_clone_manager_add_task (SeafCloneManager *mgr, const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *magic, int enc_version, const char *random_key, const char *worktree, const char *peer_addr, const char *peer_port, const char *email, const char *more_info, GError **error); /* * Similar to seaf_clone_manager_add_task. * But create a new dir for worktree under @wt_parent. * The semantics is to "download" the repo into @wt_parent. */ char * seaf_clone_manager_add_download_task (SeafCloneManager *mgr, const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *token, const char *passwd, const char *magic, int enc_version, const char *random_key, const char *wt_parent, const char *peer_addr, const char *peer_port, const char *email, const char *more_info, GError **error); int seaf_clone_manager_cancel_task (SeafCloneManager *mgr, const char *repo_id); int seaf_clone_manager_remove_task (SeafCloneManager *mgr, const char *repo_id); CloneTask * seaf_clone_manager_get_task (SeafCloneManager *mgr, const char *repo_id); GList * seaf_clone_manager_get_tasks (SeafCloneManager *mgr); gboolean seaf_clone_manager_check_worktree_path (SeafCloneManager *mgr, const char *path, GError **error); #endif seafile-6.1.5/daemon/filelock-mgr.c000066400000000000000000000515771323477647300171540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include "seafile-session.h" #include "filelock-mgr.h" #include "set-perm.h" #include "log.h" #include "db.h" struct _FilelockMgrPriv { GHashTable *repo_locked_files; pthread_mutex_t hash_lock; sqlite3 *db; pthread_mutex_t db_lock; }; typedef struct _FilelockMgrPriv FilelockMgrPriv; typedef struct _LockInfo { int locked_by_me; } LockInfo; /* When a file is locked by me, it can have two reasons: * - Locked by the user manually * - Auto-Locked by Seafile when it detects Office opens the file. */ #define _LOCKED_MANUAL 1 #define _LOCKED_AUTO 2 struct _SeafFilelockManager * seaf_filelock_manager_new (struct _SeafileSession *session) { SeafFilelockManager *mgr = g_new0 (SeafFilelockManager, 1); FilelockMgrPriv *priv = g_new0 (FilelockMgrPriv, 1); mgr->session = session; mgr->priv = priv; priv->repo_locked_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_destroy); pthread_mutex_init (&priv->hash_lock, NULL); pthread_mutex_init (&priv->db_lock, NULL); return mgr; } static void lock_info_free (LockInfo *info) { g_free (info); } static gboolean load_locked_files (sqlite3_stmt *stmt, void *data) { GHashTable *repo_locked_files = data, *files; const char *repo_id, *path; int locked_by_me; repo_id = (const char *)sqlite3_column_text (stmt, 0); path = (const char *)sqlite3_column_text (stmt, 1); locked_by_me = sqlite3_column_int (stmt, 2); files = g_hash_table_lookup (repo_locked_files, repo_id); if (!files) { files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)lock_info_free); g_hash_table_insert (repo_locked_files, g_strdup(repo_id), files); } char *key = g_strdup(path); LockInfo *info = g_new0 (LockInfo, 1); info->locked_by_me = locked_by_me; g_hash_table_replace (files, key, info); return TRUE; } int seaf_filelock_manager_init (SeafFilelockManager *mgr) { char *db_path; sqlite3 *db; char *sql; db_path = g_build_filename (seaf->seaf_dir, "filelocks.db", NULL); if (sqlite_open_db (db_path, &db) < 0) return -1; g_free (db_path); mgr->priv->db = db; sql = "CREATE TABLE IF NOT EXISTS ServerLockedFiles (" "repo_id TEXT, path TEXT, locked_by_me INTEGER);"; sqlite_query_exec (db, sql); sql = "CREATE INDEX IF NOT EXISTS server_locked_files_repo_id_idx " "ON ServerLockedFiles (repo_id);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS ServerLockedFilesTimestamp (" "repo_id TEXT, timestamp INTEGER, PRIMARY KEY (repo_id));"; sqlite_query_exec (db, sql); sql = "SELECT repo_id, path, locked_by_me FROM ServerLockedFiles"; pthread_mutex_lock (&mgr->priv->db_lock); pthread_mutex_lock (&mgr->priv->hash_lock); if (sqlite_foreach_selected_row (mgr->priv->db, sql, load_locked_files, mgr->priv->repo_locked_files) < 0) { pthread_mutex_unlock (&mgr->priv->db_lock); pthread_mutex_unlock (&mgr->priv->hash_lock); g_hash_table_destroy (mgr->priv->repo_locked_files); return -1; } pthread_mutex_unlock (&mgr->priv->hash_lock); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } static void init_locks (gpointer key, gpointer value, gpointer user_data) { char *repo_id = user_data; char *path = key; LockInfo *info = value; if (!info->locked_by_me) { seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo_id, path); } } int seaf_filelock_manager_start (SeafFilelockManager *mgr) { GHashTableIter iter; gpointer key, value; char *repo_id; GHashTable *locks; pthread_mutex_lock (&mgr->priv->hash_lock); g_hash_table_iter_init (&iter, mgr->priv->repo_locked_files); while (g_hash_table_iter_next (&iter, &key, &value)) { repo_id = key; locks = value; g_hash_table_foreach (locks, init_locks, repo_id); } pthread_mutex_unlock (&mgr->priv->hash_lock); return 0; } gboolean seaf_filelock_manager_is_file_locked (SeafFilelockManager *mgr, const char *repo_id, const char *path) { gboolean ret; pthread_mutex_lock (&mgr->priv->hash_lock); GHashTable *locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FALSE; } LockInfo *info = g_hash_table_lookup (locks, path); if (!info) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FALSE; } ret = !info->locked_by_me; pthread_mutex_unlock (&mgr->priv->hash_lock); return ret; } gboolean seaf_filelock_manager_is_file_locked_by_me (SeafFilelockManager *mgr, const char *repo_id, const char *path) { gboolean ret; pthread_mutex_lock (&mgr->priv->hash_lock); GHashTable *locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FALSE; } LockInfo *info = g_hash_table_lookup (locks, path); if (!info) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FALSE; } ret = (info->locked_by_me > 0); pthread_mutex_unlock (&mgr->priv->hash_lock); return ret; } int seaf_filelock_manager_get_lock_status (SeafFilelockManager *mgr, const char *repo_id, const char *path) { int ret; pthread_mutex_lock (&mgr->priv->hash_lock); GHashTable *locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FILE_NOT_LOCKED; } LockInfo *info = g_hash_table_lookup (locks, path); if (!info) { pthread_mutex_unlock (&mgr->priv->hash_lock); return FILE_NOT_LOCKED; } if (info->locked_by_me == _LOCKED_MANUAL) ret = FILE_LOCKED_BY_ME_MANUAL; else if (info->locked_by_me == _LOCKED_AUTO) ret = FILE_LOCKED_BY_ME_AUTO; else ret = FILE_LOCKED_BY_OTHERS; pthread_mutex_unlock (&mgr->priv->hash_lock); return ret; } void seaf_filelock_manager_lock_wt_file (SeafFilelockManager *mgr, const char *repo_id, const char *path) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) return; char *fullpath = g_build_filename (repo->worktree, path, NULL); if (seaf_util_exists (fullpath)) seaf_set_path_permission (fullpath, SEAF_PATH_PERM_RO, FALSE); g_free (fullpath); } void seaf_filelock_manager_unlock_wt_file (SeafFilelockManager *mgr, const char *repo_id, const char *path) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) return; char *fullpath = g_build_filename (repo->worktree, path, NULL); #ifdef WIN32 if (seaf_util_exists (fullpath)) seaf_unset_path_permission (fullpath, FALSE); #else if (seaf_util_exists (fullpath)) seaf_set_path_permission (fullpath, SEAF_PATH_PERM_RW, FALSE); #endif g_free (fullpath); } static void update_in_memory (SeafFilelockManager *mgr, const char *repo_id, GHashTable *new_locks) { GHashTable *repo_hash = mgr->priv->repo_locked_files; pthread_mutex_lock (&mgr->priv->hash_lock); GHashTable *locks = g_hash_table_lookup (repo_hash, repo_id); if (!locks) { if (g_hash_table_size (new_locks) == 0) { pthread_mutex_unlock (&mgr->priv->hash_lock); return; } locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)lock_info_free); g_hash_table_insert (repo_hash, g_strdup(repo_id), locks); } GHashTableIter iter; gpointer key, value; gpointer new_key, new_val; char *path; #ifdef WIN32 char *fullpath; #endif LockInfo *info; gboolean exists; int locked_by_me; SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to find repo %s\n", repo_id); return; } g_hash_table_iter_init (&iter, locks); while (g_hash_table_iter_next (&iter, &key, &value)) { path = key; info = value; exists = g_hash_table_lookup_extended (new_locks, path, &new_key, &new_val); if (!exists) { #ifdef WIN32 fullpath = g_build_path ("/", repo->worktree, path, NULL); seaf_sync_manager_add_refresh_path (seaf->sync_mgr, fullpath); g_free (fullpath); #endif seaf_filelock_manager_unlock_wt_file (mgr, repo_id, path); g_hash_table_iter_remove (&iter); } else { locked_by_me = (int)(long)new_val; if (!info->locked_by_me && locked_by_me) { #ifdef WIN32 fullpath = g_build_path ("/", repo->worktree, path, NULL); seaf_sync_manager_add_refresh_path (seaf->sync_mgr, fullpath); g_free (fullpath); #endif seaf_filelock_manager_unlock_wt_file (mgr, repo_id, path); info->locked_by_me = locked_by_me; } else if (info->locked_by_me && !locked_by_me) { #ifdef WIN32 fullpath = g_build_path ("/", repo->worktree, path, NULL); seaf_sync_manager_add_refresh_path (seaf->sync_mgr, fullpath); g_free (fullpath); #endif seaf_filelock_manager_lock_wt_file (mgr, repo_id, path); info->locked_by_me = locked_by_me; } } } g_hash_table_iter_init (&iter, new_locks); while (g_hash_table_iter_next (&iter, &new_key, &new_val)) { path = new_key; locked_by_me = (int)(long)new_val; if (!g_hash_table_lookup (locks, path)) { info = g_new0 (LockInfo, 1); info->locked_by_me = locked_by_me; g_hash_table_insert (locks, g_strdup(path), info); #ifdef WIN32 fullpath = g_build_path ("/", repo->worktree, path, NULL); seaf_sync_manager_add_refresh_path (seaf->sync_mgr, fullpath); g_free (fullpath); #endif if (!locked_by_me) { seaf_filelock_manager_lock_wt_file (mgr, repo_id, path); } } } pthread_mutex_unlock (&mgr->priv->hash_lock); } static gint compare_paths (gconstpointer a, gconstpointer b) { const char *patha = a, *pathb = b; return strcmp (patha, pathb); } static int update_db (SeafFilelockManager *mgr, const char *repo_id) { char *sql; sqlite3_stmt *stmt; GHashTable *locks; GList *paths, *ptr; char *path; LockInfo *info; pthread_mutex_lock (&mgr->priv->db_lock); sql = "DELETE FROM ServerLockedFiles WHERE repo_id = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove server locked files for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks || g_hash_table_size (locks) == 0) { pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } paths = g_hash_table_get_keys (locks); paths = g_list_sort (paths, compare_paths); sql = "INSERT INTO ServerLockedFiles (repo_id, path, locked_by_me) VALUES (?, ?, ?)"; stmt = sqlite_query_prepare (mgr->priv->db, sql); for (ptr = paths; ptr; ptr = ptr->next) { path = ptr->data; info = g_hash_table_lookup (locks, path); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, path, -1, SQLITE_TRANSIENT); sqlite3_bind_int (stmt, 3, info->locked_by_me); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to insert server file lock for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_reset (stmt); sqlite3_clear_bindings (stmt); } sqlite3_finalize (stmt); g_list_free (paths); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } int seaf_filelock_manager_update (SeafFilelockManager *mgr, const char *repo_id, GHashTable *new_locked_files) { update_in_memory (mgr, repo_id, new_locked_files); int ret = update_db (mgr, repo_id); return ret; } int seaf_filelock_manager_update_timestamp (SeafFilelockManager *mgr, const char *repo_id, gint64 timestamp) { char sql[256]; int ret; snprintf (sql, sizeof(sql), "REPLACE INTO ServerLockedFilesTimestamp VALUES ('%s', %"G_GINT64_FORMAT")", repo_id, timestamp); pthread_mutex_lock (&mgr->priv->db_lock); ret = sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return ret; } gint64 seaf_filelock_manager_get_timestamp (SeafFilelockManager *mgr, const char *repo_id) { char sql[256]; gint64 ret; sqlite3_snprintf (sizeof(sql), sql, "SELECT timestamp FROM ServerLockedFilesTimestamp WHERE repo_id = '%q'", repo_id); pthread_mutex_lock (&mgr->priv->db_lock); ret = sqlite_get_int64 (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return ret; } int seaf_filelock_manager_remove (SeafFilelockManager *mgr, const char *repo_id) { char *sql; sqlite3_stmt *stmt; pthread_mutex_lock (&mgr->priv->db_lock); sql = "DELETE FROM ServerLockedFiles WHERE repo_id = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove server locked files for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); sql = "DELETE FROM ServerLockedFilesTimestamp WHERE repo_id = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove server locked files timestamp for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); pthread_mutex_lock (&mgr->priv->hash_lock); g_hash_table_remove (mgr->priv->repo_locked_files, repo_id); pthread_mutex_unlock (&mgr->priv->hash_lock); return 0; } #ifdef WIN32 static void refresh_locked_path_status (const char *repo_id, const char *path) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) return; char *fullpath = g_build_path ("/", repo->worktree, path, NULL); seaf_sync_manager_refresh_path (seaf->sync_mgr, fullpath); g_free (fullpath); } #endif static int mark_file_locked_in_db (SeafFilelockManager *mgr, const char *repo_id, const char *path, int locked_by_me) { char *sql; sqlite3_stmt *stmt; pthread_mutex_lock (&mgr->priv->db_lock); sql = "REPLACE INTO ServerLockedFiles (repo_id, path, locked_by_me) VALUES (?, ?, ?)"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, path, -1, SQLITE_TRANSIENT); sqlite3_bind_int (stmt, 3, locked_by_me); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to update server locked files for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } int seaf_filelock_manager_mark_file_locked (SeafFilelockManager *mgr, const char *repo_id, const char *path, gboolean is_auto_lock) { GHashTable *locks; LockInfo *info; pthread_mutex_lock (&mgr->priv->hash_lock); locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks) { locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)lock_info_free); g_hash_table_insert (mgr->priv->repo_locked_files, g_strdup(repo_id), locks); } info = g_hash_table_lookup (locks, path); if (!info) { info = g_new0 (LockInfo, 1); g_hash_table_insert (locks, g_strdup(path), info); } if (!is_auto_lock) info->locked_by_me = _LOCKED_MANUAL; else info->locked_by_me = _LOCKED_AUTO; pthread_mutex_unlock (&mgr->priv->hash_lock); #ifdef WIN32 refresh_locked_path_status (repo_id, path); #endif return mark_file_locked_in_db (mgr, repo_id, path, info->locked_by_me); } static int remove_locked_file_from_db (SeafFilelockManager *mgr, const char *repo_id, const char *path) { char *sql; sqlite3_stmt *stmt; pthread_mutex_lock (&mgr->priv->db_lock); sql = "DELETE FROM ServerLockedFiles WHERE repo_id = ? AND path = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, path, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove locked file %s from %.8s: %s.\n", path, repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } int seaf_filelock_manager_mark_file_unlocked (SeafFilelockManager *mgr, const char *repo_id, const char *path) { GHashTable *locks; pthread_mutex_lock (&mgr->priv->hash_lock); locks = g_hash_table_lookup (mgr->priv->repo_locked_files, repo_id); if (!locks) { pthread_mutex_unlock (&mgr->priv->hash_lock); return 0; } g_hash_table_remove (locks, path); pthread_mutex_unlock (&mgr->priv->hash_lock); #ifdef WIN32 refresh_locked_path_status (repo_id, path); #endif return remove_locked_file_from_db (mgr, repo_id, path); } void file_lock_info_free (FileLockInfo *info) { if (!info) return; g_free (info->path); g_free (info); } static gboolean collect_auto_locked_files (sqlite3_stmt *stmt, void *vret) { GList **pret = vret; const char *repo_id, *path; FileLockInfo *info; repo_id = (const char *)sqlite3_column_text (stmt, 0); path = (const char *)sqlite3_column_text (stmt, 1); info = g_new0 (FileLockInfo, 1); memcpy (info->repo_id, repo_id, 36); info->path = g_strdup(path); *pret = g_list_prepend (*pret, info); return TRUE; } GList * seaf_filelock_manager_get_auto_locked_files (SeafFilelockManager *mgr) { char *sql; GList *ret = NULL; pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("SELECT repo_id, path FROM ServerLockedFiles " "WHERE locked_by_me = %d", _LOCKED_AUTO); sqlite_foreach_selected_row (mgr->priv->db, sql, collect_auto_locked_files, &ret); pthread_mutex_unlock (&mgr->priv->db_lock); ret = g_list_reverse (ret); sqlite3_free (sql); return ret; } seafile-6.1.5/daemon/filelock-mgr.h000066400000000000000000000057721323477647300171550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_FILELOCK_MGR_H #define SEAF_FILELOCK_MGR_H #include struct _SeafileSession; struct _FilelockMgrPriv; struct _SeafFilelockManager { struct _SeafileSession *session; struct _FilelockMgrPriv *priv; }; typedef struct _SeafFilelockManager SeafFilelockManager; struct _SeafFilelockManager * seaf_filelock_manager_new (struct _SeafileSession *session); int seaf_filelock_manager_init (SeafFilelockManager *mgr); int seaf_filelock_manager_start (SeafFilelockManager *mgr); gboolean seaf_filelock_manager_is_file_locked (SeafFilelockManager *mgr, const char *repo_id, const char *path); #define FILE_NOT_LOCKED 0 #define FILE_LOCKED_BY_OTHERS 1 #define FILE_LOCKED_BY_ME_MANUAL 2 #define FILE_LOCKED_BY_ME_AUTO 3 int seaf_filelock_manager_get_lock_status (SeafFilelockManager *mgr, const char *repo_id, const char *path); gboolean seaf_filelock_manager_is_file_locked_by_me (SeafFilelockManager *mgr, const char *repo_id, const char *path); /* Remove locking from the file on worktree */ void seaf_filelock_manager_lock_wt_file (SeafFilelockManager *mgr, const char *repo_id, const char *path); /* Add locking to the file on worktree */ void seaf_filelock_manager_unlock_wt_file (SeafFilelockManager *mgr, const char *repo_id, const char *path); int seaf_filelock_manager_update (SeafFilelockManager *mgr, const char *repo_id, GHashTable *new_locked_files); int seaf_filelock_manager_update_timestamp (SeafFilelockManager *mgr, const char *repo_id, gint64 timestamp); gint64 seaf_filelock_manager_get_timestamp (SeafFilelockManager *mgr, const char *repo_id); int seaf_filelock_manager_remove (SeafFilelockManager *mgr, const char *repo_id); int seaf_filelock_manager_mark_file_locked (SeafFilelockManager *mgr, const char *repo_id, const char *path, gboolean is_auto_lock); int seaf_filelock_manager_mark_file_unlocked (SeafFilelockManager *mgr, const char *repo_id, const char *path); struct FileLockInfo { char repo_id[37]; char *path; int status; }; typedef struct FileLockInfo FileLockInfo; void file_lock_info_free (FileLockInfo *info); GList * seaf_filelock_manager_get_auto_locked_files (SeafFilelockManager *mgr); #endif seafile-6.1.5/daemon/http-tx-mgr.c000066400000000000000000004012561323477647300167650ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "net.h" #include #include #include #include #ifdef WIN32 #include #include #endif #ifndef USE_GPL_CRYPTO #include #include #include #include #endif #include #include "seafile-config.h" #include "seafile-session.h" #include "http-tx-mgr.h" #include "seafile-error.h" #include "utils.h" #include "diff-simple.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #define HTTP_OK 200 #define HTTP_BAD_REQUEST 400 #define HTTP_FORBIDDEN 403 #define HTTP_NOT_FOUND 404 #define HTTP_NO_QUOTA 443 #define HTTP_REPO_DELETED 444 #define HTTP_REPO_CORRUPTED 445 #define HTTP_INTERNAL_SERVER_ERROR 500 #define RESET_BYTES_INTERVAL_MSEC 1000 #define CLEAR_POOL_ERR_CNT 3 #ifndef SEAFILE_CLIENT_VERSION #define SEAFILE_CLIENT_VERSION PACKAGE_VERSION #endif #ifdef WIN32 #define USER_AGENT_OS "Windows NT" #endif #ifdef __APPLE__ #define USER_AGENT_OS "Apple OS X" #endif #ifdef __linux__ #define USER_AGENT_OS "Linux" #endif #if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __DragonFly__ #define USER_AGENT_OS "BSD" #endif struct _Connection { CURL *curl; gint64 ctime; /* Used to clean up unused connection. */ gboolean release; /* If TRUE, the connection will be released. */ }; typedef struct _Connection Connection; struct _ConnectionPool { char *host; GQueue *queue; pthread_mutex_t lock; int err_cnt; }; typedef struct _ConnectionPool ConnectionPool; struct _HttpTxPriv { GHashTable *download_tasks; GHashTable *upload_tasks; GHashTable *connection_pools; /* host -> connection pool */ pthread_mutex_t pools_lock; CcnetTimer *reset_bytes_timer; char *ca_bundle_path; }; typedef struct _HttpTxPriv HttpTxPriv; /* Http Tx Task */ static HttpTxTask * http_tx_task_new (HttpTxManager *mgr, const char *repo_id, int repo_version, int type, gboolean is_clone, const char *host, const char *token, const char *passwd, const char *worktree) { HttpTxTask *task = g_new0 (HttpTxTask, 1); task->manager = mgr; memcpy (task->repo_id, repo_id, 36); task->repo_version = repo_version; task->type = type; task->is_clone = is_clone; task->host = g_strdup(host); task->token = g_strdup(token); if (passwd) task->passwd = g_strdup(passwd); if (worktree) task->worktree = g_strdup(worktree); return task; } static void http_tx_task_free (HttpTxTask *task) { g_free (task->host); g_free (task->token); g_free (task->passwd); g_free (task->worktree); g_free (task->email); if (task->type == HTTP_TASK_TYPE_DOWNLOAD) { g_hash_table_destroy (task->blk_ref_cnts); cevent_manager_unregister (seaf->ev_mgr, task->cevent_id); g_free (task->repo_name); } g_free (task); } static const char *http_task_state_str[] = { "normal", "canceled", "finished", "error", }; static const char *http_task_rt_state_str[] = { "init", "check", "commit", "fs", "data", "update-branch", "finished", }; static const char *http_task_error_strs[] = { "Successful", "Permission denied on server", "Network error", "Cannot resolve proxy address", "Cannot resolve server address", "Cannot connect to server", "Failed to establish secure connection", "Data transfer was interrupted", "Data transfer timed out", "Unhandled http redirect from server", "Server error", "Bad request", "Internal data corrupt on the client", "Not enough memory", "Failed to write data on the client", "Storage quota full", "Files are locked by other application", "Library deleted on server", "Library damaged on server", "Unknown error", }; /* Http connection and connection pool. */ static Connection * connection_new () { Connection *conn = g_new0 (Connection, 1); conn->curl = curl_easy_init(); conn->ctime = (gint64)time(NULL); return conn; } static void connection_free (Connection *conn) { curl_easy_cleanup (conn->curl); g_free (conn); } static ConnectionPool * connection_pool_new (const char *host) { ConnectionPool *pool = g_new0 (ConnectionPool, 1); pool->host = g_strdup(host); pool->queue = g_queue_new (); pthread_mutex_init (&pool->lock, NULL); return pool; } static ConnectionPool * find_connection_pool (HttpTxPriv *priv, const char *host) { ConnectionPool *pool; pthread_mutex_lock (&priv->pools_lock); pool = g_hash_table_lookup (priv->connection_pools, host); if (!pool) { pool = connection_pool_new (host); g_hash_table_insert (priv->connection_pools, g_strdup(host), pool); } pthread_mutex_unlock (&priv->pools_lock); return pool; } static Connection * connection_pool_get_connection (ConnectionPool *pool) { Connection *conn = NULL; pthread_mutex_lock (&pool->lock); conn = g_queue_pop_head (pool->queue); if (!conn) { conn = connection_new (); } pthread_mutex_unlock (&pool->lock); return conn; } static void connection_pool_clear (ConnectionPool *pool) { Connection *conn = NULL; while (1) { conn = g_queue_pop_head (pool->queue); if (!conn) break; connection_free (conn); } } static void connection_pool_return_connection (ConnectionPool *pool, Connection *conn) { if (!conn) return; if (conn->release) { connection_free (conn); pthread_mutex_lock (&pool->lock); if (++pool->err_cnt >= CLEAR_POOL_ERR_CNT) { connection_pool_clear (pool); } pthread_mutex_unlock (&pool->lock); return; } curl_easy_reset (conn->curl); /* Reset error count when one connection succeeded. */ pthread_mutex_lock (&pool->lock); pool->err_cnt = 0; g_queue_push_tail (pool->queue, conn); pthread_mutex_unlock (&pool->lock); } HttpTxManager * http_tx_manager_new (struct _SeafileSession *seaf) { HttpTxManager *mgr = g_new0 (HttpTxManager, 1); HttpTxPriv *priv = g_new0 (HttpTxPriv, 1); mgr->seaf = seaf; priv->download_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)http_tx_task_free); priv->upload_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)http_tx_task_free); priv->connection_pools = g_hash_table_new (g_str_hash, g_str_equal); pthread_mutex_init (&priv->pools_lock, NULL); priv->ca_bundle_path = g_build_filename (seaf->seaf_dir, "ca-bundle.pem", NULL); mgr->priv = priv; return mgr; } static int reset_bytes (void *vdata) { HttpTxManager *mgr = vdata; HttpTxPriv *priv = mgr->priv; GHashTableIter iter; gpointer key, value; HttpTxTask *task; g_hash_table_iter_init (&iter, priv->download_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; task->last_tx_bytes = g_atomic_int_get (&task->tx_bytes); g_atomic_int_set (&task->tx_bytes, 0); } g_hash_table_iter_init (&iter, priv->upload_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; task->last_tx_bytes = g_atomic_int_get (&task->tx_bytes); g_atomic_int_set (&task->tx_bytes, 0); } return 1; } int http_tx_manager_start (HttpTxManager *mgr) { #ifdef WIN32 /* Remove existing ca-bundle file on start. */ g_unlink (mgr->priv->ca_bundle_path); #endif /* TODO: add a timer to clean up unused Http connections. */ mgr->priv->reset_bytes_timer = ccnet_timer_new (reset_bytes, mgr, RESET_BYTES_INTERVAL_MSEC); return 0; } /* Common Utility Functions. */ #ifndef USE_GPL_CRYPTO #ifdef WIN32 static void write_cert_name_to_pem_file (FILE *f, PCCERT_CONTEXT pc) { char *name; DWORD size; fprintf (f, "\n"); if (!CertGetCertificateContextProperty(pc, CERT_FRIENDLY_NAME_PROP_ID, NULL, &size)) { return; } name = g_malloc ((gsize)size); if (!name) { seaf_warning ("Failed to alloc memory\n"); return; } if (!CertGetCertificateContextProperty(pc, CERT_FRIENDLY_NAME_PROP_ID, name, &size)) { g_free (name); return; } if (fwrite(name, (size_t)size, 1, f) != 1) { seaf_warning ("Failed to write pem file.\n"); g_free (name); return; } fprintf (f, "\n"); g_free (name); } static void write_cert_to_pem_file (FILE *f, PCCERT_CONTEXT pc) { const unsigned char *der = pc->pbCertEncoded; X509 *cert; write_cert_name_to_pem_file (f, pc); cert = d2i_X509 (NULL, &der, (int)pc->cbCertEncoded); if (!cert) { seaf_warning ("Failed to parse certificate from DER.\n"); return; } if (!PEM_write_X509 (f, cert)) { seaf_warning ("Failed to write certificate.\n"); X509_free (cert); return; } X509_free (cert); } static int load_ca_from_store (FILE *f, const wchar_t *store_name) { HCERTSTORE store; store = CertOpenSystemStoreW (0, store_name); if (!store) { seaf_warning ("Failed to open system cert store: %lu\n", GetLastError()); return -1; } PCCERT_CONTEXT pc = NULL; while (1) { pc = CertFindCertificateInStore (store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pc); if (!pc) break; write_cert_to_pem_file (f, pc); } CertCloseStore(store, 0); return 0; } static int create_ca_bundle (const char *ca_bundle_path) { FILE *f; int ret = 0; f = g_fopen (ca_bundle_path, "w+b"); if (!f) { seaf_warning ("Failed to open cabundle file %s: %s\n", ca_bundle_path, strerror(errno)); return -1; } if (load_ca_from_store (f, L"ROOT") < 0) { seaf_warning ("Failed to load ca from ROOT store.\n"); ret = -1; goto out; } if (load_ca_from_store (f, L"CA") < 0) { seaf_warning ("Failed to load ca from CA store.\n"); ret = -1; goto out; } out: fclose (f); return ret; } #endif /* WIN32 */ #ifndef __linux__ static void load_ca_bundle (CURL *curl) { char *ca_bundle_path = seaf->http_tx_mgr->priv->ca_bundle_path; /* On MacOS the certs are loaded by seafile applet instead of seaf-daemon */ if (!seaf_util_exists (ca_bundle_path)) { #ifdef WIN32 if (create_ca_bundle (ca_bundle_path) < 0) return; #else return; #endif } curl_easy_setopt (curl, CURLOPT_CAINFO, ca_bundle_path); } #endif /* __linux__ */ static gboolean load_certs (sqlite3_stmt *stmt, void *vdata) { X509_STORE *store = vdata; X509 *saved = NULL; const char *pem_b64; char *pem = NULL; BIO *b = NULL; gboolean ret = TRUE; pem_b64 = (const char *)sqlite3_column_text (stmt, 0); gsize len; pem = (char *)g_base64_decode (pem_b64, &len); if (!pem) { seaf_warning ("Failed to decode base64.\n"); goto out; } b = BIO_new (BIO_s_mem()); if (!b) { seaf_warning ("Failed to alloc BIO\n"); goto out; } if (BIO_write (b, pem, len) != len) { seaf_warning ("Failed to write pem to BIO\n"); goto out; } saved = PEM_read_bio_X509 (b, NULL, 0, NULL); if (!saved) { seaf_warning ("Failed to read PEM from BIO\n"); goto out; } X509_STORE_add_cert (store, saved); out: g_free (pem); if (b) BIO_free (b); if (saved) X509_free (saved); return ret; } static int load_certs_from_db (X509_STORE *store) { char *cert_db_path = NULL; sqlite3 *db = NULL; char *sql; int ret = 0; cert_db_path = g_build_filename (seaf->seaf_dir, "certs.db", NULL); if (sqlite_open_db (cert_db_path, &db) < 0) { seaf_warning ("Failed to open certs.db\n"); ret = -1; goto out; } sql = "SELECT cert FROM Certs;"; if (sqlite_foreach_selected_row (db, sql, load_certs, store) < 0) { ret = -1; goto out; } out: g_free (cert_db_path); if (db) sqlite_close_db (db); return ret; } static CURLcode ssl_callback (CURL *curl, void *ssl_ctx, void *userptr) { SSL_CTX *ctx = ssl_ctx; X509_STORE *store; store = SSL_CTX_get_cert_store(ctx); /* Add all certs stored in db as trusted CA certs. * This workaround has one limitation though. The self-signed certs cannot * contain chain. It must be the CA itself. */ load_certs_from_db (store); return CURLE_OK; } #endif /* USE_GPL_CRYPTO */ static void set_proxy (CURL *curl, gboolean is_https) { /* Disable proxy if proxy options are not set properly. */ if (!seaf->use_http_proxy || !seaf->http_proxy_type || !seaf->http_proxy_addr) { curl_easy_setopt (curl, CURLOPT_PROXY, NULL); return; } if (g_strcmp0(seaf->http_proxy_type, PROXY_TYPE_HTTP) == 0) { curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); /* Use CONNECT method create a SSL tunnel if https is used. */ if (is_https) curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L); curl_easy_setopt(curl, CURLOPT_PROXY, seaf->http_proxy_addr); curl_easy_setopt(curl, CURLOPT_PROXYPORT, seaf->http_proxy_port > 0 ? seaf->http_proxy_port : 80); if (seaf->http_proxy_username && seaf->http_proxy_password) { curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_DIGEST_IE | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM); curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, seaf->http_proxy_username); curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, seaf->http_proxy_password); } } else if (g_strcmp0(seaf->http_proxy_type, PROXY_TYPE_SOCKS) == 0) { if (seaf->http_proxy_port < 0) return; curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); curl_easy_setopt(curl, CURLOPT_PROXY, seaf->http_proxy_addr); curl_easy_setopt(curl, CURLOPT_PROXYPORT, seaf->http_proxy_port); } } #ifdef WIN32 static int sockopt_callback (void *clientp, curl_socket_t curlfd, curlsocktype purpose) { /* Set large enough TCP buffer size. * This greatly enhances sync speed for high latency network. * Windows by default use 8KB buffers, which is too small for such case. * Linux has auto-tuning for TCP buffers, so don't need to set manually. * OSX is TBD. */ #define DEFAULT_SNDBUF_SIZE (1 << 17) /* 128KB */ /* Set send buffer size. */ int sndbuf_size; socklen_t optlen; optlen = sizeof(int); getsockopt (curlfd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, &optlen); if (sndbuf_size < DEFAULT_SNDBUF_SIZE) { sndbuf_size = DEFAULT_SNDBUF_SIZE; optlen = sizeof(int); setsockopt (curlfd, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf_size, optlen); } /* Disable Nagle's algorithm. */ int val = 1; optlen = sizeof(int); setsockopt (curlfd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, optlen); return CURL_SOCKOPT_OK; } #endif /* WIN32 */ typedef struct _HttpResponse { char *content; size_t size; } HttpResponse; static size_t recv_response (void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; HttpResponse *rsp = userp; rsp->content = g_realloc (rsp->content, rsp->size + realsize); if (!rsp->content) { seaf_warning ("Not enough memory.\n"); /* return a value other than realsize to signify an error. */ return 0; } memcpy (rsp->content + rsp->size, contents, realsize); rsp->size += realsize; return realsize; } #define HTTP_TIMEOUT_SEC 300 typedef size_t (*HttpRecvCallback) (void *, size_t, size_t, void *); /* * The @timeout parameter is for detecting network connection problems. * The @timeout parameter should be set to TRUE for data-transfer-only operations, * such as getting objects, blocks. For operations that requires calculations * on the server side, the timeout should be set to FALSE. Otherwise when * the server sometimes takes more than 45 seconds to calculate the result, * the client will time out. */ static int http_get (CURL *curl, const char *url, const char *token, int *rsp_status, char **rsp_content, gint64 *rsp_size, HttpRecvCallback callback, void *cb_data, gboolean timeout, int *pcurl_error) { char *token_header; struct curl_slist *headers = NULL; int ret = 0; headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")"); if (token) { token_header = g_strdup_printf ("Seafile-Repo-Token: %s", token); headers = curl_slist_append (headers, token_header); g_free (token_header); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); if (timeout) { /* Set low speed limit to 1 bytes. This effectively means no data. */ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1); curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, HTTP_TIMEOUT_SEC); } if (seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); } HttpResponse rsp; memset (&rsp, 0, sizeof(rsp)); if (rsp_content) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, recv_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsp); } else if (callback) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, cb_data); } gboolean is_https = (strncasecmp(url, "https", strlen("https")) == 0); set_proxy (curl, is_https); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef USE_GPL_CRYPTO #if defined WIN32 || defined __APPLE__ load_ca_bundle (curl); #endif #endif #ifndef USE_GPL_CRYPTO if (!seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback); curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url); } #endif #ifdef WIN32 curl_easy_setopt (curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); #endif int rc = curl_easy_perform (curl); if (rc != 0) { seaf_warning ("libcurl failed to GET %s: %s.\n", url, curl_easy_strerror(rc)); if (pcurl_error) *pcurl_error = rc; ret = -1; goto out; } long status; rc = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status); if (rc != CURLE_OK) { seaf_warning ("Failed to get status code for GET %s.\n", url); ret = -1; goto out; } *rsp_status = status; if (rsp_content) { *rsp_content = rsp.content; *rsp_size = rsp.size; } out: if (ret < 0) g_free (rsp.content); curl_slist_free_all (headers); return ret; } typedef struct _HttpRequest { const char *content; size_t size; } HttpRequest; static size_t send_request (void *ptr, size_t size, size_t nmemb, void *userp) { size_t realsize = size *nmemb; size_t copy_size; HttpRequest *req = userp; if (req->size == 0) return 0; copy_size = MIN(req->size, realsize); memcpy (ptr, req->content, copy_size); req->size -= copy_size; req->content = req->content + copy_size; return copy_size; } typedef size_t (*HttpSendCallback) (void *, size_t, size_t, void *); static int http_put (CURL *curl, const char *url, const char *token, const char *req_content, gint64 req_size, HttpSendCallback callback, void *cb_data, int *rsp_status, char **rsp_content, gint64 *rsp_size, gboolean timeout, int *pcurl_error) { char *token_header; struct curl_slist *headers = NULL; int ret = 0; headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")"); /* Disable the default "Expect: 100-continue" header */ headers = curl_slist_append (headers, "Expect:"); if (token) { token_header = g_strdup_printf ("Seafile-Repo-Token: %s", token); headers = curl_slist_append (headers, token_header); g_free (token_header); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); if (timeout) { /* Set low speed limit to 1 bytes. This effectively means no data. */ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1); curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, HTTP_TIMEOUT_SEC); } if (seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); } HttpRequest req; if (req_content) { memset (&req, 0, sizeof(req)); req.content = req_content; req.size = req_size; curl_easy_setopt(curl, CURLOPT_READFUNCTION, send_request); curl_easy_setopt(curl, CURLOPT_READDATA, &req); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)req_size); } else if (callback != NULL) { curl_easy_setopt(curl, CURLOPT_READFUNCTION, callback); curl_easy_setopt(curl, CURLOPT_READDATA, cb_data); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)req_size); } else { curl_easy_setopt (curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)0); } curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); HttpResponse rsp; memset (&rsp, 0, sizeof(rsp)); if (rsp_content) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, recv_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsp); } gboolean is_https = (strncasecmp(url, "https", strlen("https")) == 0); set_proxy (curl, is_https); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); #ifndef USE_GPL_CRYPTO #if defined WIN32 || defined __APPLE__ load_ca_bundle (curl); #endif #endif #ifndef USE_GPL_CRYPTO if (!seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback); curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url); } #endif #ifdef WIN32 curl_easy_setopt (curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); #endif int rc = curl_easy_perform (curl); if (rc != 0) { seaf_warning ("libcurl failed to PUT %s: %s.\n", url, curl_easy_strerror(rc)); if (pcurl_error) *pcurl_error = rc; ret = -1; goto out; } long status; rc = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status); if (rc != CURLE_OK) { seaf_warning ("Failed to get status code for PUT %s.\n", url); ret = -1; goto out; } *rsp_status = status; if (rsp_content) { *rsp_content = rsp.content; *rsp_size = rsp.size; } out: if (ret < 0) g_free (rsp.content); curl_slist_free_all (headers); return ret; } static int http_post (CURL *curl, const char *url, const char *token, const char *req_content, gint64 req_size, int *rsp_status, char **rsp_content, gint64 *rsp_size, gboolean timeout, int *pcurl_error) { char *token_header; struct curl_slist *headers = NULL; int ret = 0; g_return_val_if_fail (req_content != NULL, -1); headers = curl_slist_append (headers, "User-Agent: Seafile/"SEAFILE_CLIENT_VERSION" ("USER_AGENT_OS")"); /* Disable the default "Expect: 100-continue" header */ headers = curl_slist_append (headers, "Expect:"); if (token) { token_header = g_strdup_printf ("Seafile-Repo-Token: %s", token); headers = curl_slist_append (headers, token_header); g_free (token_header); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POST, 1L); if (timeout) { /* Set low speed limit to 1 bytes. This effectively means no data. */ curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 1); curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, HTTP_TIMEOUT_SEC); } if (seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); } HttpRequest req; memset (&req, 0, sizeof(req)); req.content = req_content; req.size = req_size; curl_easy_setopt(curl, CURLOPT_READFUNCTION, send_request); curl_easy_setopt(curl, CURLOPT_READDATA, &req); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)req_size); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); HttpResponse rsp; memset (&rsp, 0, sizeof(rsp)); if (rsp_content) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, recv_response); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &rsp); } #ifndef USE_GPL_CRYPTO #if defined WIN32 || defined __APPLE__ load_ca_bundle (curl); #endif #endif #ifndef USE_GPL_CRYPTO if (!seaf->disable_verify_certificate) { curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback); curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url); } #endif gboolean is_https = (strncasecmp(url, "https", strlen("https")) == 0); set_proxy (curl, is_https); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* All POST requests should remain POST after redirect. */ curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); #ifdef WIN32 curl_easy_setopt (curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); #endif int rc = curl_easy_perform (curl); if (rc != 0) { seaf_warning ("libcurl failed to POST %s: %s.\n", url, curl_easy_strerror(rc)); if (pcurl_error) *pcurl_error = rc; ret = -1; goto out; } long status; rc = curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status); if (rc != CURLE_OK) { seaf_warning ("Failed to get status code for POST %s.\n", url); ret = -1; goto out; } *rsp_status = status; if (rsp_content) { *rsp_content = rsp.content; *rsp_size = rsp.size; } out: if (ret < 0) g_free (rsp.content); curl_slist_free_all (headers); return ret; } static int http_error_to_http_task_error (int status) { if (status == HTTP_BAD_REQUEST) return HTTP_TASK_ERR_BAD_REQUEST; else if (status == HTTP_FORBIDDEN) return HTTP_TASK_ERR_FORBIDDEN; else if (status >= HTTP_INTERNAL_SERVER_ERROR) return HTTP_TASK_ERR_SERVER; else if (status == HTTP_NOT_FOUND) return HTTP_TASK_ERR_SERVER; else if (status == HTTP_NO_QUOTA) return HTTP_TASK_ERR_NO_QUOTA; else if (status == HTTP_REPO_DELETED) return HTTP_TASK_ERR_REPO_DELETED; else if (status == HTTP_REPO_CORRUPTED) return HTTP_TASK_ERR_REPO_CORRUPTED; else return HTTP_TASK_ERR_UNKNOWN; } static void handle_http_errors (HttpTxTask *task, int status) { task->error = http_error_to_http_task_error (status); } static int curl_error_to_http_task_error (int curl_error) { switch (curl_error) { case CURLE_COULDNT_RESOLVE_PROXY: return HTTP_TASK_ERR_RESOLVE_PROXY; case CURLE_COULDNT_RESOLVE_HOST: return HTTP_TASK_ERR_RESOLVE_HOST; case CURLE_COULDNT_CONNECT: return HTTP_TASK_ERR_CONNECT; case CURLE_OPERATION_TIMEDOUT: return HTTP_TASK_ERR_TX_TIMEOUT; case CURLE_SSL_CONNECT_ERROR: case CURLE_PEER_FAILED_VERIFICATION: case CURLE_SSL_CERTPROBLEM: case CURLE_SSL_CACERT: case CURLE_SSL_CACERT_BADFILE: case CURLE_SSL_ISSUER_ERROR: return HTTP_TASK_ERR_SSL; case CURLE_GOT_NOTHING: case CURLE_SEND_ERROR: case CURLE_RECV_ERROR: return HTTP_TASK_ERR_TX; case CURLE_SEND_FAIL_REWIND: return HTTP_TASK_ERR_UNHANDLED_REDIRECT; default: return HTTP_TASK_ERR_NET; } } static void handle_curl_errors (HttpTxTask *task, int curl_error) { task->error = curl_error_to_http_task_error (curl_error); } static void emit_transfer_done_signal (HttpTxTask *task) { if (task->type == HTTP_TASK_TYPE_DOWNLOAD) g_signal_emit_by_name (seaf, "repo-http-fetched", task); else g_signal_emit_by_name (seaf, "repo-http-uploaded", task); } static void transition_state (HttpTxTask *task, int state, int rt_state) { seaf_message ("Transfer repo '%.8s': ('%s', '%s') --> ('%s', '%s')\n", task->repo_id, http_task_state_to_str(task->state), http_task_rt_state_to_str(task->runtime_state), http_task_state_to_str(state), http_task_rt_state_to_str(rt_state)); if (state != task->state) task->state = state; task->runtime_state = rt_state; if (rt_state == HTTP_TASK_RT_STATE_FINISHED) { /* Clear download head info. */ if (task->type == HTTP_TASK_TYPE_DOWNLOAD && state == HTTP_TASK_STATE_FINISHED) seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo_id, REPO_PROP_DOWNLOAD_HEAD, EMPTY_SHA1); emit_transfer_done_signal (task); } } typedef struct { char *host; gboolean use_fileserver_port; HttpProtocolVersionCallback callback; void *user_data; gboolean success; gboolean not_supported; int version; int error_code; } CheckProtocolData; static int parse_protocol_version (const char *rsp_content, int rsp_size, CheckProtocolData *data) { json_t *object = NULL; json_error_t jerror; int version; object = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!object) { seaf_warning ("Parse response failed: %s.\n", jerror.text); return -1; } if (json_object_has_member (object, "version")) { version = json_object_get_int_member (object, "version"); data->version = version; } else { seaf_warning ("Response doesn't contain protocol version.\n"); json_decref (object); return -1; } json_decref (object); return 0; } static void * check_protocol_version_thread (void *vdata) { CheckProtocolData *data = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; int status; char *rsp_content = NULL; gint64 rsp_size; pool = find_connection_pool (priv, data->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", data->host); return vdata; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", data->host); return vdata; } curl = conn->curl; if (!data->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/protocol-version", data->host); else url = g_strdup_printf ("%s/protocol-version", data->host); int curl_error; if (http_get (curl, url, NULL, &status, &rsp_content, &rsp_size, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; data->error_code = curl_error_to_http_task_error (curl_error); goto out; } data->success = TRUE; if (status == HTTP_OK) { if (rsp_size == 0) data->not_supported = TRUE; else if (parse_protocol_version (rsp_content, rsp_size, data) < 0) data->not_supported = TRUE; } else { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); data->not_supported = TRUE; data->error_code = http_error_to_http_task_error (status); } out: g_free (url); g_free (rsp_content); connection_pool_return_connection (pool, conn); return vdata; } static void check_protocol_version_done (void *vdata) { CheckProtocolData *data = vdata; HttpProtocolVersion result; memset (&result, 0, sizeof(result)); result.check_success = data->success; result.not_supported = data->not_supported; result.version = data->version; result.error_code = data->error_code; data->callback (&result, data->user_data); g_free (data->host); g_free (data); } int http_tx_manager_check_protocol_version (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, HttpProtocolVersionCallback callback, void *user_data) { CheckProtocolData *data = g_new0 (CheckProtocolData, 1); data->host = g_strdup(host); data->use_fileserver_port = use_fileserver_port; data->callback = callback; data->user_data = user_data; int ret = ccnet_job_manager_schedule_job (seaf->job_mgr, check_protocol_version_thread, check_protocol_version_done, data); if (ret < 0) { g_free (data->host); g_free (data); } return ret; } /* Check Head Commit. */ typedef struct { char repo_id[41]; int repo_version; char *host; char *token; gboolean use_fileserver_port; HttpHeadCommitCallback callback; void *user_data; gboolean success; gboolean is_corrupt; gboolean is_deleted; char head_commit[41]; int error_code; } CheckHeadData; static int parse_head_commit_info (const char *rsp_content, int rsp_size, CheckHeadData *data) { json_t *object = NULL; json_error_t jerror; const char *head_commit; object = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!object) { seaf_warning ("Parse response failed: %s.\n", jerror.text); return -1; } if (json_object_has_member (object, "is_corrupted") && json_object_get_int_member (object, "is_corrupted")) data->is_corrupt = TRUE; if (!data->is_corrupt) { head_commit = json_object_get_string_member (object, "head_commit_id"); if (!head_commit) { seaf_warning ("Check head commit for repo %s failed. " "Response doesn't contain head commit id.\n", data->repo_id); json_decref (object); return -1; } memcpy (data->head_commit, head_commit, 40); } json_decref (object); return 0; } static void * check_head_commit_thread (void *vdata) { CheckHeadData *data = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; int status; char *rsp_content = NULL; gint64 rsp_size; pool = find_connection_pool (priv, data->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", data->host); return vdata; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", data->host); return vdata; } curl = conn->curl; if (!data->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/commit/HEAD", data->host, data->repo_id); else url = g_strdup_printf ("%s/repo/%s/commit/HEAD", data->host, data->repo_id); int curl_error; if (http_get (curl, url, data->token, &status, &rsp_content, &rsp_size, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; data->error_code = curl_error_to_http_task_error (curl_error); goto out; } if (status == HTTP_OK) { if (parse_head_commit_info (rsp_content, rsp_size, data) < 0) goto out; data->success = TRUE; } else if (status == HTTP_REPO_DELETED) { data->is_deleted = TRUE; data->success = TRUE; } else { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); data->error_code = http_error_to_http_task_error (status); } out: g_free (url); g_free (rsp_content); connection_pool_return_connection (pool, conn); return vdata; } static void check_head_commit_done (void *vdata) { CheckHeadData *data = vdata; HttpHeadCommit result; memset (&result, 0, sizeof(result)); result.check_success = data->success; result.is_corrupt = data->is_corrupt; result.is_deleted = data->is_deleted; memcpy (result.head_commit, data->head_commit, 40); result.error_code = data->error_code; data->callback (&result, data->user_data); g_free (data->host); g_free (data->token); g_free (data); } int http_tx_manager_check_head_commit (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, gboolean use_fileserver_port, HttpHeadCommitCallback callback, void *user_data) { CheckHeadData *data = g_new0 (CheckHeadData, 1); memcpy (data->repo_id, repo_id, 36); data->repo_version = repo_version; data->host = g_strdup(host); data->token = g_strdup(token); data->callback = callback; data->user_data = user_data; data->use_fileserver_port = use_fileserver_port; if (ccnet_job_manager_schedule_job (seaf->job_mgr, check_head_commit_thread, check_head_commit_done, data) < 0) { g_free (data->host); g_free (data->token); g_free (data); return -1; } return 0; } /* Get folder permissions. */ void http_folder_perm_req_free (HttpFolderPermReq *req) { if (!req) return; g_free (req->token); g_free (req); } void http_folder_perm_res_free (HttpFolderPermRes *res) { GList *ptr; if (!res) return; for (ptr = res->user_perms; ptr; ptr = ptr->next) folder_perm_free ((FolderPerm *)ptr->data); for (ptr = res->group_perms; ptr; ptr = ptr->next) folder_perm_free ((FolderPerm *)ptr->data); g_free (res); } typedef struct { char *host; gboolean use_fileserver_port; GList *requests; HttpGetFolderPermsCallback callback; void *user_data; gboolean success; GList *results; } GetFolderPermsData; /* Make sure the path starts with '/' but doesn't end with '/'. */ static char * canonical_perm_path (const char *path) { int len = strlen(path); char *copy, *ret; if (strcmp (path, "/") == 0) return g_strdup(path); if (path[0] == '/' && path[len-1] != '/') return g_strdup(path); copy = g_strdup(path); if (copy[len-1] == '/') copy[len-1] = 0; if (copy[0] != '/') ret = g_strconcat ("/", copy, NULL); else ret = copy; return ret; } static GList * parse_permission_list (json_t *array, gboolean *error) { GList *ret = NULL, *ptr; json_t *object, *member; size_t n; int i; FolderPerm *perm; const char *str; *error = FALSE; n = json_array_size (array); for (i = 0; i < n; ++i) { object = json_array_get (array, i); perm = g_new0 (FolderPerm, 1); member = json_object_get (object, "path"); if (!member) { seaf_warning ("Invalid folder perm response format: no path.\n"); *error = TRUE; goto out; } str = json_string_value(member); if (!str) { seaf_warning ("Invalid folder perm response format: invalid path.\n"); *error = TRUE; goto out; } perm->path = canonical_perm_path (str); member = json_object_get (object, "permission"); if (!member) { seaf_warning ("Invalid folder perm response format: no permission.\n"); *error = TRUE; goto out; } str = json_string_value(member); if (!str) { seaf_warning ("Invalid folder perm response format: invalid permission.\n"); *error = TRUE; goto out; } perm->permission = g_strdup(str); ret = g_list_append (ret, perm); } out: if (*error) { for (ptr = ret; ptr; ptr = ptr->next) folder_perm_free ((FolderPerm *)ptr->data); g_list_free (ret); ret = NULL; } return ret; } static int parse_folder_perms (const char *rsp_content, int rsp_size, GetFolderPermsData *data) { json_t *array = NULL, *object, *member; json_error_t jerror; size_t n; int i; GList *results = NULL, *ptr; HttpFolderPermRes *res; const char *repo_id; int ret = 0; gboolean error; array = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!array) { seaf_warning ("Parse response failed: %s.\n", jerror.text); return -1; } n = json_array_size (array); for (i = 0; i < n; ++i) { object = json_array_get (array, i); res = g_new0 (HttpFolderPermRes, 1); member = json_object_get (object, "repo_id"); if (!member) { seaf_warning ("Invalid folder perm response format: no repo_id.\n"); ret = -1; goto out; } repo_id = json_string_value(member); if (strlen(repo_id) != 36) { seaf_warning ("Invalid folder perm response format: invalid repo_id.\n"); ret = -1; goto out; } memcpy (res->repo_id, repo_id, 36); member = json_object_get (object, "ts"); if (!member) { seaf_warning ("Invalid folder perm response format: no timestamp.\n"); ret = -1; goto out; } res->timestamp = json_integer_value (member); member = json_object_get (object, "user_perms"); if (!member) { seaf_warning ("Invalid folder perm response format: no user_perms.\n"); ret = -1; goto out; } res->user_perms = parse_permission_list (member, &error); if (error) { ret = -1; goto out; } member = json_object_get (object, "group_perms"); if (!member) { seaf_warning ("Invalid folder perm response format: no group_perms.\n"); ret = -1; goto out; } res->group_perms = parse_permission_list (member, &error); if (error) { ret = -1; goto out; } results = g_list_append (results, res); } out: json_decref (array); if (ret < 0) { for (ptr = results; ptr; ptr = ptr->next) http_folder_perm_res_free ((HttpFolderPermRes *)ptr->data); g_list_free (results); } else { data->results = results; } return ret; } static char * compose_get_folder_perms_request (GList *requests) { GList *ptr; HttpFolderPermReq *req; json_t *object, *array; char *req_str = NULL; array = json_array (); for (ptr = requests; ptr; ptr = ptr->next) { req = ptr->data; object = json_object (); json_object_set_new (object, "repo_id", json_string(req->repo_id)); json_object_set_new (object, "token", json_string(req->token)); json_object_set_new (object, "ts", json_integer(req->timestamp)); json_array_append_new (array, object); } req_str = json_dumps (array, 0); if (!req_str) { seaf_warning ("Faile to json_dumps.\n"); } json_decref (array); return req_str; } static void * get_folder_perms_thread (void *vdata) { GetFolderPermsData *data = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; char *req_content = NULL; int status; char *rsp_content = NULL; gint64 rsp_size; GList *ptr; pool = find_connection_pool (priv, data->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", data->host); return vdata; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", data->host); return vdata; } curl = conn->curl; if (!data->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/folder-perm", data->host); else url = g_strdup_printf ("%s/repo/folder-perm", data->host); req_content = compose_get_folder_perms_request (data->requests); if (!req_content) goto out; if (http_post (curl, url, NULL, req_content, strlen(req_content), &status, &rsp_content, &rsp_size, TRUE, NULL) < 0) { conn->release = TRUE; goto out; } if (status == HTTP_OK) { if (parse_folder_perms (rsp_content, rsp_size, data) < 0) goto out; data->success = TRUE; } else { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); } out: for (ptr = data->requests; ptr; ptr = ptr->next) http_folder_perm_req_free ((HttpFolderPermReq *)ptr->data); g_list_free (data->requests); g_free (url); g_free (req_content); g_free (rsp_content); connection_pool_return_connection (pool, conn); return vdata; } static void get_folder_perms_done (void *vdata) { GetFolderPermsData *data = vdata; HttpFolderPerms cb_data; memset (&cb_data, 0, sizeof(cb_data)); cb_data.success = data->success; cb_data.results = data->results; data->callback (&cb_data, data->user_data); GList *ptr; for (ptr = data->results; ptr; ptr = ptr->next) http_folder_perm_res_free ((HttpFolderPermRes *)ptr->data); g_list_free (data->results); g_free (data->host); g_free (data); } int http_tx_manager_get_folder_perms (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *folder_perm_requests, HttpGetFolderPermsCallback callback, void *user_data) { GetFolderPermsData *data = g_new0 (GetFolderPermsData, 1); data->host = g_strdup(host); data->requests = folder_perm_requests; data->callback = callback; data->user_data = user_data; data->use_fileserver_port = use_fileserver_port; if (ccnet_job_manager_schedule_job (seaf->job_mgr, get_folder_perms_thread, get_folder_perms_done, data) < 0) { g_free (data->host); g_free (data); return -1; } return 0; } /* Get Locked Files. */ void http_locked_files_req_free (HttpLockedFilesReq *req) { if (!req) return; g_free (req->token); g_free (req); } void http_locked_files_res_free (HttpLockedFilesRes *res) { if (!res) return; g_hash_table_destroy (res->locked_files); g_free (res); } typedef struct { char *host; gboolean use_fileserver_port; GList *requests; HttpGetLockedFilesCallback callback; void *user_data; gboolean success; GList *results; } GetLockedFilesData; static GHashTable * parse_locked_file_list (json_t *array) { GHashTable *ret = NULL; size_t n, i; json_t *obj, *string, *integer; ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (!ret) { return NULL; } n = json_array_size (array); for (i = 0; i < n; ++i) { obj = json_array_get (array, i); string = json_object_get (obj, "path"); if (!string) { g_hash_table_destroy (ret); return NULL; } integer = json_object_get (obj, "by_me"); if (!integer) { g_hash_table_destroy (ret); return NULL; } g_hash_table_insert (ret, g_strdup(json_string_value(string)), (void*)(long)json_integer_value(integer)); } return ret; } static int parse_locked_files (const char *rsp_content, int rsp_size, GetLockedFilesData *data) { json_t *array = NULL, *object, *member; json_error_t jerror; size_t n; int i; GList *results = NULL; HttpLockedFilesRes *res; const char *repo_id; int ret = 0; array = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!array) { seaf_warning ("Parse response failed: %s.\n", jerror.text); return -1; } n = json_array_size (array); for (i = 0; i < n; ++i) { object = json_array_get (array, i); res = g_new0 (HttpLockedFilesRes, 1); member = json_object_get (object, "repo_id"); if (!member) { seaf_warning ("Invalid locked files response format: no repo_id.\n"); ret = -1; goto out; } repo_id = json_string_value(member); if (strlen(repo_id) != 36) { seaf_warning ("Invalid locked files response format: invalid repo_id.\n"); ret = -1; goto out; } memcpy (res->repo_id, repo_id, 36); member = json_object_get (object, "ts"); if (!member) { seaf_warning ("Invalid locked files response format: no timestamp.\n"); ret = -1; goto out; } res->timestamp = json_integer_value (member); member = json_object_get (object, "locked_files"); if (!member) { seaf_warning ("Invalid locked files response format: no locked_files.\n"); ret = -1; goto out; } res->locked_files = parse_locked_file_list (member); if (res->locked_files == NULL) { ret = -1; goto out; } results = g_list_append (results, res); } out: json_decref (array); if (ret < 0) { g_list_free_full (results, (GDestroyNotify)http_locked_files_res_free); } else { data->results = results; } return ret; } static char * compose_get_locked_files_request (GList *requests) { GList *ptr; HttpLockedFilesReq *req; json_t *object, *array; char *req_str = NULL; array = json_array (); for (ptr = requests; ptr; ptr = ptr->next) { req = ptr->data; object = json_object (); json_object_set_new (object, "repo_id", json_string(req->repo_id)); json_object_set_new (object, "token", json_string(req->token)); json_object_set_new (object, "ts", json_integer(req->timestamp)); json_array_append_new (array, object); } req_str = json_dumps (array, 0); if (!req_str) { seaf_warning ("Faile to json_dumps.\n"); } json_decref (array); return req_str; } static void * get_locked_files_thread (void *vdata) { GetLockedFilesData *data = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; char *req_content = NULL; int status; char *rsp_content = NULL; gint64 rsp_size; pool = find_connection_pool (priv, data->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", data->host); return vdata; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", data->host); return vdata; } curl = conn->curl; if (!data->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/locked-files", data->host); else url = g_strdup_printf ("%s/repo/locked-files", data->host); req_content = compose_get_locked_files_request (data->requests); if (!req_content) goto out; if (http_post (curl, url, NULL, req_content, strlen(req_content), &status, &rsp_content, &rsp_size, TRUE, NULL) < 0) { conn->release = TRUE; goto out; } if (status == HTTP_OK) { if (parse_locked_files (rsp_content, rsp_size, data) < 0) goto out; data->success = TRUE; } else { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); } out: g_list_free_full (data->requests, (GDestroyNotify)http_locked_files_req_free); g_free (url); g_free (req_content); g_free (rsp_content); connection_pool_return_connection (pool, conn); return vdata; } static void get_locked_files_done (void *vdata) { GetLockedFilesData *data = vdata; HttpLockedFiles cb_data; memset (&cb_data, 0, sizeof(cb_data)); cb_data.success = data->success; cb_data.results = data->results; data->callback (&cb_data, data->user_data); g_list_free_full (data->results, (GDestroyNotify)http_locked_files_res_free); g_free (data->host); g_free (data); } int http_tx_manager_get_locked_files (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *locked_files_requests, HttpGetLockedFilesCallback callback, void *user_data) { GetLockedFilesData *data = g_new0 (GetLockedFilesData, 1); data->host = g_strdup(host); data->requests = locked_files_requests; data->callback = callback; data->user_data = user_data; data->use_fileserver_port = use_fileserver_port; if (ccnet_job_manager_schedule_job (seaf->job_mgr, get_locked_files_thread, get_locked_files_done, data) < 0) { g_free (data->host); g_free (data); return -1; } return 0; } /* Synchronous interfaces for locking/unlocking a file on the server. */ int http_tx_manager_lock_file (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, const char *token, const char *repo_id, const char *path) { HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; int status; int ret = 0; pool = find_connection_pool (priv, host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", host); return -1; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", host); return -1; } curl = conn->curl; char *esc_path = g_uri_escape_string(path, NULL, FALSE); if (!use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/lock-file?p=%s", host, repo_id, esc_path); else url = g_strdup_printf ("%s/repo/%s/lock-file?p=%s", host, repo_id, esc_path); g_free (esc_path); if (http_put (curl, url, token, NULL, 0, NULL, NULL, &status, NULL, NULL, TRUE, NULL) < 0) { conn->release = TRUE; ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for PUT %s: %d.\n", url, status); ret = -1; } out: g_free (url); connection_pool_return_connection (pool, conn); return ret; } int http_tx_manager_unlock_file (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, const char *token, const char *repo_id, const char *path) { HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; int status; int ret = 0; pool = find_connection_pool (priv, host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", host); return -1; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", host); return -1; } curl = conn->curl; char *esc_path = g_uri_escape_string(path, NULL, FALSE); if (!use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/unlock-file?p=%s", host, repo_id, esc_path); else url = g_strdup_printf ("%s/repo/%s/unlock-file?p=%s", host, repo_id, esc_path); g_free (esc_path); if (http_put (curl, url, token, NULL, 0, NULL, NULL, &status, NULL, NULL, TRUE, NULL) < 0) { conn->release = TRUE; ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for PUT %s: %d.\n", url, status); ret = -1; } out: g_free (url); connection_pool_return_connection (pool, conn); return ret; } static char * repo_id_list_to_json (GList *repo_id_list) { json_t *array = json_array(); GList *ptr; char *repo_id; for (ptr = repo_id_list; ptr; ptr = ptr->next) { repo_id = ptr->data; json_array_append_new (array, json_string(repo_id)); } char *data = json_dumps (array, JSON_COMPACT); if (!data) { seaf_warning ("Failed to dump json.\n"); json_decref (array); return NULL; } json_decref (array); return data; } static GHashTable * repo_head_commit_map_from_json (const char *json_str, gint64 len) { json_t *object; json_error_t jerror; GHashTable *ret; object = json_loadb (json_str, (size_t)len, 0, &jerror); if (!object) { seaf_warning ("Failed to load json: %s\n", jerror.text); return NULL; } ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); void *iter = json_object_iter (object); const char *key; json_t *value; while (iter) { key = json_object_iter_key (iter); value = json_object_iter_value (iter); if (json_typeof(value) != JSON_STRING) { seaf_warning ("Bad json object format when parsing head commit id map.\n"); g_hash_table_destroy (ret); goto out; } g_hash_table_replace (ret, g_strdup (key), g_strdup(json_string_value(value))); iter = json_object_iter_next (object, iter); } out: json_decref (object); return ret; } GHashTable * http_tx_manager_get_head_commit_ids (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *repo_id_list) { HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; CURL *curl; char *url; char *req_content = NULL; gint64 req_size; int status; char *rsp_content = NULL; gint64 rsp_size; GHashTable *map = NULL; pool = find_connection_pool (priv, host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", host); return NULL; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", host); return NULL; } curl = conn->curl; if (!use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/head-commits-multi/", host); else url = g_strdup_printf ("%s/repo/head-commits-multi/", host); req_content = repo_id_list_to_json (repo_id_list); req_size = strlen(req_content); if (http_post (curl, url, NULL, req_content, req_size, &status, &rsp_content, &rsp_size, TRUE, NULL) < 0) { conn->release = TRUE; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for POST %s: %d\n", url, status); goto out; } map = repo_head_commit_map_from_json (rsp_content, rsp_size); out: g_free (url); connection_pool_return_connection (pool, conn); /* returned by json_dumps(). */ free (req_content); g_free (rsp_content); return map; } static gboolean remove_task_help (gpointer key, gpointer value, gpointer user_data) { HttpTxTask *task = value; const char *repo_id = user_data; if (strcmp(task->repo_id, repo_id) != 0) return FALSE; return TRUE; } static void clean_tasks_for_repo (HttpTxManager *manager, const char *repo_id) { g_hash_table_foreach_remove (manager->priv->download_tasks, remove_task_help, (gpointer)repo_id); g_hash_table_foreach_remove (manager->priv->upload_tasks, remove_task_help, (gpointer)repo_id); } static int check_permission (HttpTxTask *task, Connection *conn) { CURL *curl; char *url; int status; int ret = 0; curl = conn->curl; const char *type = (task->type == HTTP_TASK_TYPE_DOWNLOAD) ? "download" : "upload"; const char *url_prefix = (task->use_fileserver_port) ? "" : "seafhttp/"; if (seaf->client_name) { char *client_name = g_uri_escape_string (seaf->client_name, NULL, FALSE); url = g_strdup_printf ("%s/%srepo/%s/permission-check/?op=%s" "&client_id=%s&client_name=%s", task->host, url_prefix, task->repo_id, type, seaf->session->base.id, client_name); g_free (client_name); } else { url = g_strdup_printf ("%s/%srepo/%s/permission-check/?op=%s", task->host, url_prefix, task->repo_id, type); } int curl_error; if (http_get (curl, url, task->token, &status, NULL, NULL, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; } out: g_free (url); curl_easy_reset (curl); return ret; } /* Upload. */ static void *http_upload_thread (void *vdata); static void http_upload_done (void *vdata); int http_tx_manager_add_upload (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, int protocol_version, gboolean use_fileserver_port, GError **error) { HttpTxTask *task; SeafRepo *repo; if (!repo_id || !token || !host) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty argument(s)"); return -1; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo not found"); return -1; } clean_tasks_for_repo (manager, repo_id); task = http_tx_task_new (manager, repo_id, repo_version, HTTP_TASK_TYPE_UPLOAD, FALSE, host, token, NULL, NULL); task->protocol_version = protocol_version; task->state = HTTP_TASK_STATE_NORMAL; task->use_fileserver_port = use_fileserver_port; g_hash_table_insert (manager->priv->upload_tasks, g_strdup(repo_id), task); if (ccnet_job_manager_schedule_job (seaf->job_mgr, http_upload_thread, http_upload_done, task) < 0) { g_hash_table_remove (manager->priv->upload_tasks, repo_id); return -1; } return 0; } static gboolean dirent_same (SeafDirent *dent1, SeafDirent *dent2) { return (strcmp(dent1->id, dent2->id) == 0 && dent1->mode == dent2->mode && dent1->mtime == dent2->mtime); } typedef struct { HttpTxTask *task; gint64 delta; GHashTable *active_paths; } CalcQuotaDeltaData; static int check_quota_and_active_paths_diff_files (int n, const char *basedir, SeafDirent *files[], void *vdata) { CalcQuotaDeltaData *data = vdata; SeafDirent *file1 = files[0]; SeafDirent *file2 = files[1]; gint64 size1, size2; char *path; if (file1 && file2) { size1 = file1->size; size2 = file2->size; data->delta += (size1 - size2); if (!dirent_same (file1, file2)) { path = g_strconcat(basedir, file1->name, NULL); g_hash_table_replace (data->active_paths, path, (void*)(long)S_IFREG); } } else if (file1 && !file2) { data->delta += file1->size; path = g_strconcat (basedir, file1->name, NULL); g_hash_table_replace (data->active_paths, path, (void*)(long)S_IFREG); } else if (!file1 && file2) { data->delta -= file2->size; } return 0; } static int check_quota_and_active_paths_diff_dirs (int n, const char *basedir, SeafDirent *dirs[], void *vdata, gboolean *recurse) { CalcQuotaDeltaData *data = vdata; SeafDirent *dir1 = dirs[0]; SeafDirent *dir2 = dirs[1]; char *path; /* When a new empty dir is created, or a dir became empty. */ if ((!dir2 && dir1 && strcmp(dir1->id, EMPTY_SHA1) == 0) || (dir2 && dir1 && strcmp(dir1->id, EMPTY_SHA1) == 0 && strcmp(dir2->id, EMPTY_SHA1) != 0)) { path = g_strconcat (basedir, dir1->name, NULL); g_hash_table_replace (data->active_paths, path, (void*)(long)S_IFDIR); } return 0; } static int calculate_upload_size_delta_and_active_paths (HttpTxTask *task, gint64 *delta, GHashTable *active_paths) { int ret = 0; SeafBranch *local = NULL, *master = NULL; SeafCommit *local_head = NULL, *master_head = NULL; local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Branch local not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } local_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, local->commit_id); if (!local_head) { seaf_warning ("Local head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, master->commit_id); if (!master_head) { seaf_warning ("Master head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } CalcQuotaDeltaData data; memset (&data, 0, sizeof(data)); data.task = task; data.active_paths = active_paths; DiffOptions opts; memset (&opts, 0, sizeof(opts)); memcpy (opts.store_id, task->repo_id, 36); opts.version = task->repo_version; opts.file_cb = check_quota_and_active_paths_diff_files; opts.dir_cb = check_quota_and_active_paths_diff_dirs; opts.data = &data; const char *trees[2]; trees[0] = local_head->root_id; trees[1] = master_head->root_id; if (diff_trees (2, trees, &opts) < 0) { seaf_warning ("Failed to diff local and master head for repo %.8s.\n", task->repo_id); ret = -1; goto out; } *delta = data.delta; out: seaf_branch_unref (local); seaf_branch_unref (master); seaf_commit_unref (local_head); seaf_commit_unref (master_head); return ret; } static int check_quota (HttpTxTask *task, Connection *conn, gint64 delta) { CURL *curl; char *url; int status; int ret = 0; curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/quota-check/?delta=%"G_GINT64_FORMAT"", task->host, task->repo_id, delta); else url = g_strdup_printf ("%s/repo/%s/quota-check/?delta=%"G_GINT64_FORMAT"", task->host, task->repo_id, delta); int curl_error; if (http_get (curl, url, task->token, &status, NULL, NULL, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; } out: g_free (url); curl_easy_reset (curl); return ret; } static int send_commit_object (HttpTxTask *task, Connection *conn) { CURL *curl; char *url; int status; char *data; int len; int ret = 0; if (seaf_obj_store_read_obj (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, task->head, (void**)&data, &len) < 0) { seaf_warning ("Failed to read commit %s.\n", task->head); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; return -1; } curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/commit/%s", task->host, task->repo_id, task->head); else url = g_strdup_printf ("%s/repo/%s/commit/%s", task->host, task->repo_id, task->head); int curl_error; if (http_put (curl, url, task->token, data, len, NULL, NULL, &status, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for PUT %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; } out: g_free (url); curl_easy_reset (curl); g_free (data); return ret; } typedef struct { GList **pret; GHashTable *checked_objs; } CalcFsListData; static int collect_file_ids (int n, const char *basedir, SeafDirent *files[], void *vdata) { SeafDirent *file1 = files[0]; SeafDirent *file2 = files[1]; CalcFsListData *data = vdata; GList **pret = data->pret; int dummy; if (!file1 || strcmp (file1->id, EMPTY_SHA1) == 0) return 0; if (g_hash_table_lookup (data->checked_objs, file1->id)) return 0; if (!file2 || strcmp (file1->id, file2->id) != 0) { *pret = g_list_prepend (*pret, g_strdup(file1->id)); g_hash_table_insert (data->checked_objs, g_strdup(file1->id), &dummy); } return 0; } static int collect_dir_ids (int n, const char *basedir, SeafDirent *dirs[], void *vdata, gboolean *recurse) { SeafDirent *dir1 = dirs[0]; SeafDirent *dir2 = dirs[1]; CalcFsListData *data = vdata; GList **pret = data->pret; int dummy; if (!dir1 || strcmp (dir1->id, EMPTY_SHA1) == 0) return 0; if (g_hash_table_lookup (data->checked_objs, dir1->id)) return 0; if (!dir2 || strcmp (dir1->id, dir2->id) != 0) { *pret = g_list_prepend (*pret, g_strdup(dir1->id)); g_hash_table_insert (data->checked_objs, g_strdup(dir1->id), &dummy); } return 0; } static GList * calculate_send_fs_object_list (HttpTxTask *task) { GList *ret = NULL; SeafBranch *local = NULL, *master = NULL; SeafCommit *local_head = NULL, *master_head = NULL; GList *ptr; local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Branch local not found for repo %.8s.\n", task->repo_id); goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); goto out; } local_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, local->commit_id); if (!local_head) { seaf_warning ("Local head commit not found for repo %.8s.\n", task->repo_id); goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, master->commit_id); if (!master_head) { seaf_warning ("Master head commit not found for repo %.8s.\n", task->repo_id); goto out; } /* Diff won't traverse the root object itself. */ if (strcmp (local_head->root_id, master_head->root_id) != 0) ret = g_list_prepend (ret, g_strdup(local_head->root_id)); CalcFsListData *data = g_new0(CalcFsListData, 1); data->pret = &ret; data->checked_objs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); DiffOptions opts; memset (&opts, 0, sizeof(opts)); memcpy (opts.store_id, task->repo_id, 36); opts.version = task->repo_version; opts.file_cb = collect_file_ids; opts.dir_cb = collect_dir_ids; opts.data = data; const char *trees[2]; trees[0] = local_head->root_id; trees[1] = master_head->root_id; if (diff_trees (2, trees, &opts) < 0) { seaf_warning ("Failed to diff local and master head for repo %.8s.\n", task->repo_id); for (ptr = ret; ptr; ptr = ptr->next) g_free (ptr->data); ret = NULL; } g_hash_table_destroy (data->checked_objs); g_free (data); out: seaf_branch_unref (local); seaf_branch_unref (master); seaf_commit_unref (local_head); seaf_commit_unref (master_head); return ret; } #define ID_LIST_SEGMENT_N 1000 static int upload_check_id_list_segment (HttpTxTask *task, Connection *conn, const char *url, GList **send_id_list, GList **recv_id_list) { json_t *array; json_error_t jerror; char *obj_id; int n_sent = 0; char *data = NULL; int len; CURL *curl; int status; char *rsp_content = NULL; gint64 rsp_size; int ret = 0; /* Convert object id list to JSON format. */ array = json_array (); while (*send_id_list != NULL) { obj_id = (*send_id_list)->data; json_array_append_new (array, json_string(obj_id)); *send_id_list = g_list_delete_link (*send_id_list, *send_id_list); g_free (obj_id); if (++n_sent >= ID_LIST_SEGMENT_N) break; } seaf_debug ("Check %d ids for %s:%s.\n", n_sent, task->host, task->repo_id); data = json_dumps (array, 0); len = strlen(data); json_decref (array); /* Send fs object id list. */ curl = conn->curl; int curl_error; if (http_post (curl, url, task->token, data, len, &status, &rsp_content, &rsp_size, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for POST %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto out; } /* Process needed object id list. */ array = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!array) { seaf_warning ("Invalid JSON response from the server: %s.\n", jerror.text); task->error = HTTP_TASK_ERR_SERVER; ret = -1; goto out; } int i; size_t n = json_array_size (array); json_t *str; seaf_debug ("%lu objects or blocks are needed for %s:%s.\n", n, task->host, task->repo_id); for (i = 0; i < n; ++i) { str = json_array_get (array, i); if (!str) { seaf_warning ("Invalid JSON response from the server.\n"); json_decref (array); ret = -1; goto out; } *recv_id_list = g_list_prepend (*recv_id_list, g_strdup(json_string_value(str))); } json_decref (array); out: curl_easy_reset (curl); g_free (data); g_free (rsp_content); return ret; } #define MAX_OBJECT_PACK_SIZE (1 << 20) /* 1MB */ typedef struct { char obj_id[40]; guint32 obj_size; guint8 object[0]; } __attribute__((__packed__)) ObjectHeader; static int send_fs_objects (HttpTxTask *task, Connection *conn, GList **send_fs_list) { struct evbuffer *buf; ObjectHeader hdr; char *obj_id; char *data; int len; int total_size; unsigned char *package; CURL *curl; char *url = NULL; int status; int ret = 0; int n_sent = 0; buf = evbuffer_new (); curl = conn->curl; while (*send_fs_list != NULL) { obj_id = (*send_fs_list)->data; if (seaf_obj_store_read_obj (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, obj_id, (void **)&data, &len) < 0) { seaf_warning ("Failed to read fs object %s in repo %s.\n", obj_id, task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; ret = -1; goto out; } ++n_sent; memcpy (hdr.obj_id, obj_id, 40); hdr.obj_size = htonl (len); evbuffer_add (buf, &hdr, sizeof(hdr)); evbuffer_add (buf, data, len); g_free (data); *send_fs_list = g_list_delete_link (*send_fs_list, *send_fs_list); g_free (obj_id); total_size = evbuffer_get_length (buf); if (total_size >= MAX_OBJECT_PACK_SIZE) break; } seaf_debug ("Sending %d fs objects for %s:%s.\n", n_sent, task->host, task->repo_id); package = evbuffer_pullup (buf, -1); if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/recv-fs/", task->host, task->repo_id); else url = g_strdup_printf ("%s/repo/%s/recv-fs/", task->host, task->repo_id); int curl_error; if (http_post (curl, url, task->token, (char *)package, evbuffer_get_length(buf), &status, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for POST %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; } out: g_free (url); evbuffer_free (buf); curl_easy_reset (curl); return ret; } typedef struct { GList *block_list; GHashTable *added_blocks; HttpTxTask *task; } CalcBlockListData; static void add_to_block_list (GList **block_list, GHashTable *added_blocks, const char *block_id) { int dummy; if (g_hash_table_lookup (added_blocks, block_id)) return; *block_list = g_list_prepend (*block_list, g_strdup(block_id)); g_hash_table_insert (added_blocks, g_strdup(block_id), &dummy); } static int block_list_diff_files (int n, const char *basedir, SeafDirent *files[], void *vdata) { SeafDirent *file1 = files[0]; SeafDirent *file2 = files[1]; CalcBlockListData *data = vdata; HttpTxTask *task = data->task; Seafile *f1 = NULL, *f2 = NULL; int i; if (file1 && strcmp (file1->id, EMPTY_SHA1) != 0) { if (!file2) { f1 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file1->id); if (!f1) { seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file1->id); return -1; } for (i = 0; i < f1->n_blocks; ++i) add_to_block_list (&data->block_list, data->added_blocks, f1->blk_sha1s[i]); seafile_unref (f1); } else if (strcmp (file1->id, file2->id) != 0) { f1 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file1->id); if (!f1) { seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file1->id); return -1; } f2 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file2->id); if (!f2) { seafile_unref (f1); seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file2->id); return -1; } GHashTable *h = g_hash_table_new (g_str_hash, g_str_equal); int dummy; for (i = 0; i < f2->n_blocks; ++i) g_hash_table_insert (h, f2->blk_sha1s[i], &dummy); for (i = 0; i < f1->n_blocks; ++i) if (!g_hash_table_lookup (h, f1->blk_sha1s[i])) add_to_block_list (&data->block_list, data->added_blocks, f1->blk_sha1s[i]); seafile_unref (f1); seafile_unref (f2); g_hash_table_destroy (h); } } return 0; } static int block_list_diff_dirs (int n, const char *basedir, SeafDirent *dirs[], void *data, gboolean *recurse) { /* Do nothing */ return 0; } static int calculate_block_list (HttpTxTask *task, GList **plist) { int ret = 0; SeafBranch *local = NULL, *master = NULL; SeafCommit *local_head = NULL, *master_head = NULL; local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Branch local not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } local_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, local->commit_id); if (!local_head) { seaf_warning ("Local head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, master->commit_id); if (!master_head) { seaf_warning ("Master head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } CalcBlockListData data; memset (&data, 0, sizeof(data)); data.added_blocks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); data.task = task; DiffOptions opts; memset (&opts, 0, sizeof(opts)); memcpy (opts.store_id, task->repo_id, 36); opts.version = task->repo_version; opts.file_cb = block_list_diff_files; opts.dir_cb = block_list_diff_dirs; opts.data = &data; const char *trees[2]; trees[0] = local_head->root_id; trees[1] = master_head->root_id; if (diff_trees (2, trees, &opts) < 0) { seaf_warning ("Failed to diff local and master head for repo %.8s.\n", task->repo_id); g_hash_table_destroy (data.added_blocks); GList *ptr; for (ptr = data.block_list; ptr; ptr = ptr->next) g_free (ptr->data); ret = -1; goto out; } g_hash_table_destroy (data.added_blocks); *plist = data.block_list; out: seaf_branch_unref (local); seaf_branch_unref (master); seaf_commit_unref (local_head); seaf_commit_unref (master_head); return ret; } typedef struct { char block_id[41]; BlockHandle *block; HttpTxTask *task; } SendBlockData; static size_t send_block_callback (void *ptr, size_t size, size_t nmemb, void *userp) { size_t realsize = size *nmemb; SendBlockData *data = userp; HttpTxTask *task = data->task; int n; if (task->state == HTTP_TASK_STATE_CANCELED || task->all_stop) return CURL_READFUNC_ABORT; n = seaf_block_manager_read_block (seaf->block_mgr, data->block, ptr, realsize); if (n < 0) { seaf_warning ("Failed to read block %s in repo %.8s.\n", data->block_id, task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; return CURL_READFUNC_ABORT; } /* Update global transferred bytes. */ g_atomic_int_add (&(seaf->sync_mgr->sent_bytes), n); /* Update transferred bytes for this task */ g_atomic_int_add (&task->tx_bytes, n); /* If uploaded bytes exceeds the limit, wait until the counter * is reset. We check the counter every 100 milliseconds, so we * can waste up to 100 milliseconds without sending data after * the counter is reset. */ while (1) { gint sent = g_atomic_int_get(&(seaf->sync_mgr->sent_bytes)); if (seaf->sync_mgr->upload_limit > 0 && sent > seaf->sync_mgr->upload_limit) /* 100 milliseconds */ g_usleep (100000); else break; } return n; } static int send_block (HttpTxTask *task, Connection *conn, const char *block_id, guint32 *psize) { CURL *curl; char *url; int status; BlockMetadata *bmd; BlockHandle *block; int ret = 0; bmd = seaf_block_manager_stat_block (seaf->block_mgr, task->repo_id, task->repo_version, block_id); if (!bmd) { seaf_warning ("Failed to stat block %s in repo %s.\n", block_id, task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; return -1; } block = seaf_block_manager_open_block (seaf->block_mgr, task->repo_id, task->repo_version, block_id, BLOCK_READ); if (!block) { seaf_warning ("Failed to open block %s in repo %s.\n", block_id, task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; g_free (bmd); return -1; } SendBlockData data; memset (&data, 0, sizeof(data)); memcpy (data.block_id, block_id, 40); data.block = block; data.task = task; curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/block/%s", task->host, task->repo_id, block_id); else url = g_strdup_printf ("%s/repo/%s/block/%s", task->host, task->repo_id, block_id); int curl_error; if (http_put (curl, url, task->token, NULL, bmd->size, send_block_callback, &data, &status, NULL, NULL, TRUE, &curl_error) < 0) { if (task->state == HTTP_TASK_STATE_CANCELED) goto out; if (task->error == HTTP_TASK_OK) { /* Only release connection when it's a network error */ conn->release = TRUE; handle_curl_errors (task, curl_error); } ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for PUT %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto out; } if (psize) *psize = bmd->size; out: g_free (url); curl_easy_reset (curl); g_free (bmd); seaf_block_manager_close_block (seaf->block_mgr, block); seaf_block_manager_block_handle_free (seaf->block_mgr, block); return ret; } typedef struct BlockUploadData { HttpTxTask *http_task; ConnectionPool *cpool; GAsyncQueue *finished_tasks; } BlockUploadData; typedef struct BlockUploadTask { char block_id[41]; int result; guint32 block_size; } BlockUploadTask; static void block_upload_task_free (BlockUploadTask *task) { g_free (task); } static void upload_block_thread_func (gpointer data, gpointer user_data) { BlockUploadTask *task = data; BlockUploadData *tx_data = user_data; HttpTxTask *http_task = tx_data->http_task; Connection *conn; int ret = 0; conn = connection_pool_get_connection (tx_data->cpool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", http_task->host); http_task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; ret = -1; goto out; } ret = send_block (http_task, conn, task->block_id, &task->block_size); connection_pool_return_connection (tx_data->cpool, conn); out: task->result = ret; g_async_queue_push (tx_data->finished_tasks, task); } #define DEFAULT_UPLOAD_BLOCK_THREADS 3 static int multi_threaded_send_blocks (HttpTxTask *http_task, GList *block_list) { HttpTxPriv *priv = seaf->http_tx_mgr->priv; GThreadPool *tpool; GAsyncQueue *finished_tasks; GHashTable *pending_tasks; ConnectionPool *cpool; GList *ptr; char *block_id; BlockUploadTask *task; SyncInfo *info; int ret = 0; if (block_list == NULL) return 0; cpool = find_connection_pool (priv, http_task->host); if (!cpool) { seaf_warning ("Failed to create connection pool for host %s.\n", http_task->host); http_task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; return -1; } finished_tasks = g_async_queue_new (); BlockUploadData data; data.http_task = http_task; data.finished_tasks = finished_tasks; data.cpool = cpool; tpool = g_thread_pool_new (upload_block_thread_func, &data, DEFAULT_UPLOAD_BLOCK_THREADS, FALSE, NULL); pending_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)block_upload_task_free); info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, http_task->repo_id); for (ptr = block_list; ptr; ptr = ptr->next) { block_id = ptr->data; task = g_new0 (BlockUploadTask, 1); memcpy (task->block_id, block_id, 40); if (!g_hash_table_lookup (pending_tasks, block_id)) { g_hash_table_insert (pending_tasks, g_strdup(block_id), task); g_thread_pool_push (tpool, task, NULL); } else { g_free (task); } } while ((task = g_async_queue_pop (finished_tasks)) != NULL) { if (task->result < 0 || http_task->state == HTTP_TASK_STATE_CANCELED) { ret = task->result; http_task->all_stop = TRUE; break; } ++(http_task->done_blocks); if (info && info->multipart_upload) { info->uploaded_bytes += (gint64)task->block_size; } g_hash_table_remove (pending_tasks, task->block_id); if (g_hash_table_size(pending_tasks) == 0) break; } g_thread_pool_free (tpool, TRUE, TRUE); g_hash_table_destroy (pending_tasks); g_async_queue_unref (finished_tasks); return ret; } static int update_branch (HttpTxTask *task, Connection *conn) { CURL *curl; char *url; int status; int ret = 0; curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/commit/HEAD/?head=%s", task->host, task->repo_id, task->head); else url = g_strdup_printf ("%s/repo/%s/commit/HEAD/?head=%s", task->host, task->repo_id, task->head); int curl_error; if (http_put (curl, url, task->token, NULL, 0, NULL, NULL, &status, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for PUT %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; } out: g_free (url); curl_easy_reset (curl); return ret; } static void update_master_branch (HttpTxTask *task) { SeafBranch *branch; branch = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!branch) { branch = seaf_branch_new ("master", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } else { seaf_branch_set_commit (branch, task->head); seaf_branch_manager_update_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } } static void set_path_status_syncing (gpointer key, gpointer value, gpointer user_data) { HttpTxTask *task = user_data; char *path = key; int mode = (int)(long)value; seaf_sync_manager_update_active_path (seaf->sync_mgr, task->repo_id, path, mode, SYNC_STATUS_SYNCING); } static void set_path_status_synced (gpointer key, gpointer value, gpointer user_data) { HttpTxTask *task = user_data; char *path = key; int mode = (int)(long)value; seaf_sync_manager_update_active_path (seaf->sync_mgr, task->repo_id, path, mode, SYNC_STATUS_SYNCED); } static void * http_upload_thread (void *vdata) { HttpTxTask *task = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn = NULL; char *url = NULL; GList *send_fs_list = NULL, *needed_fs_list = NULL; GList *block_list = NULL, *needed_block_list = NULL; GHashTable *active_paths = NULL; SeafBranch *local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Failed to get branch local of repo %.8s.\n", task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; return NULL; } memcpy (task->head, local->commit_id, 40); seaf_branch_unref (local); pool = find_connection_pool (priv, task->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; goto out; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; goto out; } /* seaf_message ("Upload with HTTP sync protocol version %d.\n", */ /* task->protocol_version); */ transition_state (task, task->state, HTTP_TASK_RT_STATE_CHECK); gint64 delta = 0; active_paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (calculate_upload_size_delta_and_active_paths (task, &delta, active_paths) < 0) { seaf_warning ("Failed to calculate upload size delta for repo %s.\n", task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; goto out; } g_hash_table_foreach (active_paths, set_path_status_syncing, task); if (check_permission (task, conn) < 0) { seaf_warning ("Upload permission denied for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (check_quota (task, conn, delta) < 0) { seaf_warning ("Not enough quota for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; transition_state (task, task->state, HTTP_TASK_RT_STATE_COMMIT); if (send_commit_object (task, conn) < 0) { seaf_warning ("Failed to send head commit for repo %.8s.\n", task->repo_id); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; transition_state (task, task->state, HTTP_TASK_RT_STATE_FS); send_fs_list = calculate_send_fs_object_list (task); if (!send_fs_list) { seaf_warning ("Failed to calculate fs object list for repo %.8s.\n", task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; goto out; } if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/check-fs/", task->host, task->repo_id); else url = g_strdup_printf ("%s/repo/%s/check-fs/", task->host, task->repo_id); while (send_fs_list != NULL) { if (upload_check_id_list_segment (task, conn, url, &send_fs_list, &needed_fs_list) < 0) { seaf_warning ("Failed to check fs list for repo %.8s.\n", task->repo_id); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; } g_free (url); url = NULL; while (needed_fs_list != NULL) { if (send_fs_objects (task, conn, &needed_fs_list) < 0) { seaf_warning ("Failed to send fs objects for repo %.8s.\n", task->repo_id); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; } transition_state (task, task->state, HTTP_TASK_RT_STATE_BLOCK); if (calculate_block_list (task, &block_list) < 0) { seaf_warning ("Failed to calculate block list for repo %.8s.\n", task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; goto out; } if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/check-blocks/", task->host, task->repo_id); else url = g_strdup_printf ("%s/repo/%s/check-blocks/", task->host, task->repo_id); while (block_list != NULL) { if (upload_check_id_list_segment (task, conn, url, &block_list, &needed_block_list) < 0) { seaf_warning ("Failed to check block list for repo %.8s.\n", task->repo_id); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; } g_free (url); url = NULL; task->n_blocks = g_list_length (needed_block_list); seaf_debug ("%d blocks to send for %s:%s.\n", task->n_blocks, task->host, task->repo_id); if (multi_threaded_send_blocks(task, needed_block_list) < 0 || task->state == HTTP_TASK_STATE_CANCELED) goto out; transition_state (task, task->state, HTTP_TASK_RT_STATE_UPDATE_BRANCH); if (update_branch (task, conn) < 0) { seaf_warning ("Failed to update branch of repo %.8s.\n", task->repo_id); goto out; } /* After successful upload, the cached 'master' branch should be updated to * the head commit of 'local' branch. */ update_master_branch (task); if (active_paths != NULL) g_hash_table_foreach (active_paths, set_path_status_synced, task); out: string_list_free (send_fs_list); string_list_free (needed_fs_list); string_list_free (block_list); string_list_free (needed_block_list); if (active_paths) g_hash_table_destroy (active_paths); g_free (url); connection_pool_return_connection (pool, conn); return vdata; } static void http_upload_done (void *vdata) { HttpTxTask *task = vdata; if (task->error != HTTP_TASK_OK) transition_state (task, HTTP_TASK_STATE_ERROR, HTTP_TASK_RT_STATE_FINISHED); else if (task->state == HTTP_TASK_STATE_CANCELED) transition_state (task, task->state, HTTP_TASK_RT_STATE_FINISHED); else transition_state (task, HTTP_TASK_STATE_FINISHED, HTTP_TASK_RT_STATE_FINISHED); } /* Download */ static void *http_download_thread (void *vdata); static void http_download_done (void *vdata); static void notify_conflict (CEvent *event, void *data); int http_tx_manager_add_download (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, const char *server_head_id, gboolean is_clone, const char *passwd, const char *worktree, int protocol_version, const char *email, gboolean use_fileserver_port, const char *repo_name, GError **error) { HttpTxTask *task; SeafRepo *repo; if (!repo_id || !token || !host || !server_head_id || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty argument(s)"); return -1; } if (!is_clone) { repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo not found"); return -1; } } clean_tasks_for_repo (manager, repo_id); task = http_tx_task_new (manager, repo_id, repo_version, HTTP_TASK_TYPE_DOWNLOAD, is_clone, host, token, passwd, worktree); memcpy (task->head, server_head_id, 40); task->protocol_version = protocol_version; task->email = g_strdup(email); task->state = HTTP_TASK_STATE_NORMAL; task->use_fileserver_port = use_fileserver_port; task->blk_ref_cnts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); pthread_mutex_init (&task->ref_cnt_lock, NULL); g_hash_table_insert (manager->priv->download_tasks, g_strdup(repo_id), task); task->cevent_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)notify_conflict, NULL); task->repo_name = g_strdup(repo_name); if (ccnet_job_manager_schedule_job (seaf->job_mgr, http_download_thread, http_download_done, task) < 0) { g_hash_table_remove (manager->priv->download_tasks, repo_id); return -1; } return 0; } static int get_commit_object (HttpTxTask *task, Connection *conn) { CURL *curl; char *url; int status; char *rsp_content = NULL; gint64 rsp_size; int ret = 0; curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/commit/%s", task->host, task->repo_id, task->head); else url = g_strdup_printf ("%s/repo/%s/commit/%s", task->host, task->repo_id, task->head); int curl_error; if (http_get (curl, url, task->token, &status, &rsp_content, &rsp_size, NULL, NULL, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto out; } int rc = seaf_obj_store_write_obj (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, task->head, rsp_content, rsp_size, FALSE); if (rc < 0) { seaf_warning ("Failed to save commit %s in repo %.8s.\n", task->head, task->repo_id); task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA; ret = -1; } out: g_free (url); g_free (rsp_content); curl_easy_reset (curl); return ret; } static int get_needed_fs_id_list (HttpTxTask *task, Connection *conn, GList **fs_id_list) { SeafBranch *master; CURL *curl; char *url = NULL; int status; char *rsp_content = NULL; gint64 rsp_size; int ret = 0; json_t *array; json_error_t jerror; const char *obj_id; const char *url_prefix = (task->use_fileserver_port) ? "" : "seafhttp/"; if (!task->is_clone) { master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Failed to get branch master for repo %.8s.\n", task->repo_id); return -1; } url = g_strdup_printf ("%s/%srepo/%s/fs-id-list/" "?server-head=%s&client-head=%s", task->host, url_prefix, task->repo_id, task->head, master->commit_id); seaf_branch_unref (master); } else { url = g_strdup_printf ("%s/%srepo/%s/fs-id-list/?server-head=%s", task->host, url_prefix, task->repo_id, task->head); } curl = conn->curl; int curl_error; if (http_get (curl, url, task->token, &status, &rsp_content, &rsp_size, NULL, NULL, (!task->is_clone), &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto out; } array = json_loadb (rsp_content, rsp_size, 0, &jerror); if (!array) { seaf_warning ("Invalid JSON response from the server: %s.\n", jerror.text); task->error = HTTP_TASK_ERR_SERVER; ret = -1; goto out; } int i; size_t n = json_array_size (array); json_t *str; seaf_debug ("Received fs object list size %lu from %s:%s.\n", n, task->host, task->repo_id); task->n_fs_objs = (int)n; GHashTable *checked_objs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < n; ++i) { str = json_array_get (array, i); if (!str) { seaf_warning ("Invalid JSON response from the server.\n"); json_decref (array); string_list_free (*fs_id_list); ret = -1; goto out; } obj_id = json_string_value(str); if (g_hash_table_lookup (checked_objs, obj_id)) { ++(task->done_fs_objs); continue; } char *key = g_strdup(obj_id); g_hash_table_replace (checked_objs, key, key); if (!seaf_obj_store_obj_exists (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, obj_id)) { *fs_id_list = g_list_prepend (*fs_id_list, g_strdup(obj_id)); } else if (task->is_clone) { gboolean io_error = FALSE; gboolean sound; sound = seaf_fs_manager_verify_object (seaf->fs_mgr, task->repo_id, task->repo_version, obj_id, FALSE, &io_error); if (!sound && !io_error) { *fs_id_list = g_list_prepend (*fs_id_list, g_strdup(obj_id)); } else { ++(task->done_fs_objs); } } else { ++(task->done_fs_objs); } } json_decref (array); g_hash_table_destroy (checked_objs); out: g_free (url); g_free (rsp_content); curl_easy_reset (curl); return ret; } #define GET_FS_OBJECT_N 100 static int get_fs_objects (HttpTxTask *task, Connection *conn, GList **fs_list) { json_t *array; char *obj_id; int n_sent = 0; char *data = NULL; int len; CURL *curl; char *url = NULL; int status; char *rsp_content = NULL; gint64 rsp_size; int ret = 0; GHashTable *requested; /* Convert object id list to JSON format. */ requested = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); array = json_array (); while (*fs_list != NULL) { obj_id = (*fs_list)->data; json_array_append_new (array, json_string(obj_id)); *fs_list = g_list_delete_link (*fs_list, *fs_list); g_hash_table_replace (requested, obj_id, obj_id); if (++n_sent >= GET_FS_OBJECT_N) break; } seaf_debug ("Requesting %d fs objects from %s:%s.\n", n_sent, task->host, task->repo_id); data = json_dumps (array, 0); len = strlen(data); json_decref (array); /* Send fs object id list. */ curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/pack-fs/", task->host, task->repo_id); else url = g_strdup_printf ("%s/repo/%s/pack-fs/", task->host, task->repo_id); int curl_error; if (http_post (curl, url, task->token, data, len, &status, &rsp_content, &rsp_size, TRUE, &curl_error) < 0) { conn->release = TRUE; handle_curl_errors (task, curl_error); ret = -1; goto out; } if (status != HTTP_OK) { seaf_warning ("Bad response code for POST %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto out; } /* Save received fs objects. */ int n_recv = 0; char *p = rsp_content; ObjectHeader *hdr = (ObjectHeader *)p; char recv_obj_id[41]; int n = 0; int size; int rc; while (n < rsp_size) { memcpy (recv_obj_id, hdr->obj_id, 40); recv_obj_id[40] = 0; size = ntohl (hdr->obj_size); if (n + sizeof(ObjectHeader) + size > rsp_size) { seaf_warning ("Incomplete object package received for repo %.8s.\n", task->repo_id); task->error = HTTP_TASK_ERR_SERVER; ret = -1; goto out; } ++n_recv; rc = seaf_obj_store_write_obj (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, recv_obj_id, hdr->object, size, FALSE); if (rc < 0) { seaf_warning ("Failed to write fs object %s in repo %.8s.\n", recv_obj_id, task->repo_id); task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA; ret = -1; goto out; } g_hash_table_remove (requested, recv_obj_id); ++(task->done_fs_objs); p += (sizeof(ObjectHeader) + size); n += (sizeof(ObjectHeader) + size); hdr = (ObjectHeader *)p; } seaf_debug ("Received %d fs objects from %s:%s.\n", n_recv, task->host, task->repo_id); /* The server may not return all the objects we requested. * So we need to add back the remaining object ids into fs_list. */ GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, requested); while (g_hash_table_iter_next (&iter, &key, &value)) { obj_id = key; *fs_list = g_list_prepend (*fs_list, g_strdup(obj_id)); } g_hash_table_destroy (requested); out: g_free (url); g_free (data); g_free (rsp_content); curl_easy_reset (curl); return ret; } typedef struct { char block_id[41]; BlockHandle *block; HttpTxTask *task; } GetBlockData; static size_t get_block_callback (void *ptr, size_t size, size_t nmemb, void *userp) { size_t realsize = size *nmemb; SendBlockData *data = userp; HttpTxTask *task = data->task; size_t n; if (task->state == HTTP_TASK_STATE_CANCELED || task->all_stop) return 0; n = seaf_block_manager_write_block (seaf->block_mgr, data->block, ptr, realsize); if (n < realsize) { seaf_warning ("Failed to write block %s in repo %.8s.\n", data->block_id, task->repo_id); task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA; return n; } /* Update global transferred bytes. */ g_atomic_int_add (&(seaf->sync_mgr->recv_bytes), n); /* Update transferred bytes for this task */ g_atomic_int_add (&task->tx_bytes, n); /* If uploaded bytes exceeds the limit, wait until the counter * is reset. We check the counter every 100 milliseconds, so we * can waste up to 100 milliseconds without sending data after * the counter is reset. */ while (1) { gint sent = g_atomic_int_get(&(seaf->sync_mgr->recv_bytes)); if (seaf->sync_mgr->download_limit > 0 && sent > seaf->sync_mgr->download_limit) /* 100 milliseconds */ g_usleep (100000); else break; } return n; } int get_block (HttpTxTask *task, Connection *conn, const char *block_id) { CURL *curl; char *url; int status; BlockHandle *block; int ret = 0; int *pcnt; block = seaf_block_manager_open_block (seaf->block_mgr, task->repo_id, task->repo_version, block_id, BLOCK_WRITE); if (!block) { seaf_warning ("Failed to open block %s in repo %.8s.\n", block_id, task->repo_id); return -1; } GetBlockData data; memcpy (data.block_id, block_id, 40); data.block = block; data.task = task; curl = conn->curl; if (!task->use_fileserver_port) url = g_strdup_printf ("%s/seafhttp/repo/%s/block/%s", task->host, task->repo_id, block_id); else url = g_strdup_printf ("%s/repo/%s/block/%s", task->host, task->repo_id, block_id); int curl_error; if (http_get (curl, url, task->token, &status, NULL, NULL, get_block_callback, &data, TRUE, &curl_error) < 0) { if (task->state == HTTP_TASK_STATE_CANCELED) goto error; if (task->error == HTTP_TASK_OK) { /* Only release the connection when it's a network error. */ conn->release = TRUE; handle_curl_errors (task, curl_error); } ret = -1; goto error; } if (status != HTTP_OK) { seaf_warning ("Bad response code for GET %s: %d.\n", url, status); handle_http_errors (task, status); ret = -1; goto error; } seaf_block_manager_close_block (seaf->block_mgr, block); pthread_mutex_lock (&task->ref_cnt_lock); /* Don't overwrite the block if other thread already downloaded it. * Since we've locked ref_cnt_lock, we can be sure the block won't be removed. */ if (!seaf_block_manager_block_exists (seaf->block_mgr, task->repo_id, task->repo_version, block_id) && seaf_block_manager_commit_block (seaf->block_mgr, block) < 0) { seaf_warning ("Failed to commit block %s in repo %.8s.\n", block_id, task->repo_id); task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA; ret = -1; } if (ret == 0) { pcnt = g_hash_table_lookup (task->blk_ref_cnts, block_id); if (!pcnt) { pcnt = g_new0(int, 1); g_hash_table_insert (task->blk_ref_cnts, g_strdup(block_id), pcnt); } *pcnt += 1; } pthread_mutex_unlock (&task->ref_cnt_lock); seaf_block_manager_block_handle_free (seaf->block_mgr, block); g_free (url); return ret; error: g_free (url); seaf_block_manager_close_block (seaf->block_mgr, block); seaf_block_manager_block_handle_free (seaf->block_mgr, block); return ret; } int http_tx_task_download_file_blocks (HttpTxTask *task, const char *file_id) { Seafile *file; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn; int ret = 0; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file_id); if (!file) { seaf_warning ("Failed to find seafile object %s in repo %.8s.\n", file_id, task->repo_id); return -1; } pool = find_connection_pool (priv, task->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; seafile_unref (file); return -1; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; seafile_unref (file); return -1; } int i; char *block_id; for (i = 0; i < file->n_blocks; ++i) { block_id = file->blk_sha1s[i]; ret = get_block (task, conn, block_id); if (ret < 0 || task->state == HTTP_TASK_STATE_CANCELED) break; } connection_pool_return_connection (pool, conn); seafile_unref (file); return ret; } static int update_local_repo (HttpTxTask *task) { SeafRepo *repo; SeafCommit *new_head; SeafBranch *branch; int ret = 0; new_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, task->head); if (!new_head) { seaf_warning ("Failed to get commit %s:%s.\n", task->repo_id, task->head); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; return -1; } /* If repo doesn't exist, create it. * Note that branch doesn't exist either in this case. */ repo = seaf_repo_manager_get_repo (seaf->repo_mgr, new_head->repo_id); if (task->is_clone) { if (repo != NULL) goto out; repo = seaf_repo_new (new_head->repo_id, NULL, NULL); if (repo == NULL) { /* create repo failed */ task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; ret = -1; goto out; } seaf_repo_from_commit (repo, new_head); seaf_repo_manager_add_repo (seaf->repo_mgr, repo); /* If it's a new repo, create 'local' and 'master' branch */ branch = seaf_branch_new ("local", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); branch = seaf_branch_new ("master", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } else { if (!repo) { task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; ret = -1; goto out; } branch = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!branch) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); task->error = HTTP_TASK_ERR_BAD_LOCAL_DATA; ret = -1; goto out; } seaf_branch_set_commit (branch, new_head->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); /* Update repo head branch. */ seaf_branch_set_commit (repo->head, new_head->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, repo->head); if (g_strcmp0 (repo->name, new_head->repo_name) != 0) seaf_repo_set_name (repo, new_head->repo_name); } out: seaf_commit_unref (new_head); return ret; } static void * http_download_thread (void *vdata) { HttpTxTask *task = vdata; HttpTxPriv *priv = seaf->http_tx_mgr->priv; ConnectionPool *pool; Connection *conn = NULL; GList *fs_id_list = NULL; pool = find_connection_pool (priv, task->host); if (!pool) { seaf_warning ("Failed to create connection pool for host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; goto out; } conn = connection_pool_get_connection (pool); if (!conn) { seaf_warning ("Failed to get connection to host %s.\n", task->host); task->error = HTTP_TASK_ERR_NOT_ENOUGH_MEMORY; goto out; } /* seaf_message ("Download with HTTP sync protocol version %d.\n", */ /* task->protocol_version); */ transition_state (task, task->state, HTTP_TASK_RT_STATE_CHECK); if (check_permission (task, conn) < 0) { seaf_warning ("Download permission denied for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; transition_state (task, task->state, HTTP_TASK_RT_STATE_COMMIT); if (get_commit_object (task, conn) < 0) { seaf_warning ("Failed to get server head commit for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; transition_state (task, task->state, HTTP_TASK_RT_STATE_FS); if (get_needed_fs_id_list (task, conn, &fs_id_list) < 0) { seaf_warning ("Failed to get fs id list for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; while (fs_id_list != NULL) { if (get_fs_objects (task, conn, &fs_id_list) < 0) { seaf_warning ("Failed to get fs objects for repo %.8s on server %s.\n", task->repo_id, task->host); goto out; } if (task->state == HTTP_TASK_STATE_CANCELED) goto out; } transition_state (task, task->state, HTTP_TASK_RT_STATE_BLOCK); /* Record download head commit id, so that we can resume download * if this download is interrupted. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo_id, REPO_PROP_DOWNLOAD_HEAD, task->head); int rc = seaf_repo_fetch_and_checkout (NULL, task, TRUE, task->head); switch (rc) { case FETCH_CHECKOUT_SUCCESS: break; case FETCH_CHECKOUT_CANCELED: goto out; case FETCH_CHECKOUT_FAILED: task->error = HTTP_TASK_ERR_WRITE_LOCAL_DATA; goto out; case FETCH_CHECKOUT_TRANSFER_ERROR: goto out; case FETCH_CHECKOUT_LOCKED: task->error = HTTP_TASK_ERR_FILES_LOCKED; goto out; } update_local_repo (task); out: connection_pool_return_connection (pool, conn); string_list_free (fs_id_list); return vdata; } static void http_download_done (void *vdata) { HttpTxTask *task = vdata; if (task->error != HTTP_TASK_OK) transition_state (task, HTTP_TASK_STATE_ERROR, HTTP_TASK_RT_STATE_FINISHED); else if (task->state == HTTP_TASK_STATE_CANCELED) transition_state (task, task->state, HTTP_TASK_RT_STATE_FINISHED); else transition_state (task, HTTP_TASK_STATE_FINISHED, HTTP_TASK_RT_STATE_FINISHED); } typedef struct FileConflictData { char *repo_id; char *repo_name; char *path; } FileConflictData; static void notify_conflict (CEvent *event, void *handler_data) { FileConflictData *data = event->data; json_t *object; char *str; object = json_object (); json_object_set_new (object, "repo_id", json_string(data->repo_id)); json_object_set_new (object, "repo_name", json_string(data->repo_name)); json_object_set_new (object, "path", json_string(data->path)); str = json_dumps (object, 0); seaf_mq_manager_publish_notification (seaf->mq_mgr, "sync.conflict", str); free (str); json_decref (object); g_free (data->repo_id); g_free (data->repo_name); g_free (data->path); g_free (data); } void http_tx_manager_notify_conflict (HttpTxTask *task, const char *path) { FileConflictData *data = g_new0 (FileConflictData, 1); data->repo_id = g_strdup(task->repo_id); data->repo_name = g_strdup(task->repo_name); data->path = g_strdup(path); cevent_manager_add_event (seaf->ev_mgr, task->cevent_id, data); } GList* http_tx_manager_get_upload_tasks (HttpTxManager *manager) { return g_hash_table_get_values (manager->priv->upload_tasks); } GList* http_tx_manager_get_download_tasks (HttpTxManager *manager) { return g_hash_table_get_values (manager->priv->download_tasks); } HttpTxTask * http_tx_manager_find_task (HttpTxManager *manager, const char *repo_id) { HttpTxTask *task = NULL; task = g_hash_table_lookup (manager->priv->upload_tasks, repo_id); if (task) return task; task = g_hash_table_lookup (manager->priv->download_tasks, repo_id); return task; } void http_tx_manager_cancel_task (HttpTxManager *manager, const char *repo_id, int task_type) { HttpTxTask *task = NULL; if (task_type == HTTP_TASK_TYPE_DOWNLOAD) task = g_hash_table_lookup (manager->priv->download_tasks, repo_id); else task = g_hash_table_lookup (manager->priv->upload_tasks, repo_id); if (!task) return; if (task->state != HTTP_TASK_STATE_NORMAL) { seaf_warning ("Cannot cancel task not in NORMAL state.\n"); return; } if (task->runtime_state == HTTP_TASK_RT_STATE_INIT) { transition_state (task, HTTP_TASK_STATE_CANCELED, TASK_RT_STATE_FINISHED); return; } /* Only change state. runtime_state will be changed in worker thread. */ transition_state (task, HTTP_TASK_STATE_CANCELED, task->runtime_state); } int http_tx_task_get_rate (HttpTxTask *task) { return task->last_tx_bytes; } const char * http_task_state_to_str (int state) { if (state < 0 || state >= N_HTTP_TASK_STATE) return "unknown"; return http_task_state_str[state]; } const char * http_task_rt_state_to_str (int rt_state) { if (rt_state < 0 || rt_state >= N_HTTP_TASK_RT_STATE) return "unknown"; return http_task_rt_state_str[rt_state]; } const char * http_task_error_str (int task_errno) { if (task_errno < 0 || task_errno >= N_HTTP_TASK_ERROR) return "unknown error"; return http_task_error_strs[task_errno]; } seafile-6.1.5/daemon/http-tx-mgr.h000066400000000000000000000231741323477647300167710ustar00rootroot00000000000000#ifndef HTTP_TX_MGR_H #define HTTP_TX_MGR_H #include enum { HTTP_TASK_TYPE_DOWNLOAD = 0, HTTP_TASK_TYPE_UPLOAD, }; /** * The state that can be set by user. * * A task in NORMAL state can be canceled; * A task in RT_STATE_FINISHED can be removed. */ enum HttpTaskState { HTTP_TASK_STATE_NORMAL = 0, HTTP_TASK_STATE_CANCELED, HTTP_TASK_STATE_FINISHED, HTTP_TASK_STATE_ERROR, N_HTTP_TASK_STATE, }; enum HttpTaskRuntimeState { HTTP_TASK_RT_STATE_INIT = 0, HTTP_TASK_RT_STATE_CHECK, HTTP_TASK_RT_STATE_COMMIT, HTTP_TASK_RT_STATE_FS, HTTP_TASK_RT_STATE_BLOCK, /* Only used in upload. */ HTTP_TASK_RT_STATE_UPDATE_BRANCH, /* Only used in upload. */ HTTP_TASK_RT_STATE_FINISHED, N_HTTP_TASK_RT_STATE, }; enum HttpTaskError { HTTP_TASK_OK = 0, HTTP_TASK_ERR_FORBIDDEN, HTTP_TASK_ERR_NET, HTTP_TASK_ERR_RESOLVE_PROXY, HTTP_TASK_ERR_RESOLVE_HOST, HTTP_TASK_ERR_CONNECT, HTTP_TASK_ERR_SSL, HTTP_TASK_ERR_TX, HTTP_TASK_ERR_TX_TIMEOUT, HTTP_TASK_ERR_UNHANDLED_REDIRECT, HTTP_TASK_ERR_SERVER, HTTP_TASK_ERR_BAD_REQUEST, HTTP_TASK_ERR_BAD_LOCAL_DATA, HTTP_TASK_ERR_NOT_ENOUGH_MEMORY, HTTP_TASK_ERR_WRITE_LOCAL_DATA, HTTP_TASK_ERR_NO_QUOTA, HTTP_TASK_ERR_FILES_LOCKED, HTTP_TASK_ERR_REPO_DELETED, HTTP_TASK_ERR_REPO_CORRUPTED, HTTP_TASK_ERR_UNKNOWN, N_HTTP_TASK_ERROR, }; struct _SeafileSession; struct _HttpTxPriv; struct _HttpTxManager { struct _SeafileSession *seaf; struct _HttpTxPriv *priv; }; typedef struct _HttpTxManager HttpTxManager; struct _HttpTxTask { HttpTxManager *manager; char repo_id[37]; int repo_version; char *token; int protocol_version; int type; char *host; gboolean is_clone; char *email; gboolean use_fileserver_port; char head[41]; char *passwd; char *worktree; int state; int runtime_state; int error; /* Used to signify stop transfer for all threads. */ gboolean all_stop; /* When downloading with multi-thread, a block may be shared by * multiple files. We can't remove a block before all *fetched* files with * this block have been checked out. * block_id -> ref_count. */ GHashTable *blk_ref_cnts; pthread_mutex_t ref_cnt_lock; /* For clone fs object progress */ int n_fs_objs; int done_fs_objs; /* For upload progress */ int n_blocks; int done_blocks; /* For download progress */ int n_files; int done_files; gint tx_bytes; /* bytes transferred in this second. */ gint last_tx_bytes; /* bytes transferred in the last second. */ uint32_t cevent_id; /* Used by download task to send notification. */ char *repo_name; /* Used by download task in conflict notification. */ }; typedef struct _HttpTxTask HttpTxTask; HttpTxManager * http_tx_manager_new (struct _SeafileSession *seaf); int http_tx_manager_start (HttpTxManager *mgr); int http_tx_manager_add_download (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, const char *server_head_id, gboolean is_clone, const char *passwd, const char *worktree, int protocol_version, const char *email, gboolean use_fileserver_port, const char *repo_name, GError **error); int http_tx_manager_add_upload (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, int protocol_version, gboolean use_fileserver_port, GError **error); struct _HttpProtocolVersion { gboolean check_success; /* TRUE if we get response from the server. */ gboolean not_supported; int version; int error_code; }; typedef struct _HttpProtocolVersion HttpProtocolVersion; typedef void (*HttpProtocolVersionCallback) (HttpProtocolVersion *result, void *user_data); /* Asynchronous interface for getting protocol version from a server. * Also used to determine if the server support http sync. */ int http_tx_manager_check_protocol_version (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, HttpProtocolVersionCallback callback, void *user_data); struct _HttpHeadCommit { gboolean check_success; gboolean is_corrupt; gboolean is_deleted; char head_commit[41]; int error_code; }; typedef struct _HttpHeadCommit HttpHeadCommit; typedef void (*HttpHeadCommitCallback) (HttpHeadCommit *result, void *user_data); /* Asynchronous interface for getting head commit info from a server. */ int http_tx_manager_check_head_commit (HttpTxManager *manager, const char *repo_id, int repo_version, const char *host, const char *token, gboolean use_fileserver_port, HttpHeadCommitCallback callback, void *user_data); typedef struct _HttpFolderPermReq { char repo_id[37]; char *token; gint64 timestamp; } HttpFolderPermReq; typedef struct _HttpFolderPermRes { char repo_id[37]; gint64 timestamp; GList *user_perms; GList *group_perms; } HttpFolderPermRes; void http_folder_perm_req_free (HttpFolderPermReq *req); void http_folder_perm_res_free (HttpFolderPermRes *res); struct _HttpFolderPerms { gboolean success; GList *results; /* List of HttpFolderPermRes */ }; typedef struct _HttpFolderPerms HttpFolderPerms; typedef void (*HttpGetFolderPermsCallback) (HttpFolderPerms *result, void *user_data); /* Asynchronous interface for getting folder permissions for a repo. */ int http_tx_manager_get_folder_perms (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *folder_perm_requests, /* HttpFolderPermReq */ HttpGetFolderPermsCallback callback, void *user_data); typedef struct _HttpLockedFilesReq { char repo_id[37]; char *token; gint64 timestamp; } HttpLockedFilesReq; typedef struct _HttpLockedFilesRes { char repo_id[37]; gint64 timestamp; GHashTable *locked_files; /* path -> by_me */ } HttpLockedFilesRes; void http_locked_files_req_free (HttpLockedFilesReq *req); void http_locked_files_res_free (HttpLockedFilesRes *res); struct _HttpLockedFiles { gboolean success; GList *results; /* List of HttpLockedFilesRes */ }; typedef struct _HttpLockedFiles HttpLockedFiles; typedef void (*HttpGetLockedFilesCallback) (HttpLockedFiles *result, void *user_data); /* Asynchronous interface for getting locked files for a repo. */ int http_tx_manager_get_locked_files (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *locked_files_requests, HttpGetLockedFilesCallback callback, void *user_data); /* Synchronous interface for locking/unlocking a file on the server. */ int http_tx_manager_lock_file (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, const char *token, const char *repo_id, const char *path); int http_tx_manager_unlock_file (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, const char *token, const char *repo_id, const char *path); GHashTable * http_tx_manager_get_head_commit_ids (HttpTxManager *manager, const char *host, gboolean use_fileserver_port, GList *repo_id_list); int http_tx_task_download_file_blocks (HttpTxTask *task, const char *file_id); GList* http_tx_manager_get_upload_tasks (HttpTxManager *manager); GList* http_tx_manager_get_download_tasks (HttpTxManager *manager); HttpTxTask * http_tx_manager_find_task (HttpTxManager *manager, const char *repo_id); void http_tx_manager_cancel_task (HttpTxManager *manager, const char *repo_id, int task_type); /* Only useful for download task. */ void http_tx_manager_notify_conflict (HttpTxTask *task, const char *path); int http_tx_task_get_rate (HttpTxTask *task); const char * http_task_state_to_str (int state); const char * http_task_rt_state_to_str (int rt_state); const char * http_task_error_str (int task_errno); #endif seafile-6.1.5/daemon/merge-recursive.c000066400000000000000000001012341323477647300176670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * Recursive Merge algorithm stolen from git-merge-recursive.py by * Fredrik Kuivinen. * The thieves were Alex Riesen and Johannes Schindelin, in June/July 2006 */ #include "common.h" #ifdef WIN32 #include #endif #include "seafile-session.h" #include "index/index.h" #include "index/cache-tree.h" #include "unpack-trees.h" #include "merge-recursive.h" #include "vc-utils.h" #include "vc-common.h" #include "utils.h" /* * Since we want to write the index eventually, we cannot reuse the index * for these (temporary) data. */ struct stage_data { char *path; struct { unsigned mode; guint64 ctime; guint64 mtime; guint64 current_mtime; unsigned char sha[20]; char *modifier; } stages[4]; unsigned processed:1; }; #if 0 __attribute__((format (printf, 2, 3))) static void output(struct merge_options *o, const char *fmt, ...) { va_list ap; va_start(ap, fmt); g_string_append_vprintf(o->obuf, fmt, ap); g_string_append (o->obuf, "\n"); va_end(ap); } #endif static int add_cacheinfo(struct index_state *index, unsigned int mode, const unsigned char *sha1, const char *modifier, const char *path, const char *full_path, int stage, int refresh, int options) { struct cache_entry *ce; ce = make_cache_entry(mode, sha1, path, full_path, stage, refresh); if (!ce) { g_warning("addinfo_cache failed for path '%s'", path); return -1; } ce->modifier = g_strdup(modifier); return add_index_entry(index, ce, options); } static int seafile_merge_trees(struct merge_options *o, struct unpack_trees_options *opts, SeafDir *common, SeafDir *head, SeafDir *merge, char **error) { int rc; struct tree_desc t[3]; memset(opts, 0, sizeof(*opts)); memcpy (opts->repo_id, o->repo_id, 36); opts->version = o->version; if (o->call_depth) opts->index_only = 1; else opts->update = 1; opts->merge = 1; opts->head_idx = 2; opts->base = o->worktree; opts->fn = threeway_merge; opts->src_index = o->index; opts->dst_index = o->index; if (o->crypt) opts->crypt = o->crypt; fill_tree_descriptor(o->repo_id, o->version, t+0, common->dir_id); fill_tree_descriptor(o->repo_id, o->version, t+1, head->dir_id); fill_tree_descriptor(o->repo_id, o->version, t+2, merge->dir_id); rc = unpack_trees(3, t, opts); if (rc == 0) { discard_index(o->index); *(o->index) = opts->result; if (o->collect_blocks_only) collect_new_blocks_from_index (o->repo_id, o->version, o->index, o->bl); } tree_desc_free (t); tree_desc_free (t+1); tree_desc_free (t+2); return rc; } char *write_tree_from_memory(struct merge_options *o) { struct cache_tree *it; char root_id[41]; if (unmerged_index(o->index)) { int i; g_warning("BUG: There are unmerged index entries:\n"); for (i = 0; i < o->index->cache_nr; i++) { struct cache_entry *ce = o->index->cache[i]; if (ce_stage(ce)) g_warning("%d %.*s\n", ce_stage(ce), (int)ce_namelen(ce), ce->name); } return NULL; } /* if (!active_cache_tree) */ it = cache_tree(); if (cache_tree_update(o->repo_id, o->version, o->worktree, it, o->index->cache, o->index->cache_nr, 0, 0, commit_trees_cb) < 0) { g_warning("error building trees"); cache_tree_free (&it); return NULL; } rawdata_to_hex(it->sha1, root_id, 20); cache_tree_free (&it); return g_strdup(root_id); } static int get_files_dirs_recursive(struct merge_options *o, SeafDir *tree, char *base, int baselen) { GList *p; char *path; int ret = 0; for (p = tree->entries; p; p = p->next) { SeafDirent *dent = (SeafDirent *)p->data; SeafDir *subdir; int new_baselen; int pathlen; switch (S_IFMT & dent->mode) { case S_IFREG: pathlen = baselen + dent->name_len + 1; path = malloc(pathlen); snprintf(path, pathlen, "%s%s", base, dent->name); g_hash_table_replace(o->current_file_set, path, path); break; case S_IFDIR: /* Ignore empty dirs. */ if (memcmp (dent->id, EMPTY_SHA1, 40) == 0) break; pathlen = baselen + dent->name_len + 1; path = malloc(pathlen); snprintf(path, pathlen, "%s%s", base, dent->name); g_hash_table_replace(o->current_directory_set, path, path); snprintf(base + baselen, SEAF_PATH_MAX, "%s/", dent->name); new_baselen = baselen + dent->name_len + 1; subdir = seaf_fs_manager_get_seafdir(seaf->fs_mgr, o->repo_id, o->version, dent->id); if (!subdir) { g_warning("Failed to get dir %s\n", dent->id); return -1; } ret = get_files_dirs_recursive(o, subdir, base, new_baselen); base[baselen] = 0; seaf_dir_free (subdir); break; case S_IFLNK: break; default: break; } } return ret; } static int get_files_dirs(struct merge_options *o, SeafDir *tree) { char base[SEAF_PATH_MAX]; base[0] = 0; return get_files_dirs_recursive(o, tree, base, 0); } inline static int ce_in_unmerged_list(GList *unmerged, struct cache_entry *ce) { struct stage_data *e; if (!unmerged) return 0; /* unmerged is sorted. Only need to check the first item. */ e = unmerged->data; return (strcmp(e->path, ce->name) == 0); } /* * Create a dictionary mapping file names to stage_data objects. The * dictionary contains one entry for every path with a non-zero stage entry. */ static GList *get_unmerged(struct index_state *index) { GList *unmerged = NULL; int i; for (i = 0; i < index->cache_nr; i++) { struct stage_data *e; struct cache_entry *ce = index->cache[i]; if (!ce_stage(ce)) continue; if (!ce_in_unmerged_list(unmerged, ce)) { e = (struct stage_data *)calloc(1, sizeof(struct stage_data)); e->path = g_strdup(ce->name); unmerged = g_list_prepend(unmerged, e); } e->stages[ce_stage(ce)].ctime = ce->ce_ctime.sec; e->stages[ce_stage(ce)].mtime = ce->ce_mtime.sec; e->stages[ce_stage(ce)].current_mtime = ce->current_mtime; e->stages[ce_stage(ce)].mode = ce->ce_mode; hashcpy(e->stages[ce_stage(ce)].sha, ce->sha1); e->stages[ce_stage(ce)].modifier = g_strdup(ce->modifier); } unmerged = g_list_reverse(unmerged); return unmerged; } #if 0 static void make_room_for_directories_of_df_conflicts(struct merge_options *o, GList *entries) { /* If there are D/F conflicts, and the paths currently exist * in the working copy as a file, we want to remove them to * make room for the corresponding directory. Such paths will * later be processed in process_df_entry() at the end. If * the corresponding directory ends up being removed by the * merge, then the file will be reinstated at that time; * otherwise, if the file is not supposed to be removed by the * merge, the contents of the file will be placed in another * unique filename. * * NOTE: This function relies on the fact that entries for a * D/F conflict will appear adjacent in the index, with the * entries for the file appearing before entries for paths * below the corresponding directory. */ const char *last_file = NULL; int last_len = 0; struct stage_data *last_e; GList *p; char *real_path; for (p = entries; p != NULL; p = p->next) { struct stage_data *e = p->data; int len = strlen(e->path); /* * Check if last_file & path correspond to a D/F conflict; * i.e. whether path is last_file+'/'+. * If so, remove last_file to make room for path and friends. */ if (last_file && len > last_len && memcmp(e->path, last_file, last_len) == 0 && e->path[last_len] == '/') { real_path = g_build_path(PATH_SEPERATOR, o->worktree, last_file, NULL); seaf_util_unlink(real_path); g_free (real_path); } /* * Determine whether path could exist as a file in the * working directory as a possible D/F conflict. This * will only occur when it exists in stage 2 as a * file. */ if (S_ISREG(e->stages[2].mode) || S_ISLNK(e->stages[2].mode)) { last_file = e->path; last_len = len; last_e = e; } else { last_file = NULL; } } } #endif static int remove_path (const char *worktree, const char *name, guint64 mtime) { char *slash; char *path; SeafStat st; path = g_build_path(PATH_SEPERATOR, worktree, name, NULL); /* file doesn't exist in work tree */ if (seaf_stat (path, &st) < 0) { g_free (path); return 0; } if (S_ISREG (st.st_mode)) { /* file has been changed. */ if (mtime != st.st_mtime) { g_free (path); return -1; } seaf_util_unlink(path); } else if (S_ISDIR (st.st_mode)) { if (seaf_remove_empty_dir (path) < 0) { g_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); g_free (path); return -1; } } else { g_free (path); return 0; } slash = strrchr (path, '/'); if (slash) { do { *slash = '\0'; } while (strcmp (worktree, path) != 0 && seaf_remove_empty_dir (path) == 0 && (slash = strrchr (path, '/'))); } g_free (path); return 0; } static int remove_file(struct merge_options *o, int clean, const char *path, int no_wd, guint64 mtime) { int update_cache = o->call_depth || clean; int update_working_directory = !o->call_depth && !no_wd; if (o->collect_blocks_only) return 0; if (update_cache) { if (remove_file_from_index(o->index, path)) return -1; } if (update_working_directory) { if (remove_path(o->worktree, path, mtime) < 0) return -1; } return 0; } static int create_leading_directories(int base_len, const char *path, char **new_path, const char *conflict_suffix, int *clean) { int len = strlen(path); char buf[SEAF_PATH_MAX]; int offset = base_len, my_offset = base_len; SeafStat st; int n; memcpy (buf, path, base_len); *clean = 1; /* first create all leading directories. */ while (offset < len) { do { buf[my_offset] = path[offset]; offset++; my_offset++; } while (offset < len && path[offset] != '/'); if (offset >= len) { buf[my_offset] = 0; break; } buf[my_offset] = 0; if (seaf_stat (buf, &st) == 0 && S_ISDIR(st.st_mode)) { continue; } else if (S_ISREG(st.st_mode)) { time_t t = time(NULL); char time_buf[64]; /* It's not a clean merge if conflict path is created. */ *clean = 0; strftime(time_buf, 64, "%Y-%m-%d-%H-%M-%S", localtime(&t)); n = snprintf (&buf[my_offset], SEAF_PATH_MAX - my_offset, " (%s)", time_buf); my_offset += n; if (seaf_stat (buf, &st) == 0 && S_ISDIR(st.st_mode)) continue; } if (seaf_util_mkdir (buf, 0777) < 0) { g_warning ("Failed to create directory %s.\n", buf); return -1; } } *new_path = g_strdup(buf); return 0; } static int make_room_for_path(struct index_state *index, const char *path, const char *real_path, char **new_path, const char *conflict_suffix, int *clean) { int status; SeafStat st; int base_len = strlen(real_path) - strlen(path); status = create_leading_directories(base_len, real_path, new_path, conflict_suffix, clean); if (status) { return -1; } if (seaf_stat (*new_path, &st) == 0 && S_ISDIR(st.st_mode)) { if (seaf_util_rmdir (*new_path) < 0) { g_warning ("failed to remove directory %s.\n", *new_path); /* Don't return error since we can handle conflict later. */ } return 0; } /* * Do not unlink a file in the work tree if we are not * tracking it. */ /* if (would_lose_untracked(index, path, *new_path)) { */ /* g_warning("refusing to lose untracked file at '%s'", path); */ /* return -1; */ /* } */ return 0; /* /\* Successful unlink is good.. *\/ */ /* if (!g_unlink(*new_path)) */ /* return 0; */ /* /\* .. and so is no existing file *\/ */ /* if (errno == ENOENT) */ /* return 0; */ /* /\* .. but not some other error (who really cares what?) *\/ */ /* return -1; */ } static int update_file_flags(struct merge_options *o, const unsigned char *sha, unsigned mode, const char *modifier, guint64 mtime, const char *path, int update_cache, int update_wd) { char *real_path; char file_id[41]; int clean = 1; int refresh = 1; if (update_wd && o->collect_blocks_only) { fill_seafile_blocks (o->repo_id, o->version, sha, o->bl); return clean; } real_path = g_build_path(PATH_SEPERATOR, o->worktree, path, NULL); if (update_wd) { char *new_path; SeafStat st; /* When creating a conflict directory, we use o->branch2 as conflict * suffix instead of the last changer name of path. * This is because there may be more than one conflicting file * under this directory, each has different changer. */ if (make_room_for_path(o->index, path, real_path, &new_path, o->branch2, &clean) < 0) { g_free (real_path); refresh = 0; goto update_cache; } g_free (real_path); real_path = new_path; /* Checkout an empty dir. */ if (S_ISDIR (mode)) { if (seaf_util_mkdir (real_path, 0777) < 0) { g_warning ("Failed to create empty dir %s in merge.\n", real_path); refresh = 0; } if (mtime != 0 && seaf_set_file_time (real_path, mtime) < 0) g_warning ("Failed to set mtime for %s.\n", real_path); goto update_cache; } /* We're checking out a clean file in recover merge. * Note that file is clean only when it's added by others. */ if (update_cache && o->recover_merge && seaf_stat(real_path, &st) == 0 && S_ISREG(st.st_mode)) { if (compare_file_content (real_path, &st, sha, o->crypt, o->version) == 0) { goto update_cache; } /* If the file was checked out and changed by user, we * don't need to check out again, since the user should * know the content of this file. */ g_free (real_path); return clean; } gboolean conflicted = FALSE; rawdata_to_hex(sha, file_id, 20); if (seaf_fs_manager_checkout_file(seaf->fs_mgr, o->repo_id, o->version, file_id, real_path, mode, mtime, o->crypt, o->remote_head, path, FALSE, &conflicted, NULL) < 0) { g_warning("Failed to checkout file %s.\n", file_id); refresh = 0; goto update_cache; } } update_cache: if (update_cache && clean) add_cacheinfo(o->index, mode, sha, modifier, path, real_path, 0, refresh, ADD_CACHE_OK_TO_ADD); g_free(real_path); return clean; } static int update_file(struct merge_options *o, int clean, const unsigned char *sha, unsigned mode, const char *modifier, guint64 mtime, const char *path) { return update_file_flags(o, sha, mode, modifier, mtime, path, clean, 1); } /* Per entry merge function */ static int process_entry(struct merge_options *o, const char *path, struct stage_data *entry) { /* printf("processing entry, clean cache: %s\n", index_only ? "yes": "no"); print_index_entry("\tpath: ", entry); */ int clean_merge = 1; unsigned o_mode = entry->stages[1].mode; unsigned a_mode = entry->stages[2].mode; unsigned b_mode = entry->stages[3].mode; unsigned char *o_sha = o_mode ? entry->stages[1].sha : NULL; unsigned char *a_sha = a_mode ? entry->stages[2].sha : NULL; unsigned char *b_sha = b_mode ? entry->stages[3].sha : NULL; guint64 current_mtime = entry->stages[2].current_mtime; guint64 a_mtime = entry->stages[2].mtime; guint64 b_mtime = entry->stages[3].mtime; char *a_modifier = entry->stages[2].modifier; char *b_modifier = entry->stages[3].modifier; /* if (entry->rename_df_conflict_info) */ /* return 1; /\* Such cases are handled elsewhere. *\/ */ entry->processed = 1; if (o_sha && (!a_sha || !b_sha)) { /* Case A: Deleted in one */ if ((!a_sha && !b_sha) || (!b_sha && memcmp(o_sha, a_sha, 20) == 0 && o_mode == a_mode) || (!a_sha && memcmp(o_sha, b_sha, 20) == 0 && o_mode == b_mode)) { /* Deleted in both or deleted in one and * unchanged in the other */ /* do not touch working file if it did not exist */ /* do not remove working file if it's changed. */ remove_file(o, 1, path, !a_sha, current_mtime); } else if (g_hash_table_lookup(o->current_directory_set, path)) { /* file -> (file, directory), the file side. */ entry->processed = 0; return 1; } else { /* Deleted in one and changed in the other */ /* or directory -> (file, directory), directory side */ /* Don't consider as unclean. */ if (!a_sha) clean_merge = update_file(o, 1, b_sha, b_mode, b_modifier, b_mtime, path); else update_file_flags (o, a_sha, a_mode, a_modifier, a_mtime, path, 1, 0); } } else if ((!o_sha && a_sha && !b_sha) || (!o_sha && !a_sha && b_sha)) { /* Case B: Added in one. */ if (g_hash_table_lookup(o->current_directory_set, path)) { /* directory -> (file, directory), file side. */ entry->processed = 0; return 1; } else { /* Added in one */ /* or file -> (file, directory), directory side */ if (b_sha) clean_merge = update_file(o, 1, b_sha, b_mode, b_modifier, b_mtime, path); else /* For my file, just set index entry to stage 0, * without updating worktree. */ update_file_flags (o, a_sha, a_mode, a_modifier, a_mtime, path, 1, 0); } } else if (a_sha && b_sha) { /* Case C: Added in both (check for same permissions) and */ /* case D: Modified in both, but differently. */ if (memcmp(a_sha, b_sha, 20) != 0 || a_mode != b_mode) { char *new_path = NULL; clean_merge = 0; if (!o->collect_blocks_only) { new_path = gen_conflict_path_wrapper (o->repo_id, o->version, o->remote_head, path, path); if (!new_path) new_path = gen_conflict_path(path, o->branch2, (gint64)time(NULL)); } /* Dont update index. */ /* Keep my version, rename other's version. */ update_file_flags(o, b_sha, b_mode, b_modifier, b_mtime, new_path, 0, 1); g_free (new_path); } else { update_file_flags (o, a_sha, a_mode, a_modifier, a_mtime, path, 1, 0); } } else if (!o_sha && !a_sha && !b_sha) { /* * this entry was deleted altogether. a_mode == 0 means * we had that path and want to actively remove it. */ remove_file(o, 1, path, !a_mode, current_mtime); } else g_error("Fatal merge failure, shouldn't happen."); return clean_merge; } static int is_garbage_empty_dir (struct index_state *index, const char *name) { int pos = index_name_pos (index, name, strlen(name)); /* * If pos >= 0, ++pos to the next entry in the index. * If pos < 0, -pos = (the position this entry *should* be) + 1. * So -pos-1 is the first entry larger than this entry. */ if (pos >= 0) pos++; else pos = -pos-1; struct cache_entry *next; int this_len = strlen (name); while (pos < index->cache_nr) { next = index->cache[pos]; /* If 'name' is the prefix of next->name but they are unequal, * it means there are entries under this empty dir. So this "emtpy dir" * is useless. */ if (strncmp (name, next->name, this_len) != 0) break; if (strcmp (name, next->name) != 0) return 1; ++pos; } return 0; } /* * per entry merge function for D/F (and/or rename) conflicts. In the * cases we can cleanly resolve D/F conflicts, process_entry() can * clean out all the files below the directory for us. All D/F * conflict cases must be handled here at the end to make sure any * directories that can be cleaned out, are. */ static int process_df_entry(struct merge_options *o, const char *path, struct stage_data *entry) { int clean_merge = 1; unsigned o_mode = entry->stages[1].mode; unsigned a_mode = entry->stages[2].mode; unsigned b_mode = entry->stages[3].mode; unsigned char *o_sha = o_mode ? entry->stages[1].sha : NULL; unsigned char *a_sha = a_mode ? entry->stages[2].sha : NULL; unsigned char *b_sha = b_mode ? entry->stages[3].sha : NULL; guint64 a_mtime = entry->stages[2].mtime; guint64 b_mtime = entry->stages[3].mtime; char *a_modifier = entry->stages[2].modifier; char *b_modifier = entry->stages[3].modifier; SeafStat st; char *real_path = g_build_path(PATH_SEPERATOR, o->worktree, path, NULL); char *new_path = NULL; entry->processed = 1; if (o_sha && (!a_sha || !b_sha)) { /* Modify/delete; deleted side may have put a directory in the way */ if (b_sha) { if (seaf_stat (real_path, &st) == 0 && S_ISDIR(st.st_mode)) { /* D/F conflict. */ clean_merge = 0; if (!o->collect_blocks_only) { new_path = gen_conflict_path_wrapper (o->repo_id, o->version, o->remote_head, path, path); if (!new_path) new_path = gen_conflict_path(path, o->branch2, (gint64)time(NULL)); } update_file(o, 0, b_sha, b_mode, b_modifier, b_mtime, new_path); g_free (new_path); } else { /* Modify/Delete conflict. Don't consider as unclean. */ clean_merge = update_file(o, 1, b_sha, b_mode, b_modifier, b_mtime, path); } } else { if (seaf_stat (real_path, &st) == 0 && S_ISDIR(st.st_mode)) { clean_merge = 0; } else { /* Clean merge. Just need to update index. */ update_file_flags (o, a_sha, a_mode, a_modifier, a_mtime, path, 1, 0); } } } else if (!o_sha && !!a_sha != !!b_sha) { unsigned char *sha = a_sha ? a_sha : b_sha; unsigned mode = a_sha ? a_mode : b_mode; char *modifier = a_sha ? a_modifier : b_modifier; guint64 mtime = a_sha ? a_mtime : b_mtime; /* directory -> (directory, empty dir) or * directory -> (empty dir, directory) */ if (S_ISDIR(mode)) { /* Merge is always clean. If the merge result is non empty dir, * remove the empty dir entry from the index. */ if (is_garbage_empty_dir (o->index, path)) remove_file_from_index (o->index, path); else if (a_sha) update_file_flags (o, sha, mode, modifier, mtime, path, 1, 0); else update_file_flags (o, sha, mode, modifier, mtime, path, 1, 1); goto out; } /* directory -> (directory, file) */ if (b_sha) { if (seaf_stat (real_path, &st) == 0 && S_ISDIR(st.st_mode)) { /* D/F conflict. */ clean_merge = 0; if (!o->collect_blocks_only) { new_path = gen_conflict_path_wrapper (o->repo_id, o->version, o->remote_head, path, path); if (!new_path) new_path = gen_conflict_path(path, o->branch2, (gint64)time(NULL)); } update_file(o, 0, b_sha, b_mode, b_modifier, b_mtime, new_path); g_free (new_path); } else { /* Clean merge. */ clean_merge = update_file(o, 1, b_sha, b_mode, b_modifier, b_mtime, path); } } else { if (seaf_stat (real_path, &st) == 0 && S_ISDIR(st.st_mode)) { clean_merge = 0; } else { /* Clean merge. Just need to update index. */ update_file_flags (o, a_sha, a_mode, a_modifier, a_mtime, path, 1, 0); } } } else { entry->processed = 0; g_free(real_path); return 1; /* not handled; assume clean until processed */ } out: g_free(real_path); return clean_merge; } #if 0 static void print_index (struct index_state *istate) { g_message ("Totally %u entries in index.\n", istate->cache_nr); int i; char id[41]; for (i = 0; i < istate->cache_nr; ++i) { struct cache_entry *ce = istate->cache[i]; rawdata_to_hex (ce->sha1, id, 20); g_message ("%s\t%s\t%o\t%d\t%d\t%d\n", ce->name, id, ce->ce_mode, ce_stage(ce), ce->ce_ctime.sec, ce->ce_mtime.sec); } } #endif static int process_unmerged_entries (struct merge_options *o, SeafDir *head, SeafDir *merge) { int clean = 1; if (unmerged_index(o->index)) { GList *entries, *p; g_hash_table_remove_all(o->current_file_set); g_hash_table_remove_all(o->current_directory_set); get_files_dirs(o, head); get_files_dirs(o, merge); entries = get_unmerged(o->index); /* We don't want to remove any existing file. */ /* make_room_for_directories_of_df_conflicts(o, entries); */ for (p = entries; p != NULL; p = p->next) { struct stage_data *e = p->data; if (!e->processed && !process_entry(o, e->path, e)) clean = 0; } for (p = entries; p != NULL; p = p->next) { struct stage_data *e = p->data; if (!e->processed && !process_df_entry(o, e->path, e)) clean = 0; } for (p = entries; p != NULL; p = p->next) { struct stage_data *e = p->data; if (!e->processed) { g_warning("Unprocessed path??? %s", e->path); return 0; } g_free(e->path); int i; for (i = 0; i < 4; ++i) g_free (e->stages[i].modifier); free(e); } g_list_free(entries); } return clean; } /* * Merge the commits h1 and h2, return merged tree root id * and a flag indicating the cleanness of the merge. * Return 0 if merge is done (no matter clean or not); -1 otherwise. */ int merge_recursive(struct merge_options *o, const char *h1_root, const char *h2_root, const char *ca_root, int *clean, char **root_id) { SeafDir *head, *remote, *common; int code, ret = 0; struct unpack_trees_options opts; char *error = NULL; *clean = 1; head = seaf_fs_manager_get_seafdir (seaf->fs_mgr, o->repo_id, o->version, h1_root); remote = seaf_fs_manager_get_seafdir (seaf->fs_mgr, o->repo_id, o->version, h2_root); common = seaf_fs_manager_get_seafdir (seaf->fs_mgr, o->repo_id, o->version, ca_root); if (!head || !remote || !common) { g_warning ("Invalid commits!\n"); return -1; } /* Get merged index. */ code = seafile_merge_trees(o, &opts, common, head, remote, &error); if (code != 0) { ret = -1; goto out; } /* If only collect blocks, return success. */ if (o->collect_blocks_only) { process_unmerged_entries (o, head, remote); goto out; } /* Update worktree. */ /* On windows, we have to Check if any files need to be updated * are locked by other program (e.g. Office). If no file is locked, * update worktree; otherwise just quit. * * Note that if we're recovering merge on startup, we need to update * worktree no matter files are locked or not, since we cannot retry * this operation. This will produce more confusing results, but * it doesn't hurt data integrity. */ #ifdef WIN32 if (o->recover_merge || o->force_merge || !files_locked_on_windows (o->index, o->worktree)) { update_worktree (&opts, o->recover_merge, o->remote_head, o->branch2, NULL); *clean = process_unmerged_entries (o, head, remote); } else { /* Don't update anything. */ g_debug ("[merge] files are locked, quit merge now.\n"); ret = -1; goto out; } #else update_worktree (&opts, o->recover_merge, o->remote_head, o->branch2, NULL); *clean = process_unmerged_entries (o, head, remote); #endif if (*clean) { *root_id = write_tree_from_memory(o); if (*root_id == NULL) ret = -1; } out: seaf_dir_free (head); seaf_dir_free (remote); seaf_dir_free (common); return ret; } void init_merge_options(struct merge_options *o) { memset(o, 0, sizeof(struct merge_options)); o->obuf = g_string_new(""); o->current_file_set = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); o->current_directory_set = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); } void clear_merge_options(struct merge_options *o) { g_string_free (o->obuf, TRUE); g_hash_table_destroy (o->current_file_set); g_hash_table_destroy (o->current_directory_set); } seafile-6.1.5/daemon/merge-recursive.h000066400000000000000000000023341323477647300176750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef MERGE_RECURSIVE_H #define MERGE_RECURSIVE_H #include #include "commit-mgr.h" #include "fs-mgr.h" #include "seafile-crypt.h" struct merge_options { char repo_id[37]; int version; const char *ancestor; const char *branch1; const char *branch2; const char *remote_head; int call_depth; char *worktree; struct index_state *index; GString *obuf; GHashTable *current_file_set; GHashTable *current_directory_set; gboolean recover_merge; gboolean force_merge; SeafileCrypt *crypt; /* True if we only want to know the files that would be * updated in this merge, but don't want to update them in the * worktree. */ gboolean collect_blocks_only; BlockList *bl; }; int merge_recursive(struct merge_options *o, const char *h1_root, const char *h2_root, const char *ca_root, int *clean, char **root_id); void init_merge_options(struct merge_options *o); void clear_merge_options(struct merge_options *o); char *write_tree_from_memory(struct merge_options *o); #endif seafile-6.1.5/daemon/merge.c000066400000000000000000000321231323477647300156620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include "index/index.h" #include "unpack-trees.h" #include "merge-recursive.h" #include "merge.h" #include "seafile-session.h" #include "vc-utils.h" #include "vc-common.h" #if 0 static int print_index (struct index_state *istate) { int i; struct cache_entry *ce; char id[41]; g_message ("Totally %u entries in index, version %u.\n", istate->cache_nr, istate->version); for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; rawdata_to_hex (ce->sha1, id, 20); g_message ("%s, %s, %o, %"G_GUINT64_FORMAT", %s, %d\n", ce->name, id, ce->ce_mode, ce->ce_mtime.sec, ce->modifier, ce_stage(ce)); } return 0; } #endif static int do_real_merge (SeafRepo *repo, SeafBranch *head_branch, SeafCommit *head, SeafBranch *remote_branch, SeafCommit *remote, SeafCommit *common, gboolean recover_merge, char **error) { struct merge_options opts; char index_path[SEAF_PATH_MAX]; struct index_state istate; char *root_id = NULL; SeafCommit *merged; int ret = 0, clean; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", repo->manager->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { g_warning ("Failed to load index.\n"); *error = g_strdup ("Internal error.\n"); return -1; } init_merge_options (&opts); memcpy (opts.repo_id, repo->id, 36); opts.version = repo->version; opts.index = &istate; opts.worktree = repo->worktree; opts.ancestor = "common ancestor"; opts.branch1 = seaf->session->base.user_name; opts.branch2 = remote->creator_name; opts.remote_head = remote->commit_id; opts.recover_merge = recover_merge; if (repo->encrypted) { opts.crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } ret = merge_recursive (&opts, head->root_id, remote->root_id, common->root_id, &clean, &root_id); if (ret < 0) goto out; if (update_index (&istate, index_path) < 0) { *error = g_strdup ("Internal error.\n"); ret = -1; goto out; } if (clean) { merged = seaf_commit_new (NULL, repo->id, root_id, repo->email ? repo->email : seaf->session->base.user_name, seaf->session->base.id, "Auto merge by system", 0); merged->parent_id = g_strdup(head->commit_id); merged->second_parent_id = g_strdup(remote->commit_id); merged->new_merge = TRUE; seaf_repo_to_commit (repo, merged); if (seaf_commit_manager_add_commit (seaf->commit_mgr, merged) < 0) { seaf_commit_unref (merged); *error = g_strdup ("Internal error.\n"); ret = -1; goto out; } seaf_branch_set_commit (head_branch, merged->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, head_branch); g_debug ("Auto merged.\n"); seaf_commit_unref (merged); } else { ret = -1; g_debug ("Auto merge failed.\n"); } out: if (root_id) g_free (root_id); g_free (opts.crypt); clear_merge_options (&opts); discard_index (&istate); return ret; } static SeafCommit * get_common_ancestor_commit (const char *repo_id, int version) { char ca_id[41], head_id[41]; SeafCommit *commit; if (seaf_repo_manager_get_common_ancestor (seaf->repo_mgr, repo_id, ca_id, head_id) < 0) { g_warning ("Common ancestor commit id is not found in db.\n"); return NULL; } commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, version, ca_id); return commit; } int merge_branches (SeafRepo *repo, SeafBranch *remote_branch, char **error, int *merge_status) { SeafCommit *common = NULL; SeafCommit *head = NULL, *remote = NULL; int ret = 0; #if 0 SeafRepoMergeInfo minfo; #endif g_return_val_if_fail (repo && remote_branch && error, -1); *merge_status = MERGE_STATUS_UNKNOWN; #if 0 memset (&minfo, 0, sizeof(minfo)); if (seaf_repo_manager_get_merge_info (repo->manager, repo->id, &minfo) < 0) { g_warning ("Failed to get merge status of repo %s.\n", repo->id); return -1; } #endif head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { *error = g_strdup("Internal error: current branch corrupted.\n"); return -1; } remote = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, remote_branch->commit_id); if (!remote) { *error = g_strdup("Invalid remote branch.\n"); ret = -1; goto free_commits; } #if 0 /* Are we going to recover from the last interrupted merge? */ if (minfo.in_merge) { /* We don't need to recover 2 cases, since the last merge was actually finished. * - "master" and "local" are the same; * - index is unmerged. * * The first case is a clean merge; the second case is unclean merge. */ if (strcmp (head->commit_id, remote->commit_id) == 0 || seaf_repo_is_index_unmerged (repo)) { seaf_repo_manager_clear_merge (repo->manager, repo->id); goto free_commits; } } #endif /* If not all commits are downloaded, find common ancestor from db; * otherwise we'll use the old method to calculate * common ancestor from local history. */ if (repo->version > 0) common = get_common_ancestor_commit (repo->id, repo->version); else common = get_merge_base (head, remote); if (!common) { g_warning ("Cannot find common ancestor\n"); *error = g_strdup ("Cannot find common ancestor\n"); ret = -1; goto free_commits; } /* We use the same logic for normal merge and recover. */ /* Set in_merge state. */ seaf_repo_manager_set_merge (repo->manager, repo->id, remote_branch->commit_id); /* printf ("common commit id is %s.\n", common->commit_id); */ if (strcmp(common->commit_id, remote->commit_id) == 0) { /* We are already up to date. */ g_debug ("Already up to date.\n"); *merge_status = MERGE_STATUS_UPTODATE; } else if (strcmp(common->commit_id, head->commit_id) == 0) { *merge_status = MERGE_STATUS_FAST_FORWARD; /* Fast forward. */ if (seaf_repo_checkout_commit (repo, remote, FALSE, error) < 0) { ret = -1; goto out; } seaf_branch_set_commit (repo->head, remote->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, repo->head); /* Repo info on the client is in memory. */ g_free (repo->name); repo->name = g_strdup(remote->repo_name); g_free (repo->desc); repo->desc = g_strdup(remote->repo_desc); g_debug ("Fast forward.\n"); } else { /* Not up-to-date and ff, we need a real merge. */ *merge_status = MERGE_STATUS_REAL_MERGE; ret = do_real_merge (repo, repo->head, head, remote_branch, remote, common, FALSE, error); } out: /* Clear in_merge state, no matter clean or not. */ seaf_repo_manager_clear_merge (repo->manager, repo->id); free_commits: seaf_commit_unref (common); seaf_commit_unref (remote); seaf_commit_unref (head); return ret; } /* * Get the new blocks that need to be checked out if we ff to @remote. */ static int get_new_blocks_ff (SeafRepo *repo, SeafCommit *head, SeafCommit *remote, BlockList **bl) { SeafRepoManager *mgr = repo->manager; char index_path[SEAF_PATH_MAX]; struct tree_desc trees[2]; struct unpack_trees_options topts; struct index_state istate; int ret = 0; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { g_warning ("Failed to load index.\n"); return -1; } fill_tree_descriptor (repo->id, repo->version, &trees[0], head->root_id); fill_tree_descriptor (repo->id, repo->version, &trees[1], remote->root_id); memset(&topts, 0, sizeof(topts)); memcpy (topts.repo_id, repo->id, 36); topts.version = repo->version; topts.base = repo->worktree; topts.head_idx = -1; topts.src_index = &istate; topts.update = 1; topts.merge = 1; topts.fn = twoway_merge; /* unpack_trees() doesn't update index or worktree. */ if (unpack_trees (2, trees, &topts) < 0) { g_warning ("Failed to ff to commit %s.\n", remote->commit_id); ret = -1; goto out; } *bl = block_list_new (); collect_new_blocks_from_index (repo->id, repo->version, &topts.result, *bl); out: tree_desc_free (&trees[0]); tree_desc_free (&trees[1]); discard_index (&istate); discard_index (&topts.result); return ret; } /* * Get the new blocks that need to be checked out if we do a real merge. */ static int get_new_blocks_merge (SeafRepo *repo, SeafCommit *head, SeafCommit *remote, SeafCommit *common, BlockList **bl) { struct merge_options opts; char index_path[SEAF_PATH_MAX]; struct index_state istate; int ret, clean; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", repo->manager->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { g_warning ("Failed to load index.\n"); return -1; } init_merge_options (&opts); memcpy (opts.repo_id, repo->id, 36); opts.version = repo->version; opts.index = &istate; opts.worktree = repo->worktree; opts.ancestor = "common ancestor"; opts.branch1 = seaf->session->base.user_name; opts.branch2 = remote->creator_name; opts.collect_blocks_only = TRUE; *bl = block_list_new(); opts.bl = *bl; ret = merge_recursive (&opts, head->root_id, remote->root_id, common->root_id, &clean, NULL); clear_merge_options (&opts); discard_index (&istate); return ret; } /* * Get the list of new blocks that would be checked out after * we merge with a branch headed by @remote. * * This function should be called before downloading any block * if the repo is set to not preserving history. In this case, * we don't want to download any block that will not be checked * out to the worktree (i.e. data from any historical commits). * * Return 0 if successfully calculate the block list, -1 otherwise. * If there is no new block to download, *@bl will be set to NULL; * otherwise it's set to the block list. */ int merge_get_new_block_list (SeafRepo *repo, SeafCommit *remote, BlockList **bl) { SeafCommit *common = NULL; SeafCommit *head = NULL; int ret = 0; head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { g_warning ("current branch corrupted.\n"); return -1; } /* If not all commits are downloaded, get common ancestor from db; * otherwise we'll use the old method to calculate * common ancestor from local history. */ if (repo->version > 0) common = get_common_ancestor_commit (repo->id, repo->version); else common = get_merge_base (head, remote); if (!common) { g_warning ("Cannot find common ancestor\n"); ret = -1; goto out; } if (strcmp(common->commit_id, remote->commit_id) == 0) { /* We are already up to date. No new block. */ *bl = NULL; } else if (strcmp(common->commit_id, head->commit_id) == 0) { /* Fast forward. */ ret = get_new_blocks_ff (repo, head, remote, bl); } else { /* Not up-to-date and ff, we need a real merge. */ ret = get_new_blocks_merge (repo, head, remote, common, bl); } out: seaf_commit_unref (common); seaf_commit_unref (head); return ret; } seafile-6.1.5/daemon/merge.h000066400000000000000000000006331323477647300156700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef MERGE_H #define MERGE_H #include "repo-mgr.h" #include "commit-mgr.h" #include "branch-mgr.h" #include "fs-mgr.h" int merge_branches (SeafRepo *repo, SeafBranch *remote_branch, char **error, gboolean *real_merge); int merge_get_new_block_list (SeafRepo *repo, SeafCommit *remote, BlockList **bl); #endif seafile-6.1.5/daemon/processors/000077500000000000000000000000001323477647300166205ustar00rootroot00000000000000seafile-6.1.5/daemon/processors/check-protocol-proc.c000066400000000000000000000037041323477647300226450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "check-protocol-proc.h" #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" G_DEFINE_TYPE (SeafileCheckProtocolProc, seafile_check_protocol_proc, CCNET_TYPE_PROCESSOR) static int check_protocol_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void seafile_check_protocol_proc_class_init (SeafileCheckProtocolProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "seafile-check-protocol"; proc_class->start = check_protocol_start; proc_class->handle_response = handle_response; } static void seafile_check_protocol_proc_init (SeafileCheckProtocolProc *processor) { } static int check_protocol_start (CcnetProcessor *processor, int argc, char **argv) { if (argc != 0) { seaf_warning ("[sync-repo] argc should be 0.\n"); ccnet_processor_done (processor, FALSE); return 0; } char buf[256]; snprintf (buf, 256, "remote %s seafile-check-protocol-slave", processor->peer_id); ccnet_processor_send_request (processor, buf); return 0; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileCheckProtocolProc *proc = (SeafileCheckProtocolProc *)processor; if (memcmp (code, SC_OK, 3) == 0) { if (content[clen-1] != '\0') { seaf_warning ("[check-protocol] Response not end with NULL\n"); ccnet_processor_done (processor, FALSE); return; } proc->protocol_version = atoi(content); ccnet_processor_done (processor, TRUE); } else ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/check-protocol-proc.h000066400000000000000000000026101323477647300226450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_CHECK_PROTOCOL_PROC_H #define SEAFILE_CHECK_PROTOCOL_PROC_H #include #include #define SEAFILE_TYPE_CHECK_PROTOCOL_PROC (seafile_check_protocol_proc_get_type ()) #define SEAFILE_CHECK_PROTOCOL_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_PROC, SeafileCheckProtocolProc)) #define SEAFILE_IS_CHECK_PROTOCOL_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_PROC)) #define SEAFILE_CHECK_PROTOCOL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_PROTOCOL_PROC, SeafileCheckProtocolProcClass)) #define IS_SEAFILE_CHECK_PROTOCOL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_PROTOCOL_PROC)) #define SEAFILE_CHECK_PROTOCOL_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_PROTOCOL_PROC, SeafileCheckProtocolProcClass)) typedef struct _SeafileCheckProtocolProc SeafileCheckProtocolProc; typedef struct _SeafileCheckProtocolProcClass SeafileCheckProtocolProcClass; struct _SeafileCheckProtocolProc { CcnetProcessor parent_instance; int protocol_version; }; struct _SeafileCheckProtocolProcClass { CcnetProcessorClass parent_class; }; GType seafile_check_protocol_proc_get_type (); #endif seafile-6.1.5/daemon/processors/check-tx-v3-proc.c000066400000000000000000000263161323477647300217710ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #ifndef USE_GPL_CRYPTO #include #include #include #include #include "seafile-session.h" #include "vc-common.h" #include "seafile-crypt.h" #include "log.h" #include "utils.h" #include "check-tx-v3-proc.h" #define SC_GET_TOKEN "301" #define SS_GET_TOKEN "Get token" #define SC_PUT_TOKEN "302" #define SS_PUT_TOKEN "Put token" #define SC_GET_VERSION "303" #define SS_GET_VERSION "Get version" #define SC_VERSION "304" #define SS_VERSION "Version" #define SC_ACCESS_DENIED "401" #define SS_ACCESS_DENIED "Access denied" #define SC_PROTOCOL_MISMATCH "405" #define SS_PROTOCOL_MISMATCH "Protocol version mismatch" /* Only for upload */ #define SC_QUOTA_ERROR "402" #define SS_QUOTA_ERROR "Failed to get quota" #define SC_QUOTA_FULL "403" #define SS_QUOTA_FULL "storage for the repo's owner is full" /* Only for download */ #define SC_BAD_REPO "406" #define SS_BAD_REPO "Repo doesn't exist" enum { CHECK_TX_TYPE_UPLOAD, CHECK_TX_TYPE_DOWNLOAD, }; G_DEFINE_TYPE (SeafileCheckTxV3Proc, seafile_check_tx_v3_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { CCNET_PROCESSOR_CLASS (seafile_check_tx_v3_proc_parent_class)->release_resource (processor); } static void seafile_check_tx_v3_proc_class_init (SeafileCheckTxV3ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "check-tx-proc-v3"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; } static void seafile_check_tx_v3_proc_init (SeafileCheckTxV3Proc *processor) { } /* token -> AES encrypt with session key -> rawdata_to_hex -> output */ static char * encrypt_token (CcnetProcessor *processor, const char *token) { CcnetPeer *peer = NULL; char *enc_out = NULL; SeafileCrypt *crypt = NULL; unsigned char key[16], iv[16]; int len; char *output = NULL; if (!token) goto out; peer = ccnet_get_peer(seaf->ccnetrpc_client, processor->peer_id); if (!peer || !peer->session_key) { seaf_warning ("[check tx v3] peer or peer session key not exist\n"); goto out; } EVP_BytesToKey (EVP_aes_128_cbc(), /* cipher mode */ EVP_sha1(), /* message digest */ NULL, /* slat */ (unsigned char*)peer->session_key, strlen(peer->session_key), 1, /* iteration times */ key, /* the derived key */ iv); /* IV, initial vector */ crypt = seafile_crypt_new (1, key, iv); /* encrypt the token with session key, including the trailing null byte */ if (seafile_encrypt (&enc_out, &len, token, strlen(token) + 1, crypt) < 0) { seaf_warning ("[check tx v3] failed to encrypt token\n"); goto out; } output = g_malloc (len * 2 + 1); rawdata_to_hex ((unsigned char *)enc_out, output, len); output[len * 2] = '\0'; out: g_free (crypt); g_free (enc_out); if (peer) g_object_unref(peer); return output; } static int start (CcnetProcessor *processor, int argc, char **argv) { SeafileCheckTxV3Proc *proc = (SeafileCheckTxV3Proc *)processor; TransferTask *task = proc->task; char *type, *enc_token; GString *buf; if (argc != 1) { transition_state_to_error (task, TASK_ERR_CHECK_UPLOAD_START); ccnet_processor_done (processor, FALSE); return -1; } type = argv[0]; if (strcmp (type, "upload") == 0) proc->type = CHECK_TX_TYPE_UPLOAD; else proc->type = CHECK_TX_TYPE_DOWNLOAD; enc_token = encrypt_token (processor, task->token); if (!enc_token) { transition_state_to_error (task, TASK_ERR_CHECK_UPLOAD_START); ccnet_processor_done (processor, FALSE); return -1; } buf = g_string_new(NULL); g_string_append_printf (buf, "remote %s seafile-check-tx-slave-v3 %s %d %s %s %s", processor->peer_id, type, CURRENT_PROTO_VERSION, task->repo_id, task->to_branch, enc_token); ccnet_processor_send_request (processor, buf->str); g_free (enc_token); g_string_free (buf, TRUE); return 0; } static void handle_upload_ok (CcnetProcessor *processor, TransferTask *task, char *content, int clen) { if (clen == 0) { ccnet_processor_send_update (processor, SC_GET_TOKEN, SS_GET_TOKEN, NULL, 0); return; } if (clen != 41 || content[clen-1] != '\0') { seaf_warning ("Bad response content.\n"); transfer_task_set_error (task, TASK_ERR_UNKNOWN); ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return; } /* Ignore the returned remote head id, just use the head of master branch. * For protocol version >= 6, the complete hitstory is not downloaded, so * there is no way to check fast forward on the client. For protocol version * < 6, the server will check fast forward anyway. */ SeafBranch *master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Cannot find branch master for repo %s.\n", task->repo_id); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } memcpy (task->remote_head, master->commit_id, 40); seaf_branch_unref (master); ccnet_processor_send_update (processor, SC_GET_TOKEN, SS_GET_TOKEN, NULL, 0); } static void handle_download_ok (CcnetProcessor *processor, TransferTask *task, char *content, int clen) { if (clen != 41 || content[clen-1] != '\0') { seaf_warning ("Bad response content.\n"); transfer_task_set_error (task, TASK_ERR_UNKNOWN); ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return; } memcpy (task->head, content, 41); ccnet_processor_send_update (processor, SC_GET_TOKEN, SS_GET_TOKEN, NULL, 0); } static void set_download_head_info (TransferTask *task) { /* If the last download was interrupted in the fetch and checkout stage, * resume last download. */ char *last_head = seaf_repo_manager_get_repo_property (seaf->repo_mgr, task->repo_id, REPO_PROP_DOWNLOAD_HEAD); if (last_head && strcmp (last_head, EMPTY_SHA1) != 0) memcpy (task->head, last_head, 41); g_free (last_head); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileCheckTxV3Proc *proc = (SeafileCheckTxV3Proc *)processor; TransferTask *task = proc->task; if (strncmp(code, SC_OK, 3) == 0) { if (proc->type == CHECK_TX_TYPE_UPLOAD) handle_upload_ok (processor, task, content, clen); else handle_download_ok (processor, task, content, clen); } else if (strncmp (code, SC_PUT_TOKEN, 3) == 0) { /* In LAN sync, we don't use session token. */ if (clen == 0) { ccnet_processor_done (processor, TRUE); return; } if (content[clen-1] != '\0') { seaf_warning ("Bad response content.\n"); transfer_task_set_error (task, TASK_ERR_UNKNOWN); ccnet_processor_send_update (processor, SC_BAD_ARGS, SS_BAD_ARGS, NULL, 0); ccnet_processor_done (processor, FALSE); return; } task->session_token = g_strdup (content); ccnet_processor_send_update (processor, SC_GET_VERSION, SS_GET_VERSION, NULL, 0); } else if (strncmp (code, SC_VERSION, 3) == 0) { int server_version = atoi(content); /* There is a bug in block transfer in version 4, so it's not supported. */ if (server_version == 4) server_version = 3; task->protocol_version = MIN (server_version, CURRENT_PROTO_VERSION); if (task->protocol_version < 5) { seaf_warning ("Deprecated server protocol version %d.\n", task->protocol_version); transfer_task_set_error (task, TASK_ERR_DEPRECATED_SERVER); ccnet_processor_done (processor, FALSE); return; } if (task->repo_version == 0) task->protocol_version = 5; else if (task->protocol_version == 5) { /* Syncing version 1 reop with 2.x server is not supported. * Actually version 1 repo can only be created by 3.x servers. * If version 1 repos exist on 2.x server, it means a down-grade * operation has been performed, which is not supported. */ seaf_warning ("Syncing version %d repo with protocol version %d " "is not supported.\n", task->repo_version, task->protocol_version); transfer_task_set_error (task, TASK_ERR_DEPRECATED_SERVER); ccnet_processor_done (processor, FALSE); return; } if (task->protocol_version >= 7 && !task->server_side_merge) task->protocol_version = 6; if (task->protocol_version >= 7 && task->type == TASK_TYPE_DOWNLOAD) set_download_head_info (task); seaf_message ("repo version is %d, protocol version is %d.\n", task->repo_version, task->protocol_version); ccnet_processor_done (processor, TRUE); } else { seaf_warning ("[check tx v3] Bad response: %s %s", code, code_msg); if (strncmp(code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); else if (strncmp(code, SC_QUOTA_ERROR, 3) == 0) transfer_task_set_error (task, TASK_ERR_CHECK_QUOTA); else if (strncmp(code, SC_QUOTA_FULL, 3) == 0) transfer_task_set_error (task, TASK_ERR_QUOTA_FULL); else if (strncmp(code, SC_PROTOCOL_MISMATCH, 3) == 0) transfer_task_set_error (task, TASK_ERR_PROTOCOL_VERSION); else if (strncmp(code, SC_BAD_REPO, 3) == 0) transfer_task_set_error (task, TASK_ERR_BAD_REPO_ID); else transfer_task_set_error (task, TASK_ERR_UNKNOWN); ccnet_processor_done (processor, FALSE); } } #endif seafile-6.1.5/daemon/processors/check-tx-v3-proc.h000066400000000000000000000025351323477647300217730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_CHECK_TX_V3_PROC_H #define SEAFILE_CHECK_TX_V3_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_CHECK_TX_V3_PROC (seafile_check_tx_v3_proc_get_type ()) #define SEAFILE_CHECK_TX_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECK_TX_V3_PROC, SeafileCheckTxV3Proc)) #define SEAFILE_IS_CHECK_TX_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECK_TX_PROC)) #define SEAFILE_CHECK_TX_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECK_TX_V3_PROC, SeafileCheckTxV3ProcClass)) #define IS_SEAFILE_CHECK_TX_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECK_TX_V3_PROC)) #define SEAFILE_CHECK_TX_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECK_TX_V3_PROC, SeafileCheckTxV3ProcClass)) typedef struct _SeafileCheckTxV3Proc SeafileCheckTxV3Proc; typedef struct _SeafileCheckTxV3ProcClass SeafileCheckTxV3ProcClass; struct _SeafileCheckTxV3Proc { CcnetProcessor parent_instance; int type; TransferTask *task; }; struct _SeafileCheckTxV3ProcClass { CcnetProcessorClass parent_class; }; GType seafile_check_tx_v3_proc_get_type (); #endif seafile-6.1.5/daemon/processors/checkbl-proc.c000066400000000000000000000116051323477647300213230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * checkbl-proc start * ---------------------------> * * OK * <-------------------------- * * Block list segment 1 * --------------------------> * * Non-exist block list * <------------------------- * * Block list segment 2 * --------------------------> * * Non-exist block list * <------------------------- * * Block list end * -------------------------> * */ #define SC_BLOCK_LIST "301" #define SS_BLOCK_LIST "Block list" #define SC_NEED_BLOCKS "302" #define SS_NEED_BLOCKS "Needed blocks" #define SC_BLOCK_LIST_END "303" #define SS_BLOCK_LIST_END "Block list end" #include "checkbl-proc.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" typedef struct { int offset; } SeafileCheckblProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcPriv)) #define USE_PRIV \ SeafileCheckblProcPriv *priv = GET_PRIV(processor); G_DEFINE_TYPE (SeafileCheckblProc, seafile_checkbl_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { /* FILL IT */ CCNET_PROCESSOR_CLASS (seafile_checkbl_proc_parent_class)->release_resource (processor); } static void seafile_checkbl_proc_class_init (SeafileCheckblProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof (SeafileCheckblProcPriv)); } static void seafile_checkbl_proc_init (SeafileCheckblProc *processor) { } static int start (CcnetProcessor *processor, int argc, char **argv) { SeafileCheckblProc *proc = (SeafileCheckblProc *)processor; TransferTask *task = proc->task; GString *buf = g_string_new (""); if (!proc->send_session_token) g_string_printf (buf, "remote %s seafile-checkbl", processor->peer_id); else g_string_printf (buf, "remote %s seafile-checkbl %s", processor->peer_id, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } #define BLOCK_LIST_SEGMENT_N_BLOCKS 120 #define BLOCK_LIST_SEGMENT_LEN 40 * 120 static void send_block_list_segment (CcnetProcessor *processor, BlockList *block_list) { USE_PRIV; int len, limit; char buf[BLOCK_LIST_SEGMENT_LEN]; char *ptr; if (priv->offset == block_list->n_blocks) { ccnet_processor_send_update (processor, SC_BLOCK_LIST_END, SS_BLOCK_LIST_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } len = MIN (block_list->n_blocks - priv->offset, BLOCK_LIST_SEGMENT_N_BLOCKS); limit = priv->offset + len; for (ptr = buf; priv->offset < limit; ++(priv->offset)) { char *block_id = g_ptr_array_index (block_list->block_ids, priv->offset); memcpy (ptr, block_id, 40); ptr += 40; } seaf_debug ("Send %d block ids in block list segment.\n", len); ccnet_processor_send_update (processor, SC_BLOCK_LIST, SS_BLOCK_LIST, buf, len * 40); } static void process_needed_blocks (CcnetProcessor *processor, TransferTask *task, char *content, int clen) { if (clen == 0) { seaf_debug ("No block is needed on the server.\n"); return; } if (clen % 40 != 0) { seaf_warning ("Bad block list length %d.\n", clen); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } seaf_debug ("%d blocks are needed by the server.\n", clen/40); int offset = 0; while (offset < clen) { char *block_id = g_new (char, 41); memcpy (block_id, &content[offset], 40); block_id[40] = 0; offset += 40; g_queue_push_tail (task->block_ids, block_id); } } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileCheckblProc *proc = (SeafileCheckblProc *)processor; TransferTask *task = proc->task; if (memcmp (code, SC_OK, 3) == 0) { send_block_list_segment (processor, task->block_list); } else if (memcmp (code, SC_NEED_BLOCKS, 3) == 0) { process_needed_blocks (processor, task, content, clen); send_block_list_segment (processor, task->block_list); } else { seaf_warning ("Bad response: %s %s.\n", code, code_msg); ccnet_processor_done (processor, FALSE); } } seafile-6.1.5/daemon/processors/checkbl-proc.h000066400000000000000000000024561323477647300213340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_CHECKBL_PROC_H #define SEAFILE_CHECKBL_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_CHECKBL_PROC (seafile_checkbl_proc_get_type ()) #define SEAFILE_CHECKBL_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProc)) #define SEAFILE_IS_CHECKBL_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECKBL_PROC)) #define SEAFILE_CHECKBL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcClass)) #define IS_SEAFILE_CHECKBL_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECKBL_PROC)) #define SEAFILE_CHECKBL_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECKBL_PROC, SeafileCheckblProcClass)) typedef struct _SeafileCheckblProc SeafileCheckblProc; typedef struct _SeafileCheckblProcClass SeafileCheckblProcClass; struct _SeafileCheckblProc { CcnetProcessor parent_instance; TransferTask *task; gboolean send_session_token; }; struct _SeafileCheckblProcClass { CcnetProcessorClass parent_class; }; GType seafile_checkbl_proc_get_type (); #endif seafile-6.1.5/daemon/processors/checkff-proc.c000066400000000000000000000034361323477647300213240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "checkff-proc.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" G_DEFINE_TYPE (SeafileCheckffProc, seafile_checkff_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { /* FILL IT */ CCNET_PROCESSOR_CLASS (seafile_checkff_proc_parent_class)->release_resource (processor); } static void seafile_checkff_proc_class_init (SeafileCheckffProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; } static void seafile_checkff_proc_init (SeafileCheckffProc *processor) { } static int start (CcnetProcessor *processor, int argc, char **argv) { char buf[256]; snprintf (buf, sizeof(buf), "remote %s seafile-checkff %s %s", processor->peer_id, argv[0], argv[1]); ccnet_processor_send_request (processor, buf); return 0; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileCheckffProc *proc = (SeafileCheckffProc *)processor; if (memcmp (code, SC_OK, 3) == 0) { proc->is_fast_forward = (atoi (content) != 0); ccnet_processor_done (processor, TRUE); } else { seaf_warning ("Bad response: %s %s.\n", code, code_msg); ccnet_processor_done (processor, FALSE); } } seafile-6.1.5/daemon/processors/checkff-proc.h000066400000000000000000000023701323477647300213250ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_CHECKFF_PROC_H #define SEAFILE_CHECKFF_PROC_H #include #include #define SEAFILE_TYPE_CHECKFF_PROC (seafile_checkff_proc_get_type ()) #define SEAFILE_CHECKFF_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProc)) #define SEAFILE_IS_CHECKFF_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_CHECKFF_PROC)) #define SEAFILE_CHECKFF_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProcClass)) #define IS_SEAFILE_CHECKFF_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_CHECKFF_PROC)) #define SEAFILE_CHECKFF_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_CHECKFF_PROC, SeafileCheckffProcClass)) typedef struct _SeafileCheckffProc SeafileCheckffProc; typedef struct _SeafileCheckffProcClass SeafileCheckffProcClass; struct _SeafileCheckffProc { CcnetProcessor parent_instance; gboolean is_fast_forward; }; struct _SeafileCheckffProcClass { CcnetProcessorClass parent_class; }; GType seafile_checkff_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getca-proc.c000066400000000000000000000205331323477647300210130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include "utils.h" #include "seaf-utils.h" #include "seafile-session.h" #include "getca-proc.h" /* seafile-putca INIT --------------------------> OK <------------------------- REQUEST_SENT commit id list --------------------------> common ancestor id <-------------------------- */ #define SC_ID_LIST "301" #define SS_ID_LIST "Commit id list" #define SC_ID_LIST_END "302" #define SS_ID_LIST_END "Commit id list end" #define SC_CA "303" #define SS_CA "Common ancestor" #define SC_ACCESS_DENIED "401" #define SS_ACCESS_DENIED "Access denied" #define SC_NO_CA "404" #define SS_NO_CA "No common ancestor found" enum { INIT, REQUEST_SENT, }; typedef struct { char repo_id[41]; char last_uploaded[41]; char last_checkout[41]; GList *commits; gboolean success; } SeafileGetcaProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_GETCA_PROC, SeafileGetcaProcPriv)) #define USE_PRIV \ SeafileGetcaProcPriv *priv = GET_PRIV(processor); static int get_ca_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileGetcaProc, seafile_getca_proc, CCNET_TYPE_PROCESSOR) static void release_resource (CcnetProcessor *processor) { USE_PRIV; if (priv->commits) string_list_free (priv->commits); CCNET_PROCESSOR_CLASS (seafile_getca_proc_parent_class)->release_resource (processor); } static void seafile_getca_proc_class_init (SeafileGetcaProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getca-proc"; proc_class->start = get_ca_start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof(SeafileGetcaProcPriv)); } static void seafile_getca_proc_init (SeafileGetcaProc *processor) { } static int get_ca_start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf = g_string_new (NULL); if (argc < 2) { ccnet_processor_done (processor, FALSE); return -1; } memcpy (priv->repo_id, argv[0], 36); g_string_printf (buf, "remote %s seafile-putca %s %s", processor->peer_id, argv[0], argv[1]); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } static gboolean traverse_commits_cb (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; USE_PRIV; /* Add commit id to list, including last_uploaded and last checkout, * because they can also be the common ancestor. */ priv->commits = g_list_prepend (priv->commits, g_strdup(commit->commit_id)); if (strcmp (commit->commit_id, priv->last_uploaded) == 0 || strcmp (commit->commit_id, priv->last_checkout) == 0) { *stop = TRUE; return TRUE; } return TRUE; } static void * list_commits_thread (void *data) { CcnetProcessor *processor = data; USE_PRIV; char *last_uploaded, *last_checkout; SeafRepo *repo; last_uploaded = seaf_repo_manager_get_repo_property (seaf->repo_mgr, priv->repo_id, REPO_LOCAL_HEAD); if (!last_uploaded) { seaf_warning ("Last uploaded commit id is not found in db.\n"); priv->success = FALSE; return data; } memcpy (priv->last_uploaded, last_uploaded, 40); g_free (last_uploaded); last_checkout = seaf_repo_manager_get_repo_property (seaf->repo_mgr, priv->repo_id, REPO_REMOTE_HEAD); if (!last_checkout) { seaf_warning ("Last checkout commit id is not found in db.\n"); priv->success = FALSE; return data; } memcpy (priv->last_checkout, last_checkout, 40); g_free (last_checkout); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, priv->repo_id); if (!repo) { seaf_warning ("Failed to find repo %s.\n", priv->repo_id); priv->success = FALSE; return data; } /* Since we don't download all commits, some commits may be missing. * But those missing commits (and their ancestors) can't be the common ancestor. */ priv->success = seaf_commit_manager_traverse_commit_tree_truncated (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id, traverse_commits_cb, processor, FALSE); return data; } #define MAX_BUFFER_IDS 500 static void list_commits_done (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; GString *buf; if (!priv->success) { ccnet_processor_done (processor, FALSE); return; } buf = g_string_new (""); GList *ptr; char *id; int n = 0; priv->commits = g_list_reverse (priv->commits); for (ptr = priv->commits; ptr; ptr = ptr->next) { id = ptr->data; g_string_append (buf, id); ++n; if (n == MAX_BUFFER_IDS) { seaf_debug ("Sending %d commit ids.\n", n); ccnet_processor_send_update (processor, SC_ID_LIST, SS_ID_LIST, buf->str, buf->len + 1); n = 0; g_string_free (buf, TRUE); buf = g_string_new (""); } } if (n != 0) { seaf_debug ("Sending %d commit ids.\n", n); ccnet_processor_send_update (processor, SC_ID_LIST, SS_ID_LIST, buf->str, buf->len + 1); } ccnet_processor_send_update (processor, SC_ID_LIST_END, SS_ID_LIST_END, NULL, 0); g_string_free (buf, TRUE); string_list_free (priv->commits); priv->commits = NULL; processor->state = REQUEST_SENT; } static void send_commit_id_list (CcnetProcessor *processor) { ccnet_processor_thread_create (processor, seaf->job_mgr, list_commits_thread, list_commits_done, processor); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetcaProc *proc = (SeafileGetcaProc *)processor; USE_PRIV; switch (processor->state) { case INIT: if (strncmp(code, SC_OK, 3) == 0) { send_commit_id_list (processor); return; } else if (strncmp (code, SC_ACCESS_DENIED, 3) == 0) { seaf_warning ("Access denied to repo %.8s.\n", priv->repo_id); processor->failure = GETCA_PROC_ACCESS_DENIED; ccnet_processor_done (processor, FALSE); return; } break; case REQUEST_SENT: if (strncmp (code, SC_CA, 3) == 0) { if (clen != 41) { seaf_warning ("Bad common ancestor id len %d.\n", clen); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); } memcpy (proc->ca_id, content, 40); ccnet_processor_done (processor, TRUE); return; } else if (strncmp (code, SC_NO_CA, 3) == 0) { seaf_warning ("No common ancestor found for repo %.8s.\n", priv->repo_id); processor->failure = GETCA_PROC_NO_CA; ccnet_processor_done (processor, FALSE); return; } break; default: g_return_if_reached (); } g_warning ("Bad response: %s %s.\n", code, code_msg); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/getca-proc.h000066400000000000000000000024201323477647300210130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETCA_PROC_H #define SEAFILE_GETCA_PROC_H #include #define SEAFILE_TYPE_GETCA_PROC (seafile_getca_proc_get_type ()) #define SEAFILE_GETCA_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETCA_PROC, SeafileGetcaProc)) #define SEAFILE_IS_GETCA_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETCA_PROC)) #define SEAFILE_GETCA_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETCA_PROC, SeafileGetcaProcClass)) #define IS_SEAFILE_GETCA_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETCA_PROC)) #define SEAFILE_GETCA_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETCA_PROC, SeafileGetcaProcClass)) typedef struct _SeafileGetcaProc SeafileGetcaProc; typedef struct _SeafileGetcaProcClass SeafileGetcaProcClass; /* Error code used in processor->failure */ #define GETCA_PROC_ACCESS_DENIED 401 #define GETCA_PROC_NO_CA 404 struct _SeafileGetcaProc { CcnetProcessor parent_instance; char ca_id[41]; }; struct _SeafileGetcaProcClass { CcnetProcessorClass parent_class; }; GType seafile_getca_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getcommit-v2-proc.c000066400000000000000000000170161323477647300222470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include "net.h" #include "utils.h" #include "seaf-utils.h" #include "seafile-session.h" #include "getcommit-v2-proc.h" #include "processors/objecttx-common.h" /* seafile-putcommit-v2 [END] (END is empty in clone) INIT --------------------------> OK <------------------------- Object FETCH_OBJ <------------------------- ... End FETCH_OBJ <-------------------------- */ enum { INIT, RECV_OBJECT }; typedef struct { guint32 writer_id; gboolean recv_ended; int pending_writes; } SeafileGetcommitV2ProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_GETCOMMIT_V2_PROC, SeafileGetcommitV2ProcPriv)) #define USE_PRIV \ SeafileGetcommitV2ProcPriv *priv = GET_PRIV(processor); static int get_commit_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileGetcommitV2Proc, seafile_getcommit_v2_proc, CCNET_TYPE_PROCESSOR) static void release_resource (CcnetProcessor *processor) { USE_PRIV; seaf_obj_store_unregister_async_write (seaf->commit_mgr->obj_store, priv->writer_id); CCNET_PROCESSOR_CLASS (seafile_getcommit_v2_proc_parent_class)->release_resource (processor); } static void seafile_getcommit_v2_proc_class_init (SeafileGetcommitV2ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getcommit-proc-v2"; proc_class->start = get_commit_start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof(SeafileGetcommitV2ProcPriv)); } static void seafile_getcommit_v2_proc_init (SeafileGetcommitV2Proc *processor) { } static void commit_write_cb (OSAsyncResult *res, void *data); static int get_commit_start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf = g_string_new (NULL); TransferTask *task = ((SeafileGetcommitV2Proc *)processor)->tx_task; SeafBranch *master = NULL; char *end_commit_id = NULL; g_return_val_if_fail (task->session_token, -1); if (!task->is_clone) { master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (master != NULL) end_commit_id = master->commit_id; } /* fs_roots can be non-NULL if transfer is resumed from NET_DOWN. */ if (task->fs_roots != NULL) object_list_free (task->fs_roots); task->fs_roots = object_list_new (); priv->writer_id = seaf_obj_store_register_async_write (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, commit_write_cb, processor); if (end_commit_id != NULL) g_string_printf (buf, "remote %s seafile-putcommit-v2 %s %s %s", processor->peer_id, task->head, end_commit_id, task->session_token); else g_string_printf (buf, "remote %s seafile-putcommit-v2 %s %s", processor->peer_id, task->head, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); seaf_branch_unref (master); return 0; } static void commit_write_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; USE_PRIV; TransferTask *task = ((SeafileGetcommitV2Proc *)processor)->tx_task; SeafCommit *commit; if (!res->success) { seaf_warning ("Failed to write commit %.8s.\n", res->obj_id); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } commit = seaf_commit_from_data (res->obj_id, res->data, res->len); if (!commit) { seaf_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return; } if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); seaf_commit_unref (commit); if (--(priv->pending_writes) == 0 && priv->recv_ended) ccnet_processor_done (processor, TRUE); } static int save_commit (CcnetProcessor *processor, ObjectPack *pack, int len) { USE_PRIV; int rc = seaf_obj_store_async_write (seaf->commit_mgr->obj_store, priv->writer_id, pack->id, pack->object, len - 41, FALSE); ++(priv->pending_writes); return rc; } static void receive_commit (CcnetProcessor *processor, char *content, int clen) { ObjectPack *pack = (ObjectPack *)content; if (clen < sizeof(ObjectPack)) { seaf_warning ("[getcommit] invalid object id.\n"); goto bad; } seaf_debug ("[getcommit] recv commit object %.8s\n", pack->id); if (save_commit (processor, pack, clen) < 0) { goto bad; } return; bad: seaf_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (((SeafileGetcommitV2Proc *)processor)->tx_task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetcommitV2Proc *proc = (SeafileGetcommitV2Proc *)processor; USE_PRIV; if (proc->tx_task->state != TASK_STATE_NORMAL) { ccnet_processor_done (processor, TRUE); return; } switch (processor->state) { case INIT: if (strncmp(code, SC_OK, 3) == 0) { processor->state = RECV_OBJECT; return; } break; case RECV_OBJECT: if (strncmp(code, SC_OBJECT, 3) == 0) { receive_commit (processor, content, clen); return; } else if (strncmp (code, SC_END, 3) == 0) { seaf_debug ("[getcommit] Get commit end.\n"); priv->recv_ended = TRUE; if (priv->pending_writes == 0) ccnet_processor_done (processor, TRUE); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (proc->tx_task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/getcommit-v2-proc.h000066400000000000000000000025101323477647300222450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETCOMMIT_V2_PROC_H #define SEAFILE_GETCOMMIT_V2_PROC_H #include #define SEAFILE_TYPE_GETCOMMIT_V2_PROC (seafile_getcommit_v2_proc_get_type ()) #define SEAFILE_GETCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETCOMMIT_V2_PROC, SeafileGetcommitV2Proc)) #define SEAFILE_IS_GETCOMMIT_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETCOMMIT_V2_PROC)) #define SEAFILE_GETCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETCOMMIT_V2_PROC, SeafileGetcommitV2ProcClass)) #define IS_SEAFILE_GETCOMMIT_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETCOMMIT_V2_PROC)) #define SEAFILE_GETCOMMIT_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETCOMMIT_V2_PROC, SeafileGetcommitV2ProcClass)) typedef struct _SeafileGetcommitV2Proc SeafileGetcommitV2Proc; typedef struct _SeafileGetcommitV2ProcClass SeafileGetcommitV2ProcClass; struct _SeafileGetcommitV2Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileGetcommitV2ProcClass { CcnetProcessorClass parent_class; }; GType seafile_getcommit_v2_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getcommit-v3-proc.c000066400000000000000000000140411323477647300222430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include "net.h" #include "utils.h" #include "seaf-utils.h" #include "seafile-session.h" #include "getcommit-v3-proc.h" #include "processors/objecttx-common.h" /* seafile-putcommit-v3 INIT --------------------------> Object <------------------------- */ typedef struct { guint32 writer_id; } SeafileGetcommitV3ProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_GETCOMMIT_V3_PROC, SeafileGetcommitV3ProcPriv)) #define USE_PRIV \ SeafileGetcommitV3ProcPriv *priv = GET_PRIV(processor); static int get_commit_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileGetcommitV3Proc, seafile_getcommit_v3_proc, CCNET_TYPE_PROCESSOR) static void release_resource (CcnetProcessor *processor) { USE_PRIV; seaf_obj_store_unregister_async_write (seaf->commit_mgr->obj_store, priv->writer_id); CCNET_PROCESSOR_CLASS (seafile_getcommit_v3_proc_parent_class)->release_resource (processor); } static void seafile_getcommit_v3_proc_class_init (SeafileGetcommitV3ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getcommit-proc-v3"; proc_class->start = get_commit_start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof(SeafileGetcommitV3ProcPriv)); } static void seafile_getcommit_v3_proc_init (SeafileGetcommitV3Proc *processor) { } static void commit_write_cb (OSAsyncResult *res, void *data); static int get_commit_start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf = g_string_new (NULL); TransferTask *task = ((SeafileGetcommitV3Proc *)processor)->tx_task; SeafBranch *master = NULL; g_return_val_if_fail (task->session_token, -1); /* fs_roots can be non-NULL if transfer is resumed from NET_DOWN. */ if (task->fs_roots != NULL) object_list_free (task->fs_roots); task->fs_roots = object_list_new (); priv->writer_id = seaf_obj_store_register_async_write (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, commit_write_cb, processor); g_string_printf (buf, "remote %s seafile-putcommit-v3 %s %s", processor->peer_id, task->head, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); seaf_branch_unref (master); return 0; } static void commit_write_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileGetcommitV3Proc *)processor)->tx_task; SeafCommit *commit; if (!res->success) { seaf_warning ("Failed to write commit %.8s.\n", res->obj_id); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } commit = seaf_commit_from_data (res->obj_id, res->data, res->len); if (!commit) { seaf_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return; } if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); seaf_commit_unref (commit); ccnet_processor_done (processor, TRUE); } static int save_commit (CcnetProcessor *processor, ObjectPack *pack, int len) { USE_PRIV; int rc = seaf_obj_store_async_write (seaf->commit_mgr->obj_store, priv->writer_id, pack->id, pack->object, len - 41, FALSE); return rc; } static void receive_commit (CcnetProcessor *processor, char *content, int clen) { ObjectPack *pack = (ObjectPack *)content; if (clen < sizeof(ObjectPack)) { seaf_warning ("[getcommit] invalid object id.\n"); goto bad; } seaf_debug ("[getcommit] recv commit object %.8s\n", pack->id); if (save_commit (processor, pack, clen) < 0) { goto bad; } return; bad: seaf_warning ("[getcommit] Bad commit object received.\n"); transfer_task_set_error (((SeafileGetcommitV3Proc *)processor)->tx_task, TASK_ERR_DOWNLOAD_COMMIT); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetcommitV3Proc *proc = (SeafileGetcommitV3Proc *)processor; if (proc->tx_task->state != TASK_STATE_NORMAL) { ccnet_processor_done (processor, TRUE); return; } if (strncmp(code, SC_OK, 3) == 0) { receive_commit (processor, content, clen); return; } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (proc->tx_task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/getcommit-v3-proc.h000066400000000000000000000025101323477647300222460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETCOMMIT_V3_PROC_H #define SEAFILE_GETCOMMIT_V3_PROC_H #include #define SEAFILE_TYPE_GETCOMMIT_V3_PROC (seafile_getcommit_v3_proc_get_type ()) #define SEAFILE_GETCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETCOMMIT_V3_PROC, SeafileGetcommitV3Proc)) #define SEAFILE_IS_GETCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETCOMMIT_V3_PROC)) #define SEAFILE_GETCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETCOMMIT_V3_PROC, SeafileGetcommitV3ProcClass)) #define IS_SEAFILE_GETCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETCOMMIT_V3_PROC)) #define SEAFILE_GETCOMMIT_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETCOMMIT_V3_PROC, SeafileGetcommitV3ProcClass)) typedef struct _SeafileGetcommitV3Proc SeafileGetcommitV3Proc; typedef struct _SeafileGetcommitV3ProcClass SeafileGetcommitV3ProcClass; struct _SeafileGetcommitV3Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileGetcommitV3ProcClass { CcnetProcessorClass parent_class; }; GType seafile_getcommit_v3_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getcs-proc.c000066400000000000000000000072351323477647300210410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include "seafile-session.h" #include "utils.h" #include "db.h" #include "getcs-proc.h" #include "log.h" G_DEFINE_TYPE (SeafileGetcsProc, seafile_getcs_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { CCNET_PROCESSOR_CLASS (seafile_getcs_proc_parent_class)->release_resource (processor); } static void seafile_getcs_proc_class_init (SeafileGetcsProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getcs-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; } static void seafile_getcs_proc_init (SeafileGetcsProc *processor) { } static int start (CcnetProcessor *processor, int argc, char **argv) { char buf[256]; snprintf (buf, 256, "remote %s seafile-putcs", processor->peer_id); ccnet_processor_send_request (processor, buf); return 0; } static gint peer_cmp_func (gconstpointer a, gconstpointer b) { const char *id_a = a; const char *id_b = b; return (g_strcmp0(id_a, id_b)); } static void add_chunk_server (CcnetProcessor *processor, TransferTask *task, char *cs_str) { int num; char *cs_id; char **tokens; tokens = strsplit_by_space (cs_str, &num); if (num < 1) return; cs_id = tokens[0]; if (g_list_find_custom (task->chunk_servers, cs_id, peer_cmp_func) != NULL) goto out; if (strcmp (cs_id, processor->peer_id) == 0) { CcnetPeer *peer = ccnet_get_peer (seaf->ccnetrpc_client, processor->peer_id); g_return_if_fail (peer != NULL); if (!peer->public_addr) { seaf_warning ("Public address of relay %s is not set.\n", cs_id); g_object_unref (peer); goto out; } task->chunk_servers = g_list_prepend (task->chunk_servers, g_strdup(cs_id)); g_object_unref (peer); goto out; } ccnet_add_peer (processor->session, tokens[0], tokens[1]); task->chunk_servers = g_list_prepend (task->chunk_servers, g_strdup(cs_id)); out: free (tokens); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetcsProc *proc = (SeafileGetcsProc *)processor; char *cs_str; if (proc->task->state != TASK_STATE_NORMAL) { g_debug ("Task not running, get-cs proc exits.\n"); ccnet_processor_done (processor, FALSE); return; } if (memcmp (code, SC_OK, 3) != 0) { seaf_warning ("Bad response: %s %s.\n", code, code_msg); ccnet_processor_done (processor, FALSE); return; } if (content[clen-1] != '\0') { seaf_warning ("Bad chunk server list format.\n"); ccnet_processor_done (processor, FALSE); return; } cs_str = strtok (content, "\n"); if (cs_str != NULL) { add_chunk_server (processor, proc->task, cs_str); } else { ccnet_processor_done (processor, TRUE); return; } while ((cs_str = strtok(NULL, "\n")) != NULL) add_chunk_server (processor, proc->task, cs_str); ccnet_processor_done (processor, TRUE); } seafile-6.1.5/daemon/processors/getcs-proc.h000066400000000000000000000023341323477647300210410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETCS_PROC_H #define SEAFILE_GETCS_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_GETCS_PROC (seafile_getcs_proc_get_type ()) #define SEAFILE_GETCS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETCS_PROC, SeafileGetcsProc)) #define SEAFILE_IS_GETCS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETCS_PROC)) #define SEAFILE_GETCS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETCS_PROC, SeafileGetcsProcClass)) #define IS_SEAFILE_GETCS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETCS_PROC)) #define SEAFILE_GETCS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETCS_PROC, SeafileGetcsProcClass)) typedef struct _SeafileGetcsProc SeafileGetcsProc; typedef struct _SeafileGetcsProcClass SeafileGetcsProcClass; struct _SeafileGetcsProc { CcnetProcessor parent_instance; TransferTask *task; }; struct _SeafileGetcsProcClass { CcnetProcessorClass parent_class; }; GType seafile_getcs_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getcs-v2-proc.c000066400000000000000000000072011323477647300213570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include "seafile-session.h" #include "utils.h" #include "getcs-v2-proc.h" #include "log.h" G_DEFINE_TYPE (SeafileGetcsV2Proc, seafile_getcs_v2_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { CCNET_PROCESSOR_CLASS (seafile_getcs_v2_proc_parent_class)->release_resource (processor); } static void seafile_getcs_v2_proc_class_init (SeafileGetcsV2ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getcs-v2-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; } static void seafile_getcs_v2_proc_init (SeafileGetcsV2Proc *processor) { } static int start (CcnetProcessor *processor, int argc, char **argv) { char buf[256]; snprintf (buf, 256, "remote %s seafile-putcs-v2", processor->peer_id); ccnet_processor_send_request (processor, buf); return 0; } static int add_chunk_server (CcnetProcessor *processor, TransferTask *task, char *cs_str) { char **tokens; CcnetPeer *peer; ChunkServer *cs; tokens = g_strsplit (cs_str, ":", -1); if (g_strv_length (tokens) != 2) { seaf_warning ("Invalid chunk server address format: %s.\n", cs_str); g_strfreev (tokens); return -1; } peer = ccnet_get_peer (seaf->ccnetrpc_client, processor->peer_id); if (!peer) { seaf_warning ("[getcs] Invalid peer %s.\n", processor->peer_id); g_strfreev (tokens); return -1; } if (!peer->addr_str) { seaf_warning ("[getcs] Peer doesn't have an address.\n"); g_object_unref (peer); g_strfreev (tokens); return -1; } cs = g_new0 (ChunkServer, 1); cs->addr = g_strdup (peer->addr_str); cs->port = atoi (tokens[1]); task->chunk_servers = g_list_prepend (task->chunk_servers, cs); g_strfreev (tokens); g_object_unref (peer); return 0; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetcsV2Proc *proc = (SeafileGetcsV2Proc *)processor; char *cs_str; if (proc->task->state != TASK_STATE_NORMAL) { g_debug ("Task not running, get-cs proc exits.\n"); ccnet_processor_done (processor, FALSE); return; } if (memcmp (code, SC_OK, 3) != 0) { seaf_warning ("Bad response: %s %s.\n", code, code_msg); ccnet_processor_done (processor, FALSE); return; } if (content[clen-1] != '\0') { seaf_warning ("Bad chunk server list format.\n"); ccnet_processor_done (processor, FALSE); return; } cs_str = strtok (content, "\n"); if (cs_str != NULL) { if (add_chunk_server (processor, proc->task, cs_str) < 0) goto error; } else { ccnet_processor_done (processor, TRUE); return; } while ((cs_str = strtok(NULL, "\n")) != NULL) { if (add_chunk_server (processor, proc->task, cs_str) < 0) goto error; } ccnet_processor_done (processor, TRUE); error: ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/getcs-v2-proc.h000066400000000000000000000024331323477647300213660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETCS_V2_PROC_H #define SEAFILE_GETCS_V2_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_GETCS_V2_PROC (seafile_getcs_v2_proc_get_type ()) #define SEAFILE_GETCS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETCS_V2_PROC, SeafileGetcsV2Proc)) #define SEAFILE_IS_GETCS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETCS_V2_PROC)) #define SEAFILE_GETCS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETCS_V2_PROC, SeafileGetcsV2ProcClass)) #define IS_SEAFILE_GETCS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETCS_V2_PROC)) #define SEAFILE_GETCS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETCS_V2_PROC, SeafileGetcsV2ProcClass)) typedef struct _SeafileGetcsV2Proc SeafileGetcsV2Proc; typedef struct _SeafileGetcsV2ProcClass SeafileGetcsV2ProcClass; struct _SeafileGetcsV2Proc { CcnetProcessor parent_instance; TransferTask *task; }; struct _SeafileGetcsV2ProcClass { CcnetProcessorClass parent_class; }; GType seafile_getcs_v2_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getfs-proc.c000066400000000000000000000431261323477647300210430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include #include #include "utils.h" #include "seaf-utils.h" #include "seafile-session.h" #include "commit-mgr.h" #include "fs-mgr.h" #include "processors/objecttx-common.h" #include "getfs-proc.h" #include "transfer-mgr.h" /* * Implementation Notes: * * Checking and writing of fs objects are completely asynchronous in this processor. * - FS object checking is done by a worker thread. * - Writing of received fs objects is done with the async obj-store API. * * At the beginning, all root object id is put into inspect queue. And then * We start a worker thread to check the first object in the inspect queue. * * After the worker thread is done, we send object requests in the main thread. * And then we start a worker to check the next object in the inspect queue. * * After an object is received and store asynchronously into disk, and if the object * is a directory, we put it into the inspect queue. And then we start a worker * to check the next object in the inspect queue, if no worker is running. * This means only 1 worker can be running at the same time. Because we use thread * pool, there will be no performance problem of creating threads. * * The end condition is checked after: * - worker thread is done * - an object is written * The end condition is * - inspect queue is empty, and * - no object request is pending, and * - no worker is running */ #define MAX_NUM_BATCH 64 enum { REQUEST_SENT, FETCH_OBJECT }; typedef struct ThreadData { gint refcnt; CcnetProcessor *processor; gboolean is_clone; int cmd_pipe; uint32_t cevent_id; char root_id[41]; GHashTable *fs_objects; GList *fetch_objs; char repo_id[37]; int repo_version; } ThreadData; typedef struct { gboolean worker_checking; gboolean worker_started; GQueue *inspect_queue; /* objects to check exists */ int pending_objects; guint32 writer_id; /* Used by worker thread */ int cmd_pipe[2]; uint32_t cevent_id; ThreadData *tdata; char buf[4096]; char *bufptr; int n_batch; char *obj_seg; int obj_seg_len; } SeafileGetfsProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_GETFS_PROC, SeafileGetfsProcPriv)) #define USE_PRIV \ SeafileGetfsProcPriv *priv = GET_PRIV(processor); G_DEFINE_TYPE (SeafileGetfsProc, seafile_getfs_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void thread_data_ref (ThreadData *tdata) { g_atomic_int_inc (&tdata->refcnt); } static void thread_data_unref (ThreadData *tdata) { if (g_atomic_int_dec_and_test (&tdata->refcnt)) { if (tdata->fetch_objs) string_list_free (tdata->fetch_objs); if (tdata->fs_objects) g_hash_table_destroy (tdata->fs_objects); g_free (tdata); } } static void release_resource(CcnetProcessor *processor) { USE_PRIV; g_queue_free (priv->inspect_queue); g_free (priv->obj_seg); seaf_obj_store_unregister_async_write (seaf->fs_mgr->obj_store, priv->writer_id); if (priv->worker_started) { /* The worker thread will notice the command pipe has been closed and exits. */ pipeclose (priv->cmd_pipe[1]); cevent_manager_unregister (seaf->ev_mgr, priv->cevent_id); thread_data_unref (priv->tdata); } CCNET_PROCESSOR_CLASS (seafile_getfs_proc_parent_class)->release_resource (processor); } static void seafile_getfs_proc_class_init (SeafileGetfsProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getfs-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof (SeafileGetfsProcPriv)); } static void seafile_getfs_proc_init (SeafileGetfsProc *processor) { } inline static void request_object_batch_begin (SeafileGetfsProcPriv *priv) { priv->bufptr = priv->buf; priv->n_batch = 0; } inline static void request_object_batch_flush (CcnetProcessor *processor, SeafileGetfsProcPriv *priv) { if (priv->bufptr == priv->buf) return; *priv->bufptr = '\0'; /* add ending '\0' */ priv->bufptr++; ccnet_processor_send_update (processor, SC_GET_OBJECT, SS_GET_OBJECT, priv->buf, priv->bufptr - priv->buf); /* Clean state */ priv->n_batch = 0; priv->bufptr = priv->buf; } inline static void request_object_batch (CcnetProcessor *processor, SeafileGetfsProcPriv *priv, const char *id) { memcpy (priv->bufptr, id, 40); priv->bufptr += 40; *priv->bufptr = '\n'; priv->bufptr++; if (++priv->n_batch == MAX_NUM_BATCH) request_object_batch_flush (processor, priv); ++priv->pending_objects; } /* * Recursively check fs tree rooted at @dir_id. This function returns when * all non-existent or invalid objects have been put into data->fetch_objs. */ static void check_seafdir (ThreadData *tdata, const char *dir_id) { SeafDir *dir = NULL; GList *ptr; SeafDirent *dent; if (!seaf_fs_manager_object_exists(seaf->fs_mgr, tdata->repo_id, tdata->repo_version, dir_id)) { tdata->fetch_objs = g_list_prepend (tdata->fetch_objs, g_strdup(dir_id)); return; } dir = seaf_fs_manager_get_seafdir (seaf->fs_mgr, tdata->repo_id, tdata->repo_version, dir_id); if (!dir) { /* corrupt dir object */ tdata->fetch_objs = g_list_prepend (tdata->fetch_objs, g_strdup(dir_id)); return; } for (ptr = dir->entries; ptr; ptr = ptr->next) { dent = ptr->data; /* Don't check objects that have been checked before. */ if (g_hash_table_lookup (tdata->fs_objects, dent->id)) continue; g_hash_table_insert (tdata->fs_objects, g_strdup(dent->id), (gpointer)1); if (!seaf_fs_manager_object_exists(seaf->fs_mgr, tdata->repo_id, tdata->repo_version, dent->id)) { tdata->fetch_objs = g_list_prepend (tdata->fetch_objs, g_strdup(dent->id)); continue; } if (S_ISDIR(dent->mode)) { check_seafdir (tdata, dent->id); } else if (S_ISREG (dent->mode) && tdata->is_clone) { /* Only check seafile object integrity when clone. * This is for the purpose of recovery. * In ordinary sync, checking every file object's integrity would * take too much CPU time. */ gboolean ok; gboolean err = FALSE; ok = seaf_fs_manager_verify_seafile (seaf->fs_mgr, tdata->repo_id, tdata->repo_version, dent->id, TRUE, &err); if (!ok && !err) { seaf_warning ("File object %.8s is corrupt, recover from server.\n", dent->id); tdata->fetch_objs = g_list_prepend (tdata->fetch_objs, g_strdup(dent->id)); } } } seaf_dir_free (dir); } static gboolean check_end_condition (SeafileGetfsProcPriv *priv) { return (g_queue_get_length (priv->inspect_queue) == 0 && priv->pending_objects == 0 && !priv->worker_checking); } static int check_fs_tree_from (ThreadData *tdata, const char *root_id); static void end_or_check_next_dir (CcnetProcessor *processor, SeafileGetfsProcPriv *priv) { if (check_end_condition (priv)) { seaf_debug ("Get fs end.\n"); ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } if (priv->worker_checking) { return; } /* Trigger checking the next dir. */ char *next_dir_id = g_queue_pop_head (priv->inspect_queue); if (next_dir_id) { if (check_fs_tree_from (priv->tdata, next_dir_id) < 0) { transfer_task_set_error (((SeafileGetfsProc *)processor)->tx_task, TASK_ERR_DOWNLOAD_FS); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); } g_free (next_dir_id); } } static void * check_objects_thread (void *vdata) { ThreadData *tdata = vdata; int cmd; /* Hold one reference for worker thread. */ thread_data_ref (tdata); while (1) { int n = piperead (tdata->cmd_pipe, (char*)&cmd, sizeof(cmd)); if (n < 0) { seaf_warning ("Failed to read commnd pipe: %s.\n", strerror(errno)); goto out; } if (n == 0) { seaf_message ("Getfs proc is done, worker thread exits.\n"); goto out; } check_seafdir (tdata, tdata->root_id); cevent_manager_add_event (seaf->ev_mgr, tdata->cevent_id, tdata); } out: pipeclose (tdata->cmd_pipe); thread_data_unref (tdata); return vdata; } static void check_objects_done (CEvent *event, void *unused) { ThreadData *tdata = event->data; CcnetProcessor *processor = tdata->processor; USE_PRIV; GList *ptr; char *obj_id; priv->worker_checking = FALSE; request_object_batch_begin (priv); for (ptr = tdata->fetch_objs; ptr; ptr = ptr->next) { obj_id = ptr->data; request_object_batch (processor, priv, obj_id); g_free (obj_id); } request_object_batch_flush (processor, priv); g_list_free (tdata->fetch_objs); tdata->fetch_objs = NULL; end_or_check_next_dir (processor, priv); } static int check_fs_tree_from (ThreadData *tdata, const char *root_id) { CcnetProcessor *processor = tdata->processor; USE_PRIV; memcpy (tdata->root_id, root_id, 40); tdata->fetch_objs = NULL; int cmd = 1; pipewrite (priv->cmd_pipe[1], (char*)&cmd, sizeof(cmd)); priv->worker_checking = TRUE; return 0; } static void fs_object_write_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileGetfsProc *)processor)->tx_task; USE_PRIV; if (!res->success) { seaf_warning ("Failed to write object %.8s.\n", res->obj_id); transfer_task_set_error (task, TASK_ERR_DOWNLOAD_FS); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } seaf_debug ("Written object %.8s.\n", res->obj_id); --(priv->pending_objects); int type = seaf_metadata_type_from_data (res->obj_id, res->data, res->len, (task->repo_version > 0)); if (type == SEAF_METADATA_TYPE_DIR) g_queue_push_tail (priv->inspect_queue, g_strdup(res->obj_id)); end_or_check_next_dir (processor, priv); } static int save_fs_object (SeafileGetfsProcPriv *priv, ObjectPack *pack, int len) { return seaf_obj_store_async_write (seaf->fs_mgr->obj_store, priv->writer_id, pack->id, pack->object, len - 41, FALSE); } static int recv_fs_object (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; ObjectPack *pack = (ObjectPack *)content; /* TransferTask *task = ((SeafileGetfsProc *)processor)->tx_task; */ if (clen < sizeof(ObjectPack)) { seaf_warning ("[getfs] invalid object id.\n"); goto bad; } /* TODO: check fs object integrity. */ if (save_fs_object (priv, pack, clen) < 0) { goto bad; } return 0; bad: seaf_warning ("Bad fs object received.\n"); transfer_task_set_error (((SeafileGetfsProc *)processor)->tx_task, TASK_ERR_DOWNLOAD_FS); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return -1; } static void recv_fs_object_seg (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; /* Append the received object segment to the end */ priv->obj_seg = g_realloc (priv->obj_seg, priv->obj_seg_len + clen); memcpy (priv->obj_seg + priv->obj_seg_len, content, clen); seaf_debug ("Get obj seg: \n", priv->obj_seg, priv->obj_seg_len, clen); priv->obj_seg_len += clen; } static void process_fs_object_seg (CcnetProcessor *processor) { USE_PRIV; if (recv_fs_object (processor, priv->obj_seg, priv->obj_seg_len) == 0) { g_free (priv->obj_seg); priv->obj_seg = NULL; priv->obj_seg_len = 0; } } static int start_worker_thread (CcnetProcessor *processor) { SeafileGetfsProc *proc = (SeafileGetfsProc *)processor; USE_PRIV; ThreadData *tdata; if (ccnet_pipe (priv->cmd_pipe) < 0) return -1; priv->cevent_id = cevent_manager_register (seaf->ev_mgr, check_objects_done, processor); tdata = g_new0 (ThreadData, 1); tdata->cmd_pipe = priv->cmd_pipe[0]; tdata->cevent_id = priv->cevent_id; tdata->processor = processor; tdata->is_clone = proc->tx_task->is_clone; tdata->fs_objects = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); memcpy (tdata->repo_id, proc->tx_task->repo_id, 36); tdata->repo_version = proc->tx_task->repo_version; /* Hold one reference for the main thread. */ thread_data_ref (tdata); priv->tdata = tdata; ccnet_job_manager_schedule_job (seaf->job_mgr, check_objects_thread, NULL, tdata); priv->worker_started = TRUE; return 0; } static void load_fsroot_list (CcnetProcessor *processor) { USE_PRIV; SeafileGetfsProc *proc = (SeafileGetfsProc *) processor; ObjectList *ol = proc->tx_task->fs_roots; int i; int ollen = object_list_length (ol); for (i = 0; i < ollen; i++) { g_queue_push_tail (priv->inspect_queue, g_strdup(g_ptr_array_index(ol->obj_ids, i))); } /* Kick start fs object checking. */ end_or_check_next_dir (processor, priv); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileGetfsProc *proc = (SeafileGetfsProc *)processor; TransferTask *task = proc->tx_task; switch (processor->state) { case REQUEST_SENT: if (strncmp(code, SC_OK, 3) == 0) { if (start_worker_thread (processor) < 0) { ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } load_fsroot_list (processor); processor->state = FETCH_OBJECT; return; } break; case FETCH_OBJECT: if (strncmp(code, SC_OBJ_SEG, 3) == 0) { recv_fs_object_seg (processor, content, clen); return; } else if (strncmp(code, SC_OBJ_SEG_END, 3) == 0) { recv_fs_object_seg (processor, content, clen); process_fs_object_seg (processor); return; } else if (strncmp(code, SC_OBJECT, 3) == 0) { recv_fs_object (processor, content, clen); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } static int start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; TransferTask *task = ((SeafileGetfsProc *)processor)->tx_task; GString *buf = g_string_new (NULL); if (task->session_token) g_string_printf (buf, "remote %s seafile-putfs %s", processor->peer_id, task->session_token); else g_string_printf (buf, "remote %s seafile-putfs", processor->peer_id); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); processor->state = REQUEST_SENT; priv->inspect_queue = g_queue_new (); priv->writer_id = seaf_obj_store_register_async_write (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, fs_object_write_cb, processor); return 0; } seafile-6.1.5/daemon/processors/getfs-proc.h000066400000000000000000000023031323477647300210400ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETFS_PROC_H #define SEAFILE_GETFS_PROC_H #include #include "transfer-mgr.h" #define SEAFILE_TYPE_GETFS_PROC (seafile_getfs_proc_get_type ()) #define SEAFILE_GETFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETFS_PROC, SeafileGetfsProc)) #define SEAFILE_IS_GETFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETFS_PROC)) #define SEAFILE_GETFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETFS_PROC, SeafileGetfsProcClass)) #define IS_SEAFILE_GETFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETFS_PROC)) #define SEAFILE_GETFS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETFS_PROC, SeafileGetfsProcClass)) typedef struct _SeafileGetfsProc SeafileGetfsProc; typedef struct _SeafileGetfsProcClass SeafileGetfsProcClass; struct _SeafileGetfsProc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileGetfsProcClass { CcnetProcessorClass parent_class; }; GType seafile_getfs_proc_get_type (); #endif seafile-6.1.5/daemon/processors/getfs-v2-proc.c000066400000000000000000000311361323477647300213660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include #include #include #include "utils.h" #include "seafile-session.h" #include "fs-mgr.h" #include "processors/objecttx-common.h" #include "getfs-v2-proc.h" #include "seaf-utils.h" /* * putfs-v2-proc server-head-id [client-head-id] * ------------------------------> * OK * <----------------------------- * * The server uses diff to calculate objects to put * * SC_OBJ_LIST_SEG * <----------------------------- * ...... * SC_OBJ_LIST_SEG_END * <----------------------------- * * The client calculates the list of objects to get * * SC_OBJ_LIST_SEG * -----------------------------> * ...... * SC_OBJ * <---------------------------- * ...... * SC_END * -----------------------------> * * After all objects are written to disk, the client ends the protocol */ enum { INIT = 0, CHECK_OBJECT_LIST, GET_OBJECTS, }; typedef struct { char *obj_seg; int obj_seg_len; gboolean registered; guint32 writer_id; /* Used to check object list */ GList *recv_objs; GList *needed_objs; int n_pending; int n_saved; } SeafileGetfsProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_GETFS_V2_PROC, SeafileGetfsProcPriv)) #define USE_PRIV \ SeafileGetfsProcPriv *priv = GET_PRIV(processor); G_DEFINE_TYPE (SeafileGetfsV2Proc, seafile_getfs_v2_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { USE_PRIV; g_free (priv->obj_seg); if (priv->registered) { seaf_obj_store_unregister_async_write (seaf->fs_mgr->obj_store, priv->writer_id); } string_list_free (priv->recv_objs); string_list_free (priv->needed_objs); CCNET_PROCESSOR_CLASS (seafile_getfs_v2_proc_parent_class)->release_resource (processor); } static void seafile_getfs_v2_proc_class_init (SeafileGetfsV2ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "getfs-v2-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof (SeafileGetfsProcPriv)); } static void seafile_getfs_v2_proc_init (SeafileGetfsV2Proc *processor) { } static void on_fs_write (OSAsyncResult *res, void *cb_data); static int start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf; SeafileGetfsV2Proc *proc = (SeafileGetfsV2Proc *)processor; TransferTask *task = proc->tx_task; buf = g_string_new (NULL); if (!task->is_clone) { SeafBranch *master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Master branch not found for repo %s.\n", task->repo_id); g_string_free (buf, TRUE); ccnet_processor_done (processor, FALSE); return -1; } g_string_printf (buf, "remote %s seafile-putfs-v2 %s %s %s", processor->peer_id, task->session_token, task->head, master->commit_id); seaf_branch_unref (master); } else g_string_printf (buf, "remote %s seafile-putfs-v2 %s %s", processor->peer_id, task->session_token, task->head); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); priv->registered = TRUE; priv->writer_id = seaf_obj_store_register_async_write (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, on_fs_write, processor); return 0; } static void send_object_list_segment (CcnetProcessor *processor); static void on_fs_write (OSAsyncResult *res, void *cb_data) { CcnetProcessor *processor = cb_data; USE_PRIV; if (!res->success) { seaf_warning ("[getfs] Failed to write %s.\n", res->obj_id); ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); ccnet_processor_done (processor, FALSE); return; } seaf_debug ("[getfs] Wrote fs object %s.\n", res->obj_id); if (++(priv->n_saved) == priv->n_pending) send_object_list_segment (processor); } static int save_fs_object (CcnetProcessor *processor, ObjectPack *pack, int len) { USE_PRIV; return seaf_obj_store_async_write (seaf->fs_mgr->obj_store, priv->writer_id, pack->id, pack->object, len - 41, FALSE); } static int recv_fs_object (CcnetProcessor *processor, char *content, int clen) { ObjectPack *pack = (ObjectPack *)content; /* SeafFSObject *fs_obj = NULL; */ if (clen < sizeof(ObjectPack)) { seaf_warning ("invalid object id.\n"); goto bad; } seaf_debug ("[getfs] Recv fs object %.8s.\n", pack->id); /* Check object integrity by parsing it. */ /* fs_obj = seaf_fs_object_from_data(pack->id, */ /* pack->object, clen - sizeof(ObjectPack), */ /* (priv->repo_version > 0)); */ /* if (!fs_obj) { */ /* seaf_warning ("Bad fs object %s.\n", pack->id); */ /* goto bad; */ /* } */ /* seaf_fs_object_free (fs_obj); */ if (save_fs_object (processor, pack, clen) < 0) { goto bad; } return 0; bad: ccnet_processor_send_update (processor, SC_BAD_OBJECT, SS_BAD_OBJECT, NULL, 0); seaf_warning ("[getfs] Bad fs object received.\n"); ccnet_processor_done (processor, FALSE); /* seaf_fs_object_free (fs_obj); */ return -1; } static void recv_fs_object_seg (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; /* Append the received object segment to the end */ priv->obj_seg = g_realloc (priv->obj_seg, priv->obj_seg_len + clen); memcpy (priv->obj_seg + priv->obj_seg_len, content, clen); seaf_debug ("[getfs] Get obj seg: \n", priv->obj_seg, priv->obj_seg_len, clen); priv->obj_seg_len += clen; } static void process_fs_object_seg (CcnetProcessor *processor) { USE_PRIV; if (recv_fs_object (processor, priv->obj_seg, priv->obj_seg_len) == 0) { g_free (priv->obj_seg); priv->obj_seg = NULL; priv->obj_seg_len = 0; } } static void * calculate_needed_object_list (void *data) { CcnetProcessor *processor = data; USE_PRIV; SeafileGetfsV2Proc *proc = (SeafileGetfsV2Proc *)processor; TransferTask *task = proc->tx_task; GList *ptr; char *obj_id; GHashTable *checked_objs; int dummy; checked_objs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (ptr = priv->recv_objs; ptr; ptr = ptr->next) { obj_id = ptr->data; if (g_hash_table_lookup (checked_objs, obj_id)) { g_free (obj_id); continue; } g_hash_table_insert (checked_objs, g_strdup(obj_id), &dummy); if (!seaf_obj_store_obj_exists (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, obj_id)) priv->needed_objs = g_list_prepend (priv->needed_objs, obj_id); else g_free (obj_id); } g_hash_table_destroy (checked_objs); g_list_free (priv->recv_objs); priv->recv_objs = NULL; return data; } #define OBJECT_LIST_SEGMENT_N 1000 #define OBJECT_LIST_SEGMENT_LEN 40 * 1000 static void send_object_list_segment (CcnetProcessor *processor) { USE_PRIV; char buf[OBJECT_LIST_SEGMENT_LEN]; if (priv->needed_objs == NULL) { seaf_debug ("All objects saved. Done.\n"); ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } priv->n_pending = 0; priv->n_saved = 0; int i = 0; char *p = buf; char *obj_id; while (priv->needed_objs != NULL) { obj_id = priv->needed_objs->data; priv->needed_objs = g_list_delete_link (priv->needed_objs, priv->needed_objs); memcpy (p, obj_id, 40); p += 40; g_free (obj_id); if (++i == OBJECT_LIST_SEGMENT_N) break; } if (i > 0) { seaf_debug ("Send %d object ids.\n", i); priv->n_pending = i; ccnet_processor_send_update (processor, SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, buf, i * 40); } } static void calculate_needed_object_list_done (void *data) { CcnetProcessor *processor = data; send_object_list_segment (processor); processor->state = GET_OBJECTS; } static void process_recv_object_list (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; int n, i; char *p; char *obj_id; n = clen/40; p = content; seaf_debug ("Recv %d object ids.\n", n); for (i = 0; i < n; ++i) { obj_id = g_strndup (p, 40); priv->recv_objs = g_list_prepend (priv->recv_objs, obj_id); p += 40; } } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { switch (processor->state) { case INIT: if (strncmp (code, SC_OK, 3) == 0) processor->state = CHECK_OBJECT_LIST; else { seaf_warning ("Bad response: %s %s\n", code, code_msg); ccnet_processor_done (processor, FALSE); } break; case CHECK_OBJECT_LIST: if (strncmp (code, SC_OBJ_LIST_SEG, 3) == 0) { if (clen % 40 != 0) { seaf_warning ("Invalid object list segment length %d.\n", clen); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } process_recv_object_list (processor, content, clen); } else if (strncmp (code, SC_OBJ_LIST_SEG_END, 3) == 0) { ccnet_processor_thread_create (processor, seaf->job_mgr, calculate_needed_object_list, calculate_needed_object_list_done, processor); } else if (strncmp (code, SC_END, 3) == 0) { /* The server finds nothing to put. */ ccnet_processor_done (processor, TRUE); } else { seaf_warning ("Bad response: %s %s\n", code, code_msg); ccnet_processor_send_update (processor, SC_BAD_RESPONSE_CODE, SS_BAD_RESPONSE_CODE, NULL, 0); ccnet_processor_done (processor, FALSE); } break; case GET_OBJECTS: if (strncmp(code, SC_OBJ_SEG, 3) == 0) { recv_fs_object_seg (processor, content, clen); } else if (strncmp(code, SC_OBJ_SEG_END, 3) == 0) { recv_fs_object_seg (processor, content, clen); process_fs_object_seg (processor); } else if (strncmp(code, SC_OBJECT, 3) == 0) { recv_fs_object (processor, content, clen); } else { seaf_warning ("Bad response: %s %s\n", code, code_msg); ccnet_processor_send_update (processor, SC_BAD_RESPONSE_CODE, SS_BAD_RESPONSE_CODE, NULL, 0); ccnet_processor_done (processor, FALSE); } break; default: g_return_if_reached (); } } seafile-6.1.5/daemon/processors/getfs-v2-proc.h000066400000000000000000000024371323477647300213750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_GETFS_V2_PROC_H #define SEAFILE_GETFS_V2_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_GETFS_V2_PROC (seafile_getfs_v2_proc_get_type ()) #define SEAFILE_GETFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_GETFS_V2_PROC, SeafileGetfsV2Proc)) #define SEAFILE_IS_GETFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_GETFS_V2_PROC)) #define SEAFILE_GETFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_GETFS_V2_PROC, SeafileGetfsV2ProcClass)) #define IS_SEAFILE_GETFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_GETFS_V2_PROC)) #define SEAFILE_GETFS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_GETFS_V2_PROC, SeafileGetfsV2ProcClass)) typedef struct _SeafileGetfsV2Proc SeafileGetfsV2Proc; typedef struct _SeafileGetfsV2ProcClass SeafileGetfsV2ProcClass; struct _SeafileGetfsV2Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileGetfsV2ProcClass { CcnetProcessorClass parent_class; }; GType seafile_getfs_v2_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendbranch-proc.c000066400000000000000000000063741323477647300220460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include #include #include "sendbranch-proc.h" #include "log.h" #define SC_NOT_FF "402" #define SS_NOT_FF "Not fast forward" #define SC_QUOTA_ERROR "403" #define SS_QUOTA_ERROR "Failed to get quota" #define SC_QUOTA_FULL "404" #define SS_QUOTA_FULL "storage for the repo's owner is full" #define SC_ACCESS_DENIED "410" #define SS_ACCESS_DENIED "Access denied" G_DEFINE_TYPE (SeafileSendbranchProc, seafile_sendbranch_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { /* FILL IT */ CCNET_PROCESSOR_CLASS (seafile_sendbranch_proc_parent_class)->release_resource (processor); } static void seafile_sendbranch_proc_class_init (SeafileSendbranchProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; proc_class->name = "sendbranch-proc"; } static void seafile_sendbranch_proc_init (SeafileSendbranchProc *processor) { } static int start (CcnetProcessor *processor, int argc, char **argv) { char *repo_id, *branch, *new_head; GString *buf; TransferTask *task = ((SeafileSendbranchProc *)processor)->task; if (argc != 3) { return -1; } repo_id = argv[0]; branch = argv[1]; new_head = argv[2]; buf = g_string_new (NULL); if (task->protocol_version <= 6) g_string_printf (buf, "remote %s seafile-recvbranch %s %s %s %s", processor->peer_id, repo_id, branch, new_head, task->session_token); else g_string_printf (buf, "remote %s seafile-recvbranch-v2 %s %s %s %s", processor->peer_id, repo_id, branch, new_head, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendbranchProc *proc = (SeafileSendbranchProc *)processor; TransferTask *task = proc->task; if (memcmp (code, SC_OK, 3) == 0) { ccnet_processor_done (processor, TRUE); } else { seaf_warning ("[sendbranch] Bad response: %s.\n", code_msg); if (strncmp(code, SC_NOT_FF, 3) == 0) transfer_task_set_error (task, TASK_ERR_NOT_FAST_FORWARD); else if (strncmp(code, SC_QUOTA_ERROR, 3) == 0) transfer_task_set_error (task, TASK_ERR_CHECK_QUOTA); else if (strncmp(code, SC_QUOTA_FULL, 3) == 0) transfer_task_set_error (task, TASK_ERR_QUOTA_FULL); else if (strncmp(code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); else transfer_task_set_error (task, TASK_ERR_UNKNOWN); ccnet_processor_done (processor, FALSE); } } seafile-6.1.5/daemon/processors/sendbranch-proc.h000066400000000000000000000025251323477647300220450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDBRANCH_PROC_H #define SEAFILE_SENDBRANCH_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_SENDBRANCH_PROC (seafile_sendbranch_proc_get_type ()) #define SEAFILE_SENDBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDBRANCH_PROC, SeafileSendbranchProc)) #define SEAFILE_IS_SENDBRANCH_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDBRANCH_PROC)) #define SEAFILE_SENDBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDBRANCH_PROC, SeafileSendbranchProcClass)) #define IS_SEAFILE_SENDBRANCH_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDBRANCH_PROC)) #define SEAFILE_SENDBRANCH_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDBRANCH_PROC, SeafileSendbranchProcClass)) typedef struct _SeafileSendbranchProc SeafileSendbranchProc; typedef struct _SeafileSendbranchProcClass SeafileSendbranchProcClass; struct _SeafileSendbranchProc { CcnetProcessor parent_instance; TransferTask *task; }; struct _SeafileSendbranchProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendbranch_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendcommit-v3-new-proc.c000066400000000000000000000233011323477647300232030ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include "net.h" #include "utils.h" #include "seafile-session.h" #include "sendcommit-v3-new-proc.h" #include "processors/objecttx-common.h" #include "vc-common.h" /* seafile-recvcommit-v3 INIT ---------------------> 200 OK INIT <--------------------- Object SEND_OBJ -----------------------> Ack or Bad Object <--------------------- ... End -----------------------> */ enum { INIT, SEND_OBJECT }; typedef struct { char remote_id[41]; char last_uploaded_id[41]; GList *id_list; gboolean visited_last_uploaded; gboolean compute_success; } SeafileSendcommitProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC, SeafileSendcommitProcPriv)) #define USE_PRIV \ SeafileSendcommitProcPriv *priv = GET_PRIV(processor); static int send_commit_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileSendcommitV3NewProc, seafile_sendcommit_v3_new_proc, CCNET_TYPE_PROCESSOR) static void release_resource (CcnetProcessor *processor) { USE_PRIV; if (priv->id_list != NULL) string_list_free (priv->id_list); CCNET_PROCESSOR_CLASS (seafile_sendcommit_v3_new_proc_parent_class)->release_resource (processor); } static void seafile_sendcommit_v3_new_proc_class_init (SeafileSendcommitV3NewProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "sendcommit-v3-new-proc"; proc_class->start = send_commit_start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof (SeafileSendcommitProcPriv)); } static void seafile_sendcommit_v3_new_proc_init (SeafileSendcommitV3NewProc *processor) { } static int send_commit_start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf; TransferTask *task = ((SeafileSendcommitV3NewProc *)processor)->tx_task; memcpy (priv->remote_id, task->remote_head, 41); /* fs_roots can be non-NULL if transfer is resumed from NET_DOWN. */ if (task->fs_roots != NULL) object_list_free (task->fs_roots); task->fs_roots = object_list_new (); if (task->commits != NULL) object_list_free (task->commits); task->commits = object_list_new (); buf = g_string_new (NULL); g_string_printf (buf, "remote %s seafile-recvcommit-v3 %s %s", processor->peer_id, task->to_branch, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } static void send_commit (CcnetProcessor *processor, const char *object_id) { TransferTask *task = ((SeafileSendcommitV3NewProc *)processor)->tx_task; char *data; int len; ObjectPack *pack = NULL; int pack_size; if (seaf_obj_store_read_obj (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, object_id, (void**)&data, &len) < 0) { seaf_warning ("Failed to read commit %s.\n", object_id); goto fail; } pack_size = sizeof(ObjectPack) + len; pack = malloc (pack_size); memcpy (pack->id, object_id, 41); memcpy (pack->object, data, len); ccnet_processor_send_update (processor, SC_OBJECT, SS_OBJECT, (char *)pack, pack_size); seaf_debug ("Send commit %.8s.\n", object_id); g_free (data); free (pack); return; fail: ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, object_id, 41); ccnet_processor_done (processor, FALSE); } static void send_one_commit (CcnetProcessor *processor) { USE_PRIV; char *commit_id; if (!priv->id_list) { ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } commit_id = priv->id_list->data; priv->id_list = g_list_delete_link (priv->id_list, priv->id_list); send_commit (processor, commit_id); g_free (commit_id); } static gboolean collect_upload_commit_ids (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3NewProc *)processor)->tx_task; USE_PRIV; if (strcmp (priv->last_uploaded_id, commit->commit_id) == 0) { priv->visited_last_uploaded = TRUE; *stop = TRUE; return TRUE; } if (priv->remote_id[0] != 0 && strcmp (priv->remote_id, commit->commit_id) == 0) { *stop = TRUE; return TRUE; } if (commit->parent_id && !seaf_commit_manager_commit_exists (seaf->commit_mgr, commit->repo_id, commit->version, commit->parent_id)) { *stop = TRUE; return TRUE; } if (commit->second_parent_id && !seaf_commit_manager_commit_exists (seaf->commit_mgr, commit->repo_id, commit->version, commit->second_parent_id)) { *stop = TRUE; return TRUE; } priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); /* We don't need to send the contents under an empty dir. */ if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); return TRUE; } static void * compute_upload_commits_thread (void *vdata) { CcnetProcessor *processor = vdata; SeafileSendcommitV3NewProc *proc = (SeafileSendcommitV3NewProc *)processor; TransferTask *task = proc->tx_task; USE_PRIV; gboolean ret; ret = seaf_commit_manager_traverse_commit_tree_truncated (seaf->commit_mgr, task->repo_id, task->repo_version, task->head, collect_upload_commit_ids, processor, FALSE); if (!ret) { priv->compute_success = FALSE; return vdata; } /* We have to make sure all commits that need to be uploaded are found locally. * If we have traversed up to the last uploaded commit, we've traversed all * needed commits. */ if (!priv->visited_last_uploaded) { seaf_warning ("Not all commit objects need to be uploaded exist locally.\n"); priv->compute_success = FALSE; return vdata; } priv->compute_success = TRUE; return vdata; } static void compute_upload_commits_done (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; if (!priv->compute_success) { ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, NULL, 0); ccnet_processor_done (processor, FALSE); return; } send_one_commit (processor); } static void send_commits (CcnetProcessor *processor, const char *head) { SeafileSendcommitV3NewProc *proc = (SeafileSendcommitV3NewProc *)processor; USE_PRIV; char *last_uploaded; last_uploaded = seaf_repo_manager_get_repo_property (seaf->repo_mgr, proc->tx_task->repo_id, REPO_LOCAL_HEAD); if (!last_uploaded || strlen(last_uploaded) != 40) { seaf_warning ("Last uploaded commit id is not found in db or invalid.\n"); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } memcpy (priv->last_uploaded_id, last_uploaded, 40); g_free (last_uploaded); ccnet_processor_thread_create (processor, seaf->job_mgr, compute_upload_commits_thread, compute_upload_commits_done, processor); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendcommitV3NewProc *proc = (SeafileSendcommitV3NewProc *)processor; TransferTask *task = proc->tx_task; if (task->state != TASK_STATE_NORMAL) { ccnet_processor_done (processor, TRUE); return; } switch (processor->state) { case INIT: if (memcmp (code, SC_OK, 3) == 0) { processor->state = SEND_OBJECT; send_commits (processor, task->head); return; } break; case SEND_OBJECT: if (memcmp (code, SC_ACK, 3) == 0) { send_one_commit (processor); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sendcommit-v3-new-proc.h000066400000000000000000000026671323477647300232240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDCOMMIT_V3_NEW_PROC_H #define SEAFILE_SENDCOMMIT_V3_NEW_PROC_H #include #define SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC (seafile_sendcommit_v3_new_proc_get_type ()) #define SEAFILE_SENDCOMMIT_V3_NEW_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC, SeafileSendcommitV3NewProc)) #define SEAFILE_IS_SENDCOMMIT_V3_NEW_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC)) #define SEAFILE_SENDCOMMIT_V3_NEW_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC, SeafileSendcommitV3NewProcClass)) #define IS_SEAFILE_SENDCOMMIT_V3_NEW_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC)) #define SEAFILE_SENDCOMMIT_V3_NEW_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC, SeafileSendcommitV3NewProcClass)) typedef struct _SeafileSendcommitV3NewProc SeafileSendcommitV3NewProc; typedef struct _SeafileSendcommitV3NewProcClass SeafileSendcommitV3NewProcClass; struct _SeafileSendcommitV3NewProc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileSendcommitV3NewProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendcommit_v3_new_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendcommit-v3-proc.c000066400000000000000000000265701323477647300224270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include "net.h" #include "utils.h" #include "seafile-session.h" #include "sendcommit-v3-proc.h" #include "processors/objecttx-common.h" #include "vc-common.h" /* seafile-recvcommit-v3 INIT ---------------------> 200 OK INIT <--------------------- Object SEND_OBJ -----------------------> Ack or Bad Object <--------------------- ... End -----------------------> */ enum { INIT, SEND_OBJECT }; typedef struct { char remote_id[41]; GList *id_list; GHashTable *commit_hash; gboolean fast_forward; gboolean compute_success; } SeafileSendcommitProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_SENDCOMMIT_V3_PROC, SeafileSendcommitProcPriv)) #define USE_PRIV \ SeafileSendcommitProcPriv *priv = GET_PRIV(processor); static int send_commit_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileSendcommitV3Proc, seafile_sendcommit_v3_proc, CCNET_TYPE_PROCESSOR) static void release_resource (CcnetProcessor *processor) { USE_PRIV; if (priv->id_list != NULL) string_list_free (priv->id_list); if (priv->commit_hash) g_hash_table_destroy (priv->commit_hash); CCNET_PROCESSOR_CLASS (seafile_sendcommit_v3_proc_parent_class)->release_resource (processor); } static void seafile_sendcommit_v3_proc_class_init (SeafileSendcommitV3ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "sendcommit-v3-proc"; proc_class->start = send_commit_start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof (SeafileSendcommitProcPriv)); } static void seafile_sendcommit_v3_proc_init (SeafileSendcommitV3Proc *processor) { } static int send_commit_start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; memcpy (priv->remote_id, task->remote_head, 41); /* fs_roots can be non-NULL if transfer is resumed from NET_DOWN. */ if (task->fs_roots != NULL) object_list_free (task->fs_roots); task->fs_roots = object_list_new (); if (task->commits != NULL) object_list_free (task->commits); task->commits = object_list_new (); buf = g_string_new (NULL); g_string_printf (buf, "remote %s seafile-recvcommit-v3 %s %s", processor->peer_id, task->to_branch, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } static void send_commit (CcnetProcessor *processor, const char *object_id) { TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; char *data; int len; ObjectPack *pack = NULL; int pack_size; if (seaf_obj_store_read_obj (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, object_id, (void**)&data, &len) < 0) { seaf_warning ("Failed to read commit %s.\n", object_id); goto fail; } pack_size = sizeof(ObjectPack) + len; pack = malloc (pack_size); memcpy (pack->id, object_id, 41); memcpy (pack->object, data, len); ccnet_processor_send_update (processor, SC_OBJECT, SS_OBJECT, (char *)pack, pack_size); seaf_debug ("Send commit %.8s.\n", object_id); g_free (data); free (pack); return; fail: ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, object_id, 41); ccnet_processor_done (processor, FALSE); } static void send_one_commit (CcnetProcessor *processor) { USE_PRIV; char *commit_id; if (!priv->id_list) { ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } commit_id = priv->id_list->data; priv->id_list = g_list_delete_link (priv->id_list, priv->id_list); send_commit (processor, commit_id); g_free (commit_id); } /* Traverse the commit graph until remote_id is met or a merged commit * (commit with two parents) is met. * * If a merged commit is met before remote_id, that implies that * we did a real merge when merged with the branch headed by remote_id. * In this case we'll need more computation to find out the "delta" commits * between these two branches. Otherwise, if the merge was a fast-forward * one, it's enough to just send all the commits between our head commit * and remote_id. */ static gboolean traverse_commit_fast_forward (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; if (priv->remote_id[0] != 0 && strcmp (priv->remote_id, commit->commit_id) == 0) { *stop = TRUE; return TRUE; } if (commit->second_parent_id != NULL) { *stop = TRUE; priv->fast_forward = FALSE; return TRUE; } priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); /* We don't need to send the contents under an empty dir. */ if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); return TRUE; } static gboolean traverse_commit_remote (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; USE_PRIV; char *key; if (g_hash_table_lookup (priv->commit_hash, commit->commit_id)) return TRUE; key = g_strdup(commit->commit_id); g_hash_table_replace (priv->commit_hash, key, key); return TRUE; } static gboolean compute_delta (SeafCommit *commit, void *data, gboolean *stop) { CcnetProcessor *processor = data; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; if (!g_hash_table_lookup (priv->commit_hash, commit->commit_id)) { priv->id_list = g_list_prepend (priv->id_list, g_strdup(commit->commit_id)); if (strcmp (commit->root_id, EMPTY_SHA1) != 0) object_list_insert (task->fs_roots, commit->root_id); object_list_insert (task->commits, commit->commit_id); } else { /* Stop traversing down from this commit if it already exists * in the remote branch. */ *stop = TRUE; } return TRUE; } static int compute_delta_commits (CcnetProcessor *processor, const char *head) { gboolean ret; TransferTask *task = ((SeafileSendcommitV3Proc *)processor)->tx_task; USE_PRIV; string_list_free (priv->id_list); priv->id_list = NULL; object_list_free (task->fs_roots); task->fs_roots = object_list_new (); object_list_free (task->commits); task->commits = object_list_new (); priv->commit_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, task->repo_id, task->repo_version, priv->remote_id, traverse_commit_remote, processor, FALSE); if (!ret) { return -1; } ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, task->repo_id, task->repo_version, head, compute_delta, processor, FALSE); if (!ret) { return -1; } return 0; } static void * compute_upload_commits_thread (void *vdata) { CcnetProcessor *processor = vdata; SeafileSendcommitV3Proc *proc = (SeafileSendcommitV3Proc *)processor; TransferTask *task = proc->tx_task; USE_PRIV; gboolean ret; priv->fast_forward = TRUE; ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, task->repo_id, task->repo_version, task->head, traverse_commit_fast_forward, processor, FALSE); if (!ret) { priv->compute_success = FALSE; return vdata; } if (priv->fast_forward) { priv->compute_success = TRUE; seaf_debug ("[sendcommt] Send commit after a fast forward merge.\n"); return vdata; } seaf_debug ("[sendcommit] Send commit after a real merge.\n"); if (compute_delta_commits (processor, task->head) < 0) { priv->compute_success = FALSE; return vdata; } priv->compute_success = TRUE; return vdata; } static void compute_upload_commits_done (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; if (!priv->compute_success) { ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, NULL, 0); ccnet_processor_done (processor, FALSE); return; } send_one_commit (processor); } static void send_commits (CcnetProcessor *processor, const char *head) { ccnet_processor_thread_create (processor, seaf->job_mgr, compute_upload_commits_thread, compute_upload_commits_done, processor); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendcommitV3Proc *proc = (SeafileSendcommitV3Proc *)processor; TransferTask *task = proc->tx_task; if (task->state != TASK_STATE_NORMAL) { ccnet_processor_done (processor, TRUE); return; } switch (processor->state) { case INIT: if (memcmp (code, SC_OK, 3) == 0) { processor->state = SEND_OBJECT; send_commits (processor, task->head); return; } break; case SEND_OBJECT: if (memcmp (code, SC_ACK, 3) == 0) { send_one_commit (processor); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sendcommit-v3-proc.h000066400000000000000000000025401323477647300224230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDCOMMIT_V3_PROC_H #define SEAFILE_SENDCOMMIT_V3_PROC_H #include #define SEAFILE_TYPE_SENDCOMMIT_V3_PROC (seafile_sendcommit_v3_proc_get_type ()) #define SEAFILE_SENDCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_PROC, SeafileSendcommitV3Proc)) #define SEAFILE_IS_SENDCOMMIT_V3_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_PROC)) #define SEAFILE_SENDCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDCOMMIT_V3_PROC, SeafileSendcommitV3ProcClass)) #define IS_SEAFILE_SENDCOMMIT_V3_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDCOMMIT_V3_PROC)) #define SEAFILE_SENDCOMMIT_V3_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDCOMMIT_V3_PROC, SeafileSendcommitV3ProcClass)) typedef struct _SeafileSendcommitV3Proc SeafileSendcommitV3Proc; typedef struct _SeafileSendcommitV3ProcClass SeafileSendcommitV3ProcClass; struct _SeafileSendcommitV3Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileSendcommitV3ProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendcommit_v3_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendcommit-v4-proc.c000066400000000000000000000072031323477647300224200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include "net.h" #include "utils.h" #include "seafile-session.h" #include "sendcommit-v4-proc.h" #include "processors/objecttx-common.h" #include "vc-common.h" enum { INIT, SEND_OBJECT }; static int send_commit_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); G_DEFINE_TYPE (SeafileSendcommitV4Proc, seafile_sendcommit_v4_proc, CCNET_TYPE_PROCESSOR) static void seafile_sendcommit_v4_proc_class_init (SeafileSendcommitV4ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "sendcommit-v4-proc"; proc_class->start = send_commit_start; proc_class->handle_response = handle_response; } static void seafile_sendcommit_v4_proc_init (SeafileSendcommitV4Proc *processor) { } static int send_commit_start (CcnetProcessor *processor, int argc, char **argv) { TransferTask *task = ((SeafileSendcommitV4Proc *)processor)->tx_task; GString *buf; buf = g_string_new (NULL); g_string_printf (buf, "remote %s seafile-recvcommit-v3 master %s", processor->peer_id, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); return 0; } static void send_commit (CcnetProcessor *processor, const char *object_id) { TransferTask *task = ((SeafileSendcommitV4Proc *)processor)->tx_task; char *data; int len; ObjectPack *pack = NULL; int pack_size; if (seaf_obj_store_read_obj (seaf->commit_mgr->obj_store, task->repo_id, task->repo_version, object_id, (void**)&data, &len) < 0) { seaf_warning ("Failed to read commit %s.\n", object_id); goto fail; } pack_size = sizeof(ObjectPack) + len; pack = malloc (pack_size); memcpy (pack->id, object_id, 41); memcpy (pack->object, data, len); ccnet_processor_send_update (processor, SC_OBJECT, SS_OBJECT, (char *)pack, pack_size); seaf_debug ("Send commit %.8s.\n", object_id); g_free (data); free (pack); return; fail: ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, object_id, 41); ccnet_processor_done (processor, FALSE); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendcommitV4Proc *proc = (SeafileSendcommitV4Proc *)processor; TransferTask *task = proc->tx_task; if (task->state != TASK_STATE_NORMAL) { ccnet_processor_done (processor, TRUE); return; } switch (processor->state) { case INIT: if (memcmp (code, SC_OK, 3) == 0) { processor->state = SEND_OBJECT; send_commit (processor, task->head); return; } break; case SEND_OBJECT: if (memcmp (code, SC_ACK, 3) == 0) { ccnet_processor_done (processor, TRUE); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sendcommit-v4-proc.h000066400000000000000000000025401323477647300224240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDCOMMIT_V4_PROC_H #define SEAFILE_SENDCOMMIT_V4_PROC_H #include #define SEAFILE_TYPE_SENDCOMMIT_V4_PROC (seafile_sendcommit_v4_proc_get_type ()) #define SEAFILE_SENDCOMMIT_V4_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDCOMMIT_V4_PROC, SeafileSendcommitV4Proc)) #define SEAFILE_IS_SENDCOMMIT_V4_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDCOMMIT_V4_PROC)) #define SEAFILE_SENDCOMMIT_V4_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDCOMMIT_V4_PROC, SeafileSendcommitV4ProcClass)) #define IS_SEAFILE_SENDCOMMIT_V4_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDCOMMIT_V4_PROC)) #define SEAFILE_SENDCOMMIT_V4_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDCOMMIT_V4_PROC, SeafileSendcommitV4ProcClass)) typedef struct _SeafileSendcommitV4Proc SeafileSendcommitV4Proc; typedef struct _SeafileSendcommitV4ProcClass SeafileSendcommitV4ProcClass; struct _SeafileSendcommitV4Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileSendcommitV4ProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendcommit_v4_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendfs-proc.c000066400000000000000000000177411323477647300212210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * file system synchronization algorithm: * * Begins with the root directory object, * * seafile-recvfs * S(INIT -> SEND_ROOT) ---------------------------------> T * OK * S(SEND_ROOT) <--------------------------- T * FS_ROOT * S(SEND_ROOT) ----------------------------> T * OK * S(SEND_ROOT) <---------------------------- T * FS Root, FS Root End * S(SEND_ROOT -> SEND_OBJECT) ----------------------------> T * * Get Object * S(SEND_OBJECT) <---------------------------- T * Object * S(SEND_OBJECT) ----------------------------> T * . * . * . * END * S(SEND_OBJECT) <--------------------------- T */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include #include "utils.h" #include "seafile-session.h" #include "commit-mgr.h" #include "fs-mgr.h" #include "processors/objecttx-common.h" #include "sendfs-proc.h" enum { INIT, SEND_ROOT, SEND_OBJECT }; typedef struct { guint32 reader_id; } SeafileSendfsProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_SENDFS_PROC, SeafileSendfsProcPriv)) #define USE_PRIV \ SeafileSendfsProcPriv *priv = GET_PRIV(processor); G_DEFINE_TYPE (SeafileSendfsProc, seafile_sendfs_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { USE_PRIV; seaf_obj_store_unregister_async_read (seaf->fs_mgr->obj_store, priv->reader_id); CCNET_PROCESSOR_CLASS (seafile_sendfs_proc_parent_class)->release_resource (processor); } static void seafile_sendfs_proc_class_init (SeafileSendfsProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "sendfs-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof(SeafileSendfsProcPriv)); } static void seafile_sendfs_proc_init (SeafileSendfsProc *processor) { } static void fs_object_read_cb (OSAsyncResult *res, void *data); static int start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf; SeafileSendfsProc *proc = (SeafileSendfsProc *)processor; TransferTask *task = proc->tx_task; buf = g_string_new (NULL); g_string_printf (buf, "remote %s seafile-recvfs %s", processor->peer_id, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); processor->state = SEND_ROOT; proc->last_idx = 0; priv->reader_id = seaf_obj_store_register_async_read (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, fs_object_read_cb, processor); return 0; } static void send_fs_object (CcnetProcessor *processor, const char *object_id, char *data, int len) { ObjectPack *pack = NULL; int pack_size; pack_size = sizeof(ObjectPack) + len; pack = malloc (pack_size); memcpy (pack->id, object_id, 41); memcpy (pack->object, data, len); if (pack_size <= MAX_OBJ_SEG_SIZE) { ccnet_processor_send_update (processor, SC_OBJECT, SS_OBJECT, (char *)pack, pack_size); } else { int offset, n; offset = 0; while (offset < pack_size) { n = MIN(pack_size - offset, MAX_OBJ_SEG_SIZE); if (offset + n < pack_size) { ccnet_processor_send_update (processor, SC_OBJ_SEG, SS_OBJ_SEG, (char *)pack + offset, n); } else { ccnet_processor_send_update (processor, SC_OBJ_SEG_END, SS_OBJ_SEG_END, (char *)pack + offset, n); } seaf_debug ("Sent object %s segment\n", object_id, pack_size, offset, n); offset += n; } } seaf_debug ("Send fs object %.8s.\n", object_id); free (pack); } static void fs_object_read_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; if (!res->success) { seaf_warning ("Failed to read fs object %.8s.\n", res->obj_id); ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, res->obj_id, 41); ccnet_processor_done (processor, FALSE); return; } send_fs_object (processor, res->obj_id, res->data, res->len); } static void read_fs_object (CcnetProcessor *processor, const char *obj_id) { USE_PRIV; seaf_obj_store_async_read (seaf->fs_mgr->obj_store, priv->reader_id, obj_id); } static void send_fs_objects (CcnetProcessor *processor, char *content, int clen) { char *object_id; int n_objects; int i; if (clen % 41 != 1 || content[clen-1] != '\0') { seaf_warning ("Bad fs object list.\n"); ccnet_processor_send_update (processor, SC_BAD_OL, SS_BAD_OL, NULL, 0); ccnet_processor_done (processor, FALSE); return; } n_objects = clen/41; object_id = content; for (i = 0; i < n_objects; ++i) { object_id[40] = '\0'; read_fs_object (processor, object_id); object_id += 41; } } static void send_fs_roots (CcnetProcessor *processor) { SeafileSendfsProc *proc = (SeafileSendfsProc *)processor; char buf[2096]; char *ptr = buf; int i, count = 0; ObjectList *ol = proc->tx_task->fs_roots; int ollen = object_list_length (ol); if (proc->last_idx == ollen) { ccnet_processor_send_update (processor, SC_ROOT_END, SS_ROOT_END, NULL, 0); processor->state = SEND_OBJECT; return; } for (i = proc->last_idx; i < ollen; i++) { memcpy (ptr, g_ptr_array_index(ol->obj_ids, i), 40); ptr += 40; *ptr++ = '\n'; if (++count == 48) break; } ccnet_processor_send_update (processor, SC_ROOT, SS_ROOT, buf, 41 * count); proc->last_idx = i; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendfsProc *proc = (SeafileSendfsProc *)processor; TransferTask *task = proc->tx_task; switch (processor->state) { case SEND_ROOT: if (strncmp(code, SC_OK, 3) == 0) { send_fs_roots (processor); return; } break; case SEND_OBJECT: if (strncmp(code, SC_GET_OBJECT, 3) == 0) { send_fs_objects (processor, content, clen); return; } else if (strncmp(code, SC_END, 3) == 0) { seaf_debug ("Send fs objects end.\n"); ccnet_processor_done (processor, TRUE); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sendfs-proc.h000066400000000000000000000024731323477647300212220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDFS_PROC_H #define SEAFILE_SENDFS_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_SENDFS_PROC (seafile_sendfs_proc_get_type ()) #define SEAFILE_SENDFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDFS_PROC, SeafileSendfsProc)) #define SEAFILE_IS_SENDFS_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDFS_PROC)) #define SEAFILE_SENDFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDFS_PROC, SeafileSendfsProcClass)) #define IS_SEAFILE_SENDFS_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDFS_PROC)) #define SEAFILE_SENDFS_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDFS_PROC, SeafileSendfsProcClass)) typedef struct _SeafileSendfsProc SeafileSendfsProc; typedef struct _SeafileSendfsProcClass SeafileSendfsProcClass; struct _SeafileSendfsProc { CcnetProcessor parent_instance; TransferTask *tx_task; int last_idx; /* used in send root fs to peer */ }; struct _SeafileSendfsProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendfs_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sendfs-v2-proc.c000066400000000000000000000343231323477647300215410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include #include "utils.h" #include "seafile-session.h" #include "commit-mgr.h" #include "fs-mgr.h" #include "processors/objecttx-common.h" #include "sendfs-v2-proc.h" #include "diff-simple.h" /* * recvfs-v2-proc * ------------------------------> * * OK * <----------------------------- * * Calculate send object list * * SC_OBJ_LIST_SEG * -----------------------------> * SC_OBJ_LIST_SEG * <---------------------------- * ...... * SC_OBJ_LIST_SEG_END * -----------------------------> * * SC_OBJ * -----------------------------> * ...... * After all objects are saved to disk, the server ends the protocol. * SC_END * <---------------------------- */ enum { INIT = 0, CHECK_OBJECT_LIST, SEND_OBJECTS, }; typedef struct { GList *send_obj_list; GList *recv_obj_list; guint32 reader_id; gboolean calc_success; } SeafileSendfsProcPriv; #define GET_PRIV(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAFILE_TYPE_SENDFS_V2_PROC, SeafileSendfsProcPriv)) #define USE_PRIV \ SeafileSendfsProcPriv *priv = GET_PRIV(processor); G_DEFINE_TYPE (SeafileSendfsV2Proc, seafile_sendfs_v2_proc, CCNET_TYPE_PROCESSOR) static int start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void release_resource(CcnetProcessor *processor) { USE_PRIV; string_list_free (priv->send_obj_list); string_list_free (priv->recv_obj_list); seaf_obj_store_unregister_async_read (seaf->fs_mgr->obj_store, priv->reader_id); CCNET_PROCESSOR_CLASS (seafile_sendfs_v2_proc_parent_class)->release_resource (processor); } static void seafile_sendfs_v2_proc_class_init (SeafileSendfsV2ProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "sendfs-v2-proc"; proc_class->start = start; proc_class->handle_response = handle_response; proc_class->release_resource = release_resource; g_type_class_add_private (klass, sizeof(SeafileSendfsProcPriv)); } static void seafile_sendfs_v2_proc_init (SeafileSendfsV2Proc *processor) { } static void fs_object_read_cb (OSAsyncResult *res, void *data); static int start (CcnetProcessor *processor, int argc, char **argv) { USE_PRIV; GString *buf; SeafileSendfsV2Proc *proc = (SeafileSendfsV2Proc *)processor; TransferTask *task = proc->tx_task; buf = g_string_new (NULL); g_string_printf (buf, "remote %s seafile-recvfs-v2 %s", processor->peer_id, task->session_token); ccnet_processor_send_request (processor, buf->str); g_string_free (buf, TRUE); priv->reader_id = seaf_obj_store_register_async_read (seaf->fs_mgr->obj_store, task->repo_id, task->repo_version, fs_object_read_cb, processor); return 0; } /* Calculate send object list */ typedef struct { GList **pret; GHashTable *checked_objs; } CalcData; inline static gboolean dirent_same (SeafDirent *denta, SeafDirent *dentb) { return (strcmp (dentb->id, denta->id) == 0 && denta->mode == dentb->mode); } static int collect_file_ids (int n, const char *basedir, SeafDirent *files[], void *vdata) { SeafDirent *file1 = files[0]; SeafDirent *file2 = files[1]; CalcData *data = vdata; GList **pret = data->pret; int dummy; if (!file1 || strcmp (file1->id, EMPTY_SHA1) == 0) return 0; if (g_hash_table_lookup (data->checked_objs, file1->id)) return 0; if (!file2 || !dirent_same (file1, file2)) { *pret = g_list_prepend (*pret, g_strdup(file1->id)); g_hash_table_insert (data->checked_objs, g_strdup(file1->id), &dummy); } return 0; } static int collect_dir_ids (int n, const char *basedir, SeafDirent *dirs[], void *vdata, gboolean *recurse) { SeafDirent *dir1 = dirs[0]; SeafDirent *dir2 = dirs[1]; CalcData *data = vdata; GList **pret = data->pret; int dummy; if (!dir1 || strcmp (dir1->id, EMPTY_SHA1) == 0) return 0; if (g_hash_table_lookup (data->checked_objs, dir1->id)) return 0; if (!dir2 || !dirent_same (dir1, dir2)) { *pret = g_list_prepend (*pret, g_strdup(dir1->id)); g_hash_table_insert (data->checked_objs, g_strdup(dir1->id), &dummy); } return 0; } static void * calculate_send_object_list (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; SeafileSendfsV2Proc *proc = (SeafileSendfsV2Proc *)processor; TransferTask *task = proc->tx_task; SeafBranch *local = NULL, *master = NULL; SeafCommit *local_head = NULL, *master_head = NULL; local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Branch local not found for repo %.8s.\n", task->repo_id); priv->calc_success = FALSE; goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); priv->calc_success = FALSE; goto out; } local_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, local->commit_id); if (!local_head) { seaf_warning ("Local head commit not found for repo %.8s.\n", task->repo_id); priv->calc_success = FALSE; goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, master->commit_id); if (!master_head) { seaf_warning ("Master head commit not found for repo %.8s.\n", task->repo_id); priv->calc_success = FALSE; goto out; } /* Diff won't traverse the root object itself. */ if (strcmp (local_head->root_id, master_head->root_id) != 0 && strcmp (local_head->root_id, EMPTY_SHA1) != 0) priv->send_obj_list = g_list_prepend (priv->send_obj_list, g_strdup(local_head->root_id)); CalcData *data = g_new0(CalcData, 1); data->pret = &priv->send_obj_list; data->checked_objs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); DiffOptions opts; memset (&opts, 0, sizeof(opts)); memcpy (opts.store_id, task->repo_id, 36); opts.version = task->repo_version; opts.file_cb = collect_file_ids; opts.dir_cb = collect_dir_ids; opts.data = data; const char *trees[2]; trees[0] = local_head->root_id; trees[1] = master_head->root_id; if (diff_trees (2, trees, &opts) < 0) { seaf_warning ("Failed to diff local and master head for repo %.8s.\n", task->repo_id); priv->calc_success = FALSE; } g_hash_table_destroy (data->checked_objs); g_free (data); priv->calc_success = TRUE; out: seaf_branch_unref (local); seaf_branch_unref (master); seaf_commit_unref (local_head); seaf_commit_unref (master_head); return vdata; } static void send_object_list_segment (CcnetProcessor *processor); static void calculate_send_object_list_done (void *vdata) { CcnetProcessor *processor = vdata; USE_PRIV; if (!priv->calc_success) { ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } if (priv->send_obj_list == NULL) { seaf_message ("No fs objects to upload. Done.\n"); ccnet_processor_send_update (processor, SC_END, SS_END, NULL, 0); ccnet_processor_done (processor, TRUE); return; } send_object_list_segment (processor); } /* Check object list. */ #define OBJECT_LIST_SEGMENT_N 1000 #define OBJECT_LIST_SEGMENT_LEN 40 * 1000 static void send_next_object (CcnetProcessor *processor); static void send_object_list_segment (CcnetProcessor *processor) { USE_PRIV; char buf[OBJECT_LIST_SEGMENT_LEN]; if (priv->send_obj_list == NULL) { seaf_debug ("Check object list end.\n"); ccnet_processor_send_update (processor, SC_OBJ_LIST_SEG_END, SS_OBJ_LIST_SEG_END, NULL, 0); send_next_object (processor); processor->state = SEND_OBJECTS; return; } int i = 0; char *p = buf; char *obj_id; while (priv->send_obj_list != NULL) { obj_id = priv->send_obj_list->data; priv->send_obj_list = g_list_delete_link (priv->send_obj_list, priv->send_obj_list); memcpy (p, obj_id, 40); p += 40; g_free (obj_id); if (++i == OBJECT_LIST_SEGMENT_N) break; } if (i > 0) { seaf_debug ("Send %d object ids.\n", i); ccnet_processor_send_update (processor, SC_OBJ_LIST_SEG, SS_OBJ_LIST_SEG, buf, i * 40); } } static void process_object_list_segment (CcnetProcessor *processor, char *content, int clen) { USE_PRIV; int n, i; char *p; if (clen % 40 != 0) { seaf_warning ("Invalid object list segment length %d.\n", clen); ccnet_processor_send_update (processor, SC_SHUTDOWN, SS_SHUTDOWN, NULL, 0); ccnet_processor_done (processor, FALSE); return; } n = clen/40; p = content; seaf_debug ("%d objects are needed by the server.\n", n); for (i = 0; i < n; ++i) { priv->recv_obj_list = g_list_prepend (priv->recv_obj_list, g_strndup (p, 40)); p += 40; } } /* Send objects */ static void send_fs_object (CcnetProcessor *processor, const char *object_id, char *data, int len) { ObjectPack *pack = NULL; int pack_size; pack_size = sizeof(ObjectPack) + len; pack = malloc (pack_size); memcpy (pack->id, object_id, 41); memcpy (pack->object, data, len); if (pack_size <= MAX_OBJ_SEG_SIZE) { ccnet_processor_send_update (processor, SC_OBJECT, SS_OBJECT, (char *)pack, pack_size); } else { int offset, n; offset = 0; while (offset < pack_size) { n = MIN(pack_size - offset, MAX_OBJ_SEG_SIZE); if (offset + n < pack_size) { ccnet_processor_send_update (processor, SC_OBJ_SEG, SS_OBJ_SEG, (char *)pack + offset, n); } else { ccnet_processor_send_update (processor, SC_OBJ_SEG_END, SS_OBJ_SEG_END, (char *)pack + offset, n); } seaf_debug ("Sent object %s segment\n", object_id, pack_size, offset, n); offset += n; } } seaf_debug ("Send fs object %.8s.\n", object_id); free (pack); } static void fs_object_read_cb (OSAsyncResult *res, void *data) { CcnetProcessor *processor = data; if (!res->success) { seaf_warning ("Failed to read fs object %.8s.\n", res->obj_id); ccnet_processor_send_update (processor, SC_NOT_FOUND, SS_NOT_FOUND, res->obj_id, 41); ccnet_processor_done (processor, FALSE); return; } send_fs_object (processor, res->obj_id, res->data, res->len); send_next_object (processor); } static void read_fs_object (CcnetProcessor *processor, const char *obj_id) { USE_PRIV; seaf_obj_store_async_read (seaf->fs_mgr->obj_store, priv->reader_id, obj_id); } static void send_next_object (CcnetProcessor *processor) { USE_PRIV; char *object_id; if (priv->recv_obj_list == NULL) { seaf_debug ("Send fs objects end.\n"); return; } object_id = priv->recv_obj_list->data; priv->recv_obj_list = g_list_delete_link (priv->recv_obj_list, priv->recv_obj_list); read_fs_object (processor, object_id); g_free (object_id); } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSendfsV2Proc *proc = (SeafileSendfsV2Proc *)processor; TransferTask *task = proc->tx_task; switch (processor->state) { case INIT: if (strncmp(code, SC_OK, 3) == 0) { ccnet_processor_thread_create (processor, seaf->job_mgr, calculate_send_object_list, calculate_send_object_list_done, processor); processor->state = CHECK_OBJECT_LIST; return; } break; case CHECK_OBJECT_LIST: if (strncmp (code, SC_OBJ_LIST_SEG, 3) == 0) { process_object_list_segment (processor, content, clen); send_object_list_segment (processor); return; } break; case SEND_OBJECTS: if (strncmp (code, SC_END, 3) == 0) { seaf_debug ("All objects received. Done.\n"); ccnet_processor_done (processor, TRUE); return; } break; default: g_return_if_reached (); } seaf_warning ("Bad response: %s %s.\n", code, code_msg); if (memcmp (code, SC_ACCESS_DENIED, 3) == 0) transfer_task_set_error (task, TASK_ERR_ACCESS_DENIED); ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sendfs-v2-proc.h000066400000000000000000000024671323477647300215520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SENDFS_V2_PROC_H #define SEAFILE_SENDFS_V2_PROC_H #include #include #include "transfer-mgr.h" #define SEAFILE_TYPE_SENDFS_V2_PROC (seafile_sendfs_v2_proc_get_type ()) #define SEAFILE_SENDFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SENDFS_V2_PROC, SeafileSendfsV2Proc)) #define SEAFILE_IS_SENDFS_V2_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SENDFS_V2_PROC)) #define SEAFILE_SENDFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SENDFS_V2_PROC, SeafileSendfsV2ProcClass)) #define IS_SEAFILE_SENDFS_V2_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SENDFS_V2_PROC)) #define SEAFILE_SENDFS_V2_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SENDFS_V2_PROC, SeafileSendfsV2ProcClass)) typedef struct _SeafileSendfsV2Proc SeafileSendfsV2Proc; typedef struct _SeafileSendfsV2ProcClass SeafileSendfsV2ProcClass; struct _SeafileSendfsV2Proc { CcnetProcessor parent_instance; TransferTask *tx_task; }; struct _SeafileSendfsV2ProcClass { CcnetProcessorClass parent_class; }; GType seafile_sendfs_v2_proc_get_type (); #endif seafile-6.1.5/daemon/processors/sync-repo-proc.c000066400000000000000000000072341323477647300216520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "seafile-session.h" #include "repo-mgr.h" #include "sync-mgr.h" #include "utils.h" #include "sync-repo-proc.h" #include "sync-repo-common.h" #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" /* client relay sync-repo-slave ----------------------------------> 300 <---------------------------------- or 301 No such repo <---------------------------------- 302 No such branch <---------------------------------- */ G_DEFINE_TYPE (SeafileSyncRepoProc, seafile_sync_repo_proc, CCNET_TYPE_PROCESSOR) static int sync_repo_start (CcnetProcessor *processor, int argc, char **argv); static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen); static void seafile_sync_repo_proc_class_init (SeafileSyncRepoProcClass *klass) { CcnetProcessorClass *proc_class = CCNET_PROCESSOR_CLASS (klass); proc_class->name = "seafile-sync-repo"; proc_class->start = sync_repo_start; proc_class->handle_response = handle_response; } static void seafile_sync_repo_proc_init (SeafileSyncRepoProc *processor) { } static int sync_repo_start (CcnetProcessor *processor, int argc, char **argv) { SeafileSyncRepoProc *proc = (SeafileSyncRepoProc *) processor; if (argc != 0) { seaf_warning ("[sync-repo] argc should be 0.\n"); ccnet_processor_done (processor, FALSE); return 0; } if (!proc->task) { seaf_warning ("[sync-repo] Error: not provide info task.\n"); ccnet_processor_done (processor, FALSE); return 0; } char buf[256]; /* Use a virutal "fetch_head" branch that works both on client and server. */ snprintf (buf, 256, "remote %s seafile-sync-repo-slave %s %s", processor->peer_id, proc->task->info->repo_id, "fetch_head"); ccnet_processor_send_request (processor, buf); return 0; } static void handle_response (CcnetProcessor *processor, char *code, char *code_msg, char *content, int clen) { SeafileSyncRepoProc *proc = (SeafileSyncRepoProc *)processor; proc->task->info->deleted_on_relay = FALSE; proc->task->info->branch_deleted_on_relay = FALSE; proc->task->info->repo_corrupted = FALSE; if (memcmp (code, SC_COMMIT_ID, 3) == 0) { if (content[clen-1] != '\0') { seaf_warning ("[sync-repo] Response not end with NULL\n"); ccnet_processor_done (processor, FALSE); return; } /* g_debug ("[sync-repo] Get repo head commit %s\n", content); */ if (strlen(content) != 40) { seaf_debug ("[sync-repo] Invalid commit id\n"); ccnet_processor_done (processor, FALSE); return; } memcpy(proc->task->info->head_commit, content, 41); ccnet_processor_done (processor, TRUE); } else if (memcmp (code, SC_NO_REPO, 3) == 0) { proc->task->info->deleted_on_relay = TRUE; ccnet_processor_done (processor, TRUE); } else if (memcmp (code, SC_NO_BRANCH, 3) == 0) { proc->task->info->branch_deleted_on_relay = TRUE; ccnet_processor_done (processor, TRUE); } else if (memcmp (code, SC_REPO_CORRUPT, 3) == 0) { proc->task->info->repo_corrupted = TRUE; ccnet_processor_done (processor, TRUE); } else ccnet_processor_done (processor, FALSE); } seafile-6.1.5/daemon/processors/sync-repo-proc.h000066400000000000000000000026351323477647300216570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SYNC_REPO_PROC_H #define SEAFILE_SYNC_REPO_PROC_H #include #include #define SEAFILE_TYPE_SYNC_REPO_PROC (seafile_sync_repo_proc_get_type ()) #define SEAFILE_SYNC_REPO_PROC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SYNC_REPO_PROC, SeafileSyncRepoProc)) #define SEAFILE_IS_SYNC_REPO_PROC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SYNC_REPO_PROC)) #define SEAFILE_SYNC_REPO_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SYNC_REPO_PROC, SeafileSyncRepoProcClass)) #define IS_SEAFILE_SYNC_REPO_PROC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SYNC_REPO_PROC)) #define SEAFILE_SYNC_REPO_PROC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SYNC_REPO_PROC, SeafileSyncRepoProcClass)) typedef struct _SeafileSyncRepoProc SeafileSyncRepoProc; typedef struct _SeafileSyncRepoProcClass SeafileSyncRepoProcClass; struct _SyncTask; struct _SeafileSyncRepoProc { CcnetProcessor parent_instance; struct _SyncTask *task; }; struct _SeafileSyncRepoProcClass { CcnetProcessorClass parent_class; }; GType seafile_sync_repo_proc_get_type (); void seafile_sync_repo_proc_set_repo (SeafileSyncRepoProc *processor, char *repo_id); #endif seafile-6.1.5/daemon/repo-mgr.c000066400000000000000000007753061323477647300163340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #ifdef WIN32 #include #include #endif #include #include #include "utils.h" #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" #include "status.h" #include "vc-utils.h" #include "merge.h" #include "seafile-session.h" #include "seafile-config.h" #include "commit-mgr.h" #include "branch-mgr.h" #include "repo-mgr.h" #include "fs-mgr.h" #include "seafile-error.h" #include "seafile-crypt.h" #include "index/index.h" #include "index/cache-tree.h" #include "unpack-trees.h" #include "diff-simple.h" #include "change-set.h" #include "db.h" #include "seafile-object.h" #define INDEX_DIR "index" #define IGNORE_FILE "seafile-ignore.txt" #ifdef HAVE_KEYSTORAGE_GK #include "repokey/seafile-gnome-keyring.h" #endif // HAVE_KEYSTORAGE_GK #ifndef SEAFILE_CLIENT_VERSION #define SEAFILE_CLIENT_VERSION PACKAGE_VERSION #endif struct _SeafRepoManagerPriv { GHashTable *repo_hash; sqlite3 *db; pthread_mutex_t db_lock; GHashTable *checkout_tasks_hash; pthread_rwlock_t lock; GHashTable *user_perms; /* repo_id -> folder user perms */ GHashTable *group_perms; /* repo_id -> folder group perms */ pthread_mutex_t perm_lock; uint32_t cevent_id; /* Used to notify sync error */ GAsyncQueue *lock_office_job_queue; }; static const char *ignore_table[] = { /* tmp files under Linux */ "*~", /* Seafile's backup file */ "*.sbak", /* Emacs tmp files */ "#*#", /* windows image cache */ "Thumbs.db", /* For Mac */ ".DS_Store", NULL, }; #define CONFLICT_PATTERN " \\(SFConflict .+\\)" #define OFFICE_LOCK_PATTERN "~\\$(.+)$" static GPatternSpec** ignore_patterns; static GPatternSpec* office_temp_ignore_patterns[4]; static GRegex *conflict_pattern = NULL; static GRegex *office_lock_pattern = NULL; static SeafRepo * load_repo (SeafRepoManager *manager, const char *repo_id); static void load_repos (SeafRepoManager *manager, const char *seaf_dir); static void seaf_repo_manager_del_repo_property (SeafRepoManager *manager, const char *repo_id); static int save_branch_repo_map (SeafRepoManager *manager, SeafBranch *branch); static void save_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key, const char *value); static void locked_file_free (LockedFile *file) { if (!file) return; g_free (file->operation); g_free (file); } static gboolean load_locked_file (sqlite3_stmt *stmt, void *data) { GHashTable *ret = data; LockedFile *file; const char *path, *operation, *file_id; gint64 old_mtime; path = (const char *)sqlite3_column_text (stmt, 0); operation = (const char *)sqlite3_column_text (stmt, 1); old_mtime = sqlite3_column_int64 (stmt, 2); file_id = (const char *)sqlite3_column_text (stmt, 3); file = g_new0 (LockedFile, 1); file->operation = g_strdup(operation); file->old_mtime = old_mtime; if (file_id) memcpy (file->file_id, file_id, 40); g_hash_table_insert (ret, g_strdup(path), file); return TRUE; } LockedFileSet * seaf_repo_manager_get_locked_file_set (SeafRepoManager *mgr, const char *repo_id) { GHashTable *locked_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)locked_file_free); char sql[256]; sqlite3_snprintf (sizeof(sql), sql, "SELECT path, operation, old_mtime, file_id FROM LockedFiles " "WHERE repo_id = '%q'", repo_id); pthread_mutex_lock (&mgr->priv->db_lock); /* Ingore database error. We return an empty set on error. */ sqlite_foreach_selected_row (mgr->priv->db, sql, load_locked_file, locked_files); pthread_mutex_unlock (&mgr->priv->db_lock); LockedFileSet *ret = g_new0 (LockedFileSet, 1); ret->mgr = mgr; memcpy (ret->repo_id, repo_id, 36); ret->locked_files = locked_files; return ret; } void locked_file_set_free (LockedFileSet *fset) { if (!fset) return; g_hash_table_destroy (fset->locked_files); g_free (fset); } int locked_file_set_add_update (LockedFileSet *fset, const char *path, const char *operation, gint64 old_mtime, const char *file_id) { SeafRepoManager *mgr = fset->mgr; char *sql; sqlite3_stmt *stmt; LockedFile *file; gboolean exists; exists = (g_hash_table_lookup (fset->locked_files, path) != NULL); pthread_mutex_lock (&mgr->priv->db_lock); if (!exists) { seaf_debug ("New locked file record %.8s, %s, %s, %" G_GINT64_FORMAT".\n", fset->repo_id, path, operation, old_mtime); sql = "INSERT INTO LockedFiles VALUES (?, ?, ?, ?, ?, NULL)"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, fset->repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, path, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 3, operation, -1, SQLITE_TRANSIENT); sqlite3_bind_int64 (stmt, 4, old_mtime); sqlite3_bind_text (stmt, 5, file_id, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to insert locked file %s to db: %s.\n", path, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); file = g_new0 (LockedFile, 1); file->operation = g_strdup(operation); file->old_mtime = old_mtime; if (file_id) memcpy (file->file_id, file_id, 40); g_hash_table_insert (fset->locked_files, g_strdup(path), file); } else { seaf_debug ("Update locked file record %.8s, %s, %s.\n", fset->repo_id, path, operation); /* If a UPDATE record exists, don't update the old_mtime. * We need to keep the old mtime when the locked file was first detected. */ sql = "UPDATE LockedFiles SET operation = ?, file_id = ? " "WHERE repo_id = ? AND path = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, operation, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, file_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 3, fset->repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 4, path, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to update locked file %s to db: %s.\n", path, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); file = g_hash_table_lookup (fset->locked_files, path); g_free (file->operation); file->operation = g_strdup(operation); if (file_id) memcpy (file->file_id, file_id, 40); } pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } int locked_file_set_remove (LockedFileSet *fset, const char *path, gboolean db_only) { SeafRepoManager *mgr = fset->mgr; char *sql; sqlite3_stmt *stmt; if (g_hash_table_lookup (fset->locked_files, path) == NULL) return 0; seaf_debug ("Remove locked file record %.8s, %s.\n", fset->repo_id, path); pthread_mutex_lock (&mgr->priv->db_lock); sql = "DELETE FROM LockedFiles WHERE repo_id = ? AND path = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, fset->repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, path, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove locked file %s from db: %s.\n", path, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); g_hash_table_remove (fset->locked_files, path); return 0; } LockedFile * locked_file_set_lookup (LockedFileSet *fset, const char *path) { return (LockedFile *) g_hash_table_lookup (fset->locked_files, path); } /* Folder permissions. */ FolderPerm * folder_perm_new (const char *path, const char *permission) { FolderPerm *perm = g_new0 (FolderPerm, 1); perm->path = g_strdup(path); perm->permission = g_strdup(permission); return perm; } void folder_perm_free (FolderPerm *perm) { if (!perm) return; g_free (perm->path); g_free (perm->permission); g_free (perm); } static GList * folder_perm_list_copy (GList *perms) { GList *ret = NULL, *ptr; FolderPerm *perm, *new_perm; for (ptr = perms; ptr; ptr = ptr->next) { perm = ptr->data; new_perm = folder_perm_new (perm->path, perm->permission); ret = g_list_append (ret, new_perm); } return ret; } static gint comp_folder_perms (gconstpointer a, gconstpointer b) { const FolderPerm *perm_a = a, *perm_b = b; return (strcmp (perm_b->path, perm_a->path)); } int seaf_repo_manager_update_folder_perms (SeafRepoManager *mgr, const char *repo_id, FolderPermType type, GList *folder_perms) { char *sql; sqlite3_stmt *stmt; GList *ptr; FolderPerm *perm; g_return_val_if_fail ((type == FOLDER_PERM_TYPE_USER || type == FOLDER_PERM_TYPE_GROUP), -1); /* Update db. */ pthread_mutex_lock (&mgr->priv->db_lock); if (type == FOLDER_PERM_TYPE_USER) sql = "DELETE FROM FolderUserPerms WHERE repo_id = ?"; else sql = "DELETE FROM FolderGroupPerms WHERE repo_id = ?"; stmt = sqlite_query_prepare (mgr->priv->db, sql); sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to remove folder perms for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_finalize (stmt); if (!folder_perms) { pthread_mutex_unlock (&mgr->priv->db_lock); return 0; } if (type == FOLDER_PERM_TYPE_USER) sql = "INSERT INTO FolderUserPerms VALUES (?, ?, ?)"; else sql = "INSERT INTO FolderGroupPerms VALUES (?, ?, ?)"; stmt = sqlite_query_prepare (mgr->priv->db, sql); for (ptr = folder_perms; ptr; ptr = ptr->next) { perm = ptr->data; sqlite3_bind_text (stmt, 1, repo_id, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 2, perm->path, -1, SQLITE_TRANSIENT); sqlite3_bind_text (stmt, 3, perm->permission, -1, SQLITE_TRANSIENT); if (sqlite3_step (stmt) != SQLITE_DONE) { seaf_warning ("Failed to insert folder perms for %.8s: %s.\n", repo_id, sqlite3_errmsg (mgr->priv->db)); sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } sqlite3_reset (stmt); sqlite3_clear_bindings (stmt); } sqlite3_finalize (stmt); pthread_mutex_unlock (&mgr->priv->db_lock); /* Update in memory */ GList *new, *old; new = folder_perm_list_copy (folder_perms); new = g_list_sort (new, comp_folder_perms); pthread_mutex_lock (&mgr->priv->perm_lock); if (type == FOLDER_PERM_TYPE_USER) { old = g_hash_table_lookup (mgr->priv->user_perms, repo_id); if (old) g_list_free_full (old, (GDestroyNotify)folder_perm_free); g_hash_table_insert (mgr->priv->user_perms, g_strdup(repo_id), new); } else if (type == FOLDER_PERM_TYPE_GROUP) { old = g_hash_table_lookup (mgr->priv->group_perms, repo_id); if (old) g_list_free_full (old, (GDestroyNotify)folder_perm_free); g_hash_table_insert (mgr->priv->group_perms, g_strdup(repo_id), new); } pthread_mutex_unlock (&mgr->priv->perm_lock); return 0; } static gboolean load_folder_perm (sqlite3_stmt *stmt, void *data) { GList **p_perms = data; const char *path, *permission; path = (const char *)sqlite3_column_text (stmt, 0); permission = (const char *)sqlite3_column_text (stmt, 1); FolderPerm *perm = folder_perm_new (path, permission); *p_perms = g_list_prepend (*p_perms, perm); return TRUE; } static GList * load_folder_perms_for_repo (SeafRepoManager *mgr, const char *repo_id, FolderPermType type) { GList *perms = NULL; char sql[256]; g_return_val_if_fail ((type == FOLDER_PERM_TYPE_USER || type == FOLDER_PERM_TYPE_GROUP), NULL); if (type == FOLDER_PERM_TYPE_USER) sqlite3_snprintf (sizeof(sql), sql, "SELECT path, permission FROM FolderUserPerms " "WHERE repo_id = '%q'", repo_id); else sqlite3_snprintf (sizeof(sql), sql, "SELECT path, permission FROM FolderGroupPerms " "WHERE repo_id = '%q'", repo_id); pthread_mutex_lock (&mgr->priv->db_lock); if (sqlite_foreach_selected_row (mgr->priv->db, sql, load_folder_perm, &perms) < 0) { pthread_mutex_unlock (&mgr->priv->db_lock); GList *ptr; for (ptr = perms; ptr; ptr = ptr->next) folder_perm_free ((FolderPerm *)ptr->data); g_list_free (perms); return NULL; } pthread_mutex_unlock (&mgr->priv->db_lock); /* Sort list in descending order by perm->path (longer path first). */ perms = g_list_sort (perms, comp_folder_perms); return perms; } static void init_folder_perms (SeafRepoManager *mgr) { SeafRepoManagerPriv *priv = mgr->priv; GList *repo_ids = g_hash_table_get_keys (priv->repo_hash); GList *ptr; GList *perms; char *repo_id; priv->user_perms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->group_perms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); pthread_mutex_init (&priv->perm_lock, NULL); for (ptr = repo_ids; ptr; ptr = ptr->next) { repo_id = ptr->data; perms = load_folder_perms_for_repo (mgr, repo_id, FOLDER_PERM_TYPE_USER); if (perms) { pthread_mutex_lock (&priv->perm_lock); g_hash_table_insert (priv->user_perms, g_strdup(repo_id), perms); pthread_mutex_unlock (&priv->perm_lock); } perms = load_folder_perms_for_repo (mgr, repo_id, FOLDER_PERM_TYPE_GROUP); if (perms) { pthread_mutex_lock (&priv->perm_lock); g_hash_table_insert (priv->group_perms, g_strdup(repo_id), perms); pthread_mutex_unlock (&priv->perm_lock); } } g_list_free (repo_ids); } static void remove_folder_perms (SeafRepoManager *mgr, const char *repo_id) { GList *perms = NULL; pthread_mutex_lock (&mgr->priv->perm_lock); perms = g_hash_table_lookup (mgr->priv->user_perms, repo_id); if (perms) { g_list_free_full (perms, (GDestroyNotify)folder_perm_free); g_hash_table_remove (mgr->priv->user_perms, repo_id); } perms = g_hash_table_lookup (mgr->priv->group_perms, repo_id); if (perms) { g_list_free_full (perms, (GDestroyNotify)folder_perm_free); g_hash_table_remove (mgr->priv->group_perms, repo_id); } pthread_mutex_unlock (&mgr->priv->perm_lock); } int seaf_repo_manager_update_folder_perm_timestamp (SeafRepoManager *mgr, const char *repo_id, gint64 timestamp) { char sql[256]; int ret; snprintf (sql, sizeof(sql), "REPLACE INTO FolderPermTimestamp VALUES ('%s', %"G_GINT64_FORMAT")", repo_id, timestamp); pthread_mutex_lock (&mgr->priv->db_lock); ret = sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return ret; } gint64 seaf_repo_manager_get_folder_perm_timestamp (SeafRepoManager *mgr, const char *repo_id) { char sql[256]; gint64 ret; sqlite3_snprintf (sizeof(sql), sql, "SELECT timestamp FROM FolderPermTimestamp WHERE repo_id = '%q'", repo_id); pthread_mutex_lock (&mgr->priv->db_lock); ret = sqlite_get_int64 (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); return ret; } static char * lookup_folder_perm (GList *perms, const char *path) { GList *ptr; FolderPerm *perm; char *folder; int len; char *permission = NULL; for (ptr = perms; ptr; ptr = ptr->next) { perm = ptr->data; if (strcmp (perm->path, "/") != 0) folder = g_strconcat (perm->path, "/", NULL); else folder = g_strdup(perm->path); len = strlen(folder); if (strcmp (perm->path, path) == 0 || strncmp(folder, path, len) == 0) { permission = perm->permission; g_free (folder); break; } g_free (folder); } return permission; } static gboolean is_path_writable (const char *repo_id, gboolean is_repo_readonly, const char *path) { SeafRepoManager *mgr = seaf->repo_mgr; GList *user_perms = NULL, *group_perms = NULL; char *permission = NULL; char *abs_path = NULL; pthread_mutex_lock (&mgr->priv->perm_lock); user_perms = g_hash_table_lookup (mgr->priv->user_perms, repo_id); group_perms = g_hash_table_lookup (mgr->priv->group_perms, repo_id); if (user_perms || group_perms) abs_path = g_strconcat ("/", path, NULL); if (user_perms) permission = lookup_folder_perm (user_perms, abs_path); if (!permission && group_perms) permission = lookup_folder_perm (group_perms, abs_path); pthread_mutex_unlock (&mgr->priv->perm_lock); g_free (abs_path); if (!permission) return !is_repo_readonly; if (strcmp (permission, "rw") == 0) return TRUE; else return FALSE; } gboolean seaf_repo_manager_is_path_writable (SeafRepoManager *mgr, const char *repo_id, const char *path) { SeafRepo *repo = seaf_repo_manager_get_repo (mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", repo_id); return FALSE; } return is_path_writable (repo_id, repo->is_readonly, path); } gboolean is_repo_id_valid (const char *id) { if (!id) return FALSE; return is_uuid_valid (id); } #define SYNC_ERROR_ID_FILE_LOCKED_BY_APP 0 #define SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP 1 #define SYNC_ERROR_ID_FILE_LOCKED 2 #define SYNC_ERROR_ID_INVALID_PATH 3 #define SYNC_ERROR_ID_INDEX_ERROR 4 #define SYNC_ERROR_ID_PATH_END_SPACE_PERIOD 5 #define SYNC_ERROR_ID_PATH_INVALID_CHARACTER 6 typedef struct FileErrorAux { char *repo_id; char *path; int err_id; } FileErrorAux; static gboolean get_last_file_sync_error (sqlite3_stmt *stmt, void *data) { FileErrorAux *aux = data; aux->repo_id = g_strdup((const char *)sqlite3_column_text (stmt, 0)); aux->path = g_strdup((const char *)sqlite3_column_text (stmt, 1)); aux->err_id = sqlite3_column_int (stmt, 2); return FALSE; } static void save_file_sync_error (const char *repo_id, const char *repo_name, const char *path, int err_id) { char *sql; FileErrorAux aux; int n; memset (&aux, 0, sizeof(aux)); pthread_mutex_lock (&seaf->repo_mgr->priv->db_lock); sql = "SELECT repo_id, path, err_id FROM FileSyncError " "ORDER BY id DESC LIMIT 1 OFFSET 0"; n = sqlite_foreach_selected_row (seaf->repo_mgr->priv->db, sql, get_last_file_sync_error, &aux); if (n > 0 && g_strcmp0(repo_id, aux.repo_id) == 0 && g_strcmp0(path, aux.path) == 0 && err_id == aux.err_id) goto out; sql = sqlite3_mprintf ("INSERT INTO FileSyncError " "(repo_id, repo_name, path, err_id, timestamp) " "VALUES ('%q', '%q', '%q', %d, %"G_GINT64_FORMAT")", repo_id, repo_name, path, err_id, (gint64)time(NULL)); sqlite_query_exec (seaf->repo_mgr->priv->db, sql); sqlite3_free (sql); out: pthread_mutex_unlock (&seaf->repo_mgr->priv->db_lock); g_free (aux.repo_id); g_free (aux.path); return; } static gboolean collect_file_sync_errors (sqlite3_stmt *stmt, void *data) { GList **pret = data; const char *repo_id, *repo_name, *path; int err_id; gint64 timestamp; SeafileFileSyncError *error; repo_id = (const char *)sqlite3_column_text (stmt, 0); repo_name = (const char *)sqlite3_column_text (stmt, 1); path = (const char *)sqlite3_column_text (stmt, 2); err_id = sqlite3_column_int (stmt, 3); timestamp = sqlite3_column_int64 (stmt, 4); error = g_object_new (SEAFILE_TYPE_FILE_SYNC_ERROR, "repo_id", repo_id, "repo_name", repo_name, "path", path, "err_id", err_id, "timestamp", timestamp, NULL); *pret = g_list_prepend (*pret, error); return TRUE; } GList * seaf_repo_manager_get_file_sync_errors (SeafRepoManager *mgr, int offset, int limit) { GList *ret = NULL; char *sql; pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("SELECT repo_id, repo_name, path, err_id, timestamp FROM " "FileSyncError ORDER BY id DESC LIMIT %d OFFSET %d", limit, offset); sqlite_foreach_selected_row (mgr->priv->db, sql, collect_file_sync_errors, &ret); sqlite3_free (sql); pthread_mutex_unlock (&mgr->priv->db_lock); ret = g_list_reverse (ret); return ret; } typedef struct SyncErrorData { char *repo_id; char *repo_name; char *path; int err_id; } SyncErrorData; static void notify_sync_error (CEvent *event, void *handler_data) { SyncErrorData *data = event->data; json_t *object; char *str; object = json_object (); json_object_set_new (object, "repo_id", json_string(data->repo_id)); json_object_set_new (object, "repo_name", json_string(data->repo_name)); json_object_set_new (object, "path", json_string(data->path)); json_object_set_new (object, "err_id", json_integer(data->err_id)); str = json_dumps (object, 0); seaf_mq_manager_publish_notification (seaf->mq_mgr, "sync.error", str); free (str); json_decref (object); g_free (data->repo_id); g_free (data->repo_name); g_free (data->path); g_free (data); } static void send_sync_error_notification (const char *repo_id, const char *repo_name, const char *path, int err_id) { if (!repo_name) { SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) return; repo_name = repo->name; } SyncErrorData *data = g_new0 (SyncErrorData, 1); data->repo_id = g_strdup(repo_id); data->repo_name = g_strdup(repo_name); data->path = g_strdup(path); data->err_id = err_id; cevent_manager_add_event (seaf->ev_mgr, seaf->repo_mgr->priv->cevent_id, data); save_file_sync_error (repo_id, repo_name, path, err_id); } SeafRepo* seaf_repo_new (const char *id, const char *name, const char *desc) { SeafRepo* repo; /* valid check */ repo = g_new0 (SeafRepo, 1); memcpy (repo->id, id, 36); repo->id[36] = '\0'; repo->name = g_strdup(name); repo->desc = g_strdup(desc); repo->worktree_invalid = TRUE; repo->auto_sync = 1; pthread_mutex_init (&repo->lock, NULL); return repo; } int seaf_repo_check_worktree (SeafRepo *repo) { SeafStat st; if (repo->worktree == NULL) { seaf_warning ("Worktree for repo '%s'(%.8s) is not set.\n", repo->name, repo->id); return -1; } /* check repo worktree */ if (g_access(repo->worktree, F_OK) < 0) { seaf_warning ("Failed to access worktree %s for repo '%s'(%.8s)\n", repo->worktree, repo->name, repo->id); return -1; } if (seaf_stat(repo->worktree, &st) < 0) { seaf_warning ("Failed to stat worktree %s for repo '%s'(%.8s)\n", repo->worktree, repo->name, repo->id); return -1; } if (!S_ISDIR(st.st_mode)) { seaf_warning ("Worktree %s for repo '%s'(%.8s) is not a directory.\n", repo->worktree, repo->name, repo->id); return -1; } return 0; } static gboolean check_worktree_common (SeafRepo *repo) { if (!repo->head) { seaf_warning ("Head for repo '%s'(%.8s) is not set.\n", repo->name, repo->id); return FALSE; } if (seaf_repo_check_worktree (repo) < 0) { return FALSE; } return TRUE; } void seaf_repo_free (SeafRepo *repo) { if (repo->head) seaf_branch_unref (repo->head); g_free (repo->name); g_free (repo->desc); g_free (repo->category); g_free (repo->worktree); g_free (repo->relay_id); g_free (repo->email); g_free (repo->token); g_free (repo); } static void set_head_common (SeafRepo *repo, SeafBranch *branch) { if (repo->head) seaf_branch_unref (repo->head); repo->head = branch; seaf_branch_ref(branch); } int seaf_repo_set_head (SeafRepo *repo, SeafBranch *branch) { if (save_branch_repo_map (repo->manager, branch) < 0) return -1; set_head_common (repo, branch); return 0; } SeafCommit * seaf_repo_get_head_commit (const char *repo_id) { SeafRepo *repo; SeafCommit *head; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %s.\n", repo_id); return NULL; } head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo->version, repo->head->commit_id); if (!head) { seaf_warning ("Failed to get head for repo %s.\n", repo_id); return NULL; } return head; } void seaf_repo_from_commit (SeafRepo *repo, SeafCommit *commit) { repo->name = g_strdup (commit->repo_name); repo->desc = g_strdup (commit->repo_desc); repo->encrypted = commit->encrypted; repo->last_modify = commit->ctime; memcpy (repo->root_id, commit->root_id, 40); if (repo->encrypted) { repo->enc_version = commit->enc_version; if (repo->enc_version == 1) memcpy (repo->magic, commit->magic, 32); else if (repo->enc_version == 2) { memcpy (repo->magic, commit->magic, 64); memcpy (repo->random_key, commit->random_key, 96); } } repo->no_local_history = commit->no_local_history; repo->version = commit->version; } void seaf_repo_to_commit (SeafRepo *repo, SeafCommit *commit) { commit->repo_name = g_strdup (repo->name); commit->repo_desc = g_strdup (repo->desc); commit->encrypted = repo->encrypted; if (commit->encrypted) { commit->enc_version = repo->enc_version; if (commit->enc_version == 1) commit->magic = g_strdup (repo->magic); else if (commit->enc_version == 2) { commit->magic = g_strdup (repo->magic); commit->random_key = g_strdup (repo->random_key); } } commit->no_local_history = repo->no_local_history; commit->version = repo->version; } static gboolean need_to_sync_worktree_name (const char *repo_id) { char *need_sync_wt_name = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo_id, REPO_SYNC_WORKTREE_NAME); gboolean ret = (g_strcmp0(need_sync_wt_name, "true") == 0); g_free (need_sync_wt_name); return ret; } static void update_repo_worktree_name (SeafRepo *repo, const char *new_name, gboolean rewatch) { char *dirname = NULL, *basename = NULL; char *new_worktree = NULL; seaf_message ("Update worktree folder name of repo %s to %s.\n", repo->id, new_name); dirname = g_path_get_dirname (repo->worktree); if (g_strcmp0 (dirname, ".") == 0) return; basename = g_path_get_basename (repo->worktree); new_worktree = g_build_filename (dirname, new_name, NULL); /* This can possibly fail on Windows if some files are opened under the worktree. * The rename operation will be retried on next restart. */ if (seaf_util_rename (repo->worktree, new_worktree) < 0) { seaf_warning ("Failed to rename worktree from %s to %s: %s.\n", repo->worktree, new_worktree, strerror(errno)); goto out; } if (seaf_repo_manager_set_repo_worktree (seaf->repo_mgr, repo, new_worktree) < 0) { goto out; } if (rewatch) { if (seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id) < 0) { seaf_warning ("Failed to unwatch repo %s old worktree.\n", repo->id); goto out; } if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("Failed to watch repo %s new worktree.\n", repo->id); } } out: g_free (dirname); g_free (basename); g_free (new_worktree); } void seaf_repo_set_name (SeafRepo *repo, const char *new_name) { char *old_name = repo->name; repo->name = g_strdup(new_name); g_free (old_name); if (need_to_sync_worktree_name (repo->id)) update_repo_worktree_name (repo, new_name, TRUE); } static gboolean collect_commit (SeafCommit *commit, void *vlist, gboolean *stop) { GList **commits = vlist; /* The traverse function will unref the commit, so we need to ref it. */ seaf_commit_ref (commit); *commits = g_list_prepend (*commits, commit); return TRUE; } GList * seaf_repo_get_commits (SeafRepo *repo) { GList *branches; GList *ptr; SeafBranch *branch; GList *commits = NULL; branches = seaf_branch_manager_get_branch_list (seaf->branch_mgr, repo->id); if (branches == NULL) { seaf_warning ("Failed to get branch list of repo %s.\n", repo->id); return NULL; } for (ptr = branches; ptr != NULL; ptr = ptr->next) { branch = ptr->data; gboolean res = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, repo->id, repo->version, branch->commit_id, collect_commit, &commits, FALSE); if (!res) { for (ptr = commits; ptr != NULL; ptr = ptr->next) seaf_commit_unref ((SeafCommit *)(ptr->data)); g_list_free (commits); goto out; } } commits = g_list_reverse (commits); out: for (ptr = branches; ptr != NULL; ptr = ptr->next) { seaf_branch_unref ((SeafBranch *)ptr->data); } return commits; } void seaf_repo_set_readonly (SeafRepo *repo) { repo->is_readonly = TRUE; save_repo_property (repo->manager, repo->id, REPO_PROP_IS_READONLY, "true"); } void seaf_repo_unset_readonly (SeafRepo *repo) { repo->is_readonly = FALSE; save_repo_property (repo->manager, repo->id, REPO_PROP_IS_READONLY, "false"); } gboolean seaf_repo_manager_is_ignored_hidden_file (const char *filename) { GPatternSpec **spec = ignore_patterns; while (*spec) { if (g_pattern_match_string(*spec, filename)) return TRUE; spec++; } return FALSE; } static gboolean should_ignore(const char *basepath, const char *filename, void *data) { GPatternSpec **spec = ignore_patterns; GList *ignore_list = (GList *)data; if (!g_utf8_validate (filename, -1, NULL)) { seaf_warning ("File name %s contains non-UTF8 characters, skip.\n", filename); return TRUE; } /* Ignore file/dir if its name is too long. */ if (strlen(filename) >= SEAF_DIR_NAME_LEN) return TRUE; if (strchr (filename, '/')) return TRUE; while (*spec) { if (g_pattern_match_string(*spec, filename)) return TRUE; spec++; } if (!seaf->sync_extra_temp_file) { spec = office_temp_ignore_patterns; while (*spec) { if (g_pattern_match_string(*spec, filename)) return TRUE; spec++; } } if (basepath) { char *fullpath = g_build_path ("/", basepath, filename, NULL); if (seaf_repo_check_ignore_file (ignore_list, fullpath)) { g_free (fullpath); return TRUE; } g_free (fullpath); } return FALSE; } static int index_cb (const char *repo_id, int version, const char *path, unsigned char sha1[], SeafileCrypt *crypt, gboolean write_data) { gint64 size; /* Check in blocks and get object ID. */ if (seaf_fs_manager_index_blocks (seaf->fs_mgr, repo_id, version, path, sha1, &size, crypt, write_data, TRUE) < 0) { seaf_warning ("Failed to index file %s.\n", path); return -1; } return 0; } #define MAX_COMMIT_SIZE 100 * (1 << 20) /* 100MB */ typedef struct _AddOptions { LockedFileSet *fset; ChangeSet *changeset; gboolean is_repo_ro; gboolean startup_scan; } AddOptions; static int add_file (const char *repo_id, int version, const char *modifier, struct index_state *istate, const char *path, const char *full_path, SeafStat *st, SeafileCrypt *crypt, gint64 *total_size, GQueue **remain_files, AddOptions *options) { gboolean added = FALSE; int ret = 0; gboolean is_writable = TRUE, is_locked = FALSE; struct cache_entry *ce; if (options) is_writable = is_path_writable(repo_id, options->is_repo_ro, path); is_locked = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, path); if (is_locked && options && !(options->startup_scan)) { /* send_sync_error_notification (repo_id, NULL, path, */ /* SYNC_ERROR_ID_FILE_LOCKED); */ } if (options && options->startup_scan) { SyncStatus status; ce = index_name_exists (istate, path, strlen(path), 0); if (!ce || ie_match_stat(ce, st, 0) != 0) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; /* Don't set "syncing" status for read-only path. */ if (status == SYNC_STATUS_SYNCED || (is_writable && !is_locked)) seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, S_IFREG, status); } if (!is_writable || is_locked) return ret; #ifdef WIN32 if (options && options->fset) { LockedFile *file = locked_file_set_lookup (options->fset, path); if (file) { if (strcmp (file->operation, LOCKED_OP_DELETE) == 0) { /* Only remove the lock record if the file is changed. */ if (st->st_mtime == file->old_mtime) { return ret; } locked_file_set_remove (options->fset, path, FALSE); } else if (strcmp (file->operation, LOCKED_OP_UPDATE) == 0) { return ret; } } } #endif if (!remain_files) { ret = add_to_index (repo_id, version, istate, path, full_path, st, 0, crypt, index_cb, modifier, &added); if (!added) { /* If the contents of the file doesn't change, move it to synced status. */ seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, S_IFREG, SYNC_STATUS_SYNCED); } else { if (total_size) *total_size += (gint64)(st->st_size); if (options && options->changeset) { /* ce may be updated. */ ce = index_name_exists (istate, path, strlen(path), 0); add_to_changeset (options->changeset, DIFF_STATUS_ADDED, ce->sha1, st, modifier, path, NULL); } } } else if (*remain_files == NULL) { ret = add_to_index (repo_id, version, istate, path, full_path, st, 0, crypt, index_cb, modifier, &added); if (added) { *total_size += (gint64)(st->st_size); if (*total_size >= MAX_COMMIT_SIZE) *remain_files = g_queue_new (); } else { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, S_IFREG, SYNC_STATUS_SYNCED); } if (added && options && options->changeset) { /* ce may be updated. */ ce = index_name_exists (istate, path, strlen(path), 0); add_to_changeset (options->changeset, DIFF_STATUS_ADDED, ce->sha1, st, modifier, path, NULL); } } else { *total_size += (gint64)(st->st_size); g_queue_push_tail (*remain_files, g_strdup(path)); } if (ret < 0) { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, S_IFREG, SYNC_STATUS_ERROR); /* send_sync_error_notification (repo_id, NULL, path, */ /* SYNC_ERROR_ID_INDEX_ERROR); */ } return ret; } typedef struct AddParams { const char *repo_id; int version; const char *modifier; struct index_state *istate; const char *worktree; SeafileCrypt *crypt; gboolean ignore_empty_dir; GList *ignore_list; gint64 *total_size; GQueue **remain_files; AddOptions *options; } AddParams; #ifndef WIN32 static int add_dir_recursive (const char *path, const char *full_path, SeafStat *st, AddParams *params, gboolean ignored) { AddOptions *options = params->options; GDir *dir; const char *dname; char *subpath, *full_subpath; int n, total; gboolean is_writable = TRUE; struct stat sub_st; dir = g_dir_open (full_path, 0, NULL); if (!dir) { seaf_warning ("Failed to open dir %s: %s.\n", full_path, strerror(errno)); seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, SYNC_STATUS_ERROR); return 0; } n = 0; total = 0; while ((dname = g_dir_read_name(dir)) != NULL) { ++total; #ifdef __APPLE__ char *norm_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC); subpath = g_build_path (PATH_SEPERATOR, path, norm_dname, NULL); g_free (norm_dname); #else subpath = g_build_path (PATH_SEPERATOR, path, dname, NULL); #endif full_subpath = g_build_filename (params->worktree, subpath, NULL); if (stat (full_subpath, &sub_st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_subpath, strerror(errno)); g_free (subpath); g_free (full_subpath); continue; } if (ignored || should_ignore(full_path, dname, params->ignore_list)) { if (options && options->startup_scan) { if (S_ISDIR(sub_st.st_mode)) add_dir_recursive (subpath, full_subpath, &sub_st, params, TRUE); else seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, subpath, S_IFREG, SYNC_STATUS_IGNORED); } g_free (subpath); g_free (full_subpath); continue; } ++n; if (S_ISDIR(sub_st.st_mode)) add_dir_recursive (subpath, full_subpath, &sub_st, params, FALSE); else if (S_ISREG(sub_st.st_mode)) add_file (params->repo_id, params->version, params->modifier, params->istate, subpath, full_subpath, &sub_st, params->crypt, params->total_size, params->remain_files, params->options); g_free (subpath); g_free (full_subpath); } g_dir_close (dir); if (ignored) { seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, SYNC_STATUS_IGNORED); return 0; } if (options) is_writable = is_path_writable(params->repo_id, options->is_repo_ro, path); /* Update active path status for empty dir */ if (options && options->startup_scan && total == 0) { SyncStatus status; struct cache_entry *ce = index_name_exists (params->istate, path, strlen(path), 0); if (!ce) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; if (status == SYNC_STATUS_SYNCED || is_writable) seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, status); } if (n == 0 && path[0] != 0 && is_writable) { if (!params->remain_files || *(params->remain_files) == NULL) { int rc = add_empty_dir_to_index (params->istate, path, st); if (rc == 1 && options && options->changeset) { unsigned char allzero[20] = {0}; add_to_changeset (options->changeset, DIFF_STATUS_DIR_ADDED, allzero, st, NULL, path, NULL); } } else g_queue_push_tail (*(params->remain_files), g_strdup(path)); } return 0; } /* * @remain_files: returns the files haven't been added under this path. * If it's set to NULL, no partial commit will be created. */ static int add_recursive (const char *repo_id, int version, const char *modifier, struct index_state *istate, const char *worktree, const char *path, SeafileCrypt *crypt, gboolean ignore_empty_dir, GList *ignore_list, gint64 *total_size, GQueue **remain_files, AddOptions *options) { char *full_path; SeafStat st; full_path = g_build_path (PATH_SEPERATOR, worktree, path, NULL); if (seaf_stat (full_path, &st) < 0) { /* Ignore broken symlinks on Linux and Mac OS X */ if (lstat (full_path, &st) == 0 && S_ISLNK(st.st_mode)) { g_free (full_path); return 0; } seaf_warning ("Failed to stat %s.\n", full_path); g_free (full_path); /* Ignore error. */ seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, 0, SYNC_STATUS_ERROR); return 0; } if (S_ISREG(st.st_mode)) { add_file (repo_id, version, modifier, istate, path, full_path, &st, crypt, total_size, remain_files, options); } else if (S_ISDIR(st.st_mode)) { AddParams params = { .repo_id = repo_id, .version = version, .modifier = modifier, .istate = istate, .worktree = worktree, .crypt = crypt, .ignore_empty_dir = ignore_empty_dir, .ignore_list = ignore_list, .total_size = total_size, .remain_files = remain_files, .options = options, }; add_dir_recursive (path, full_path, &st, ¶ms, FALSE); } g_free (full_path); return 0; } static gboolean is_empty_dir (const char *path, GList *ignore_list) { GDir *dir; const char *dname; gboolean ret = TRUE; dir = g_dir_open (path, 0, NULL); if (!dir) { return FALSE; } while ((dname = g_dir_read_name(dir)) != NULL) { if (!should_ignore(path, dname, ignore_list)) { ret = FALSE; break; } } g_dir_close (dir); return ret; } #else typedef struct IterCBData { AddParams *add_params; const char *parent; const char *full_parent; int n; /* If parent dir is ignored, all children are ignored too. */ gboolean ignored; } IterCBData; static int add_dir_recursive (const char *path, const char *full_path, SeafStat *st, AddParams *params, gboolean ignored); static int iter_dir_cb (wchar_t *full_parent_w, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { IterCBData *data = user_data; AddParams *params = data->add_params; AddOptions *options = params->options; char *dname = NULL, *path = NULL, *full_path = NULL; SeafStat st; int ret = 0; dname = g_utf16_to_utf8 (fdata->cFileName, -1, NULL, NULL, NULL); path = g_build_path ("/", data->parent, dname, NULL); full_path = g_build_path ("/", params->worktree, path, NULL); seaf_stat_from_find_data (fdata, &st); if (data->ignored || should_ignore(data->full_parent, dname, params->ignore_list)) { if (options && options->startup_scan) { if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) add_dir_recursive (path, full_path, &st, params, TRUE); else seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFREG, SYNC_STATUS_IGNORED); } goto out; } if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ret = add_dir_recursive (path, full_path, &st, params, FALSE); else ret = add_file (params->repo_id, params->version, params->modifier, params->istate, path, full_path, &st, params->crypt, params->total_size, params->remain_files, params->options); ++(data->n); out: g_free (dname); g_free (path); g_free (full_path); return 0; } static int add_dir_recursive (const char *path, const char *full_path, SeafStat *st, AddParams *params, gboolean ignored) { AddOptions *options = params->options; IterCBData data; wchar_t *full_path_w; int ret = 0; gboolean is_writable = TRUE; memset (&data, 0, sizeof(data)); data.add_params = params; data.parent = path; data.full_parent = full_path; data.ignored = ignored; full_path_w = win32_long_path (full_path); ret = traverse_directory_win32 (full_path_w, iter_dir_cb, &data); g_free (full_path_w); /* Ignore traverse dir error. */ if (ret < 0) { seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, SYNC_STATUS_ERROR); return 0; } if (ignored) { seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, SYNC_STATUS_IGNORED); return 0; } if (options) is_writable = is_path_writable(params->repo_id, options->is_repo_ro, path); /* Update active path status for empty dir */ if (options && options->startup_scan && ret == 0) { SyncStatus status; struct cache_entry *ce = index_name_exists (params->istate, path, strlen(path), 0); if (!ce) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; if (status == SYNC_STATUS_SYNCED || is_writable) seaf_sync_manager_update_active_path (seaf->sync_mgr, params->repo_id, path, S_IFDIR, status); } if (data.n == 0 && path[0] != 0 && !params->ignore_empty_dir && is_writable) { if (!params->remain_files || *(params->remain_files) == NULL) { int rc = add_empty_dir_to_index (params->istate, path, st); if (rc == 1 && options && options->changeset) { unsigned char allzero[20] = {0}; add_to_changeset (options->changeset, DIFF_STATUS_DIR_ADDED, allzero, st, NULL, path, NULL); } } else g_queue_push_tail (*(params->remain_files), g_strdup(path)); } return ret; } static int add_recursive (const char *repo_id, int version, const char *modifier, struct index_state *istate, const char *worktree, const char *path, SeafileCrypt *crypt, gboolean ignore_empty_dir, GList *ignore_list, gint64 *total_size, GQueue **remain_files, AddOptions *options) { char *full_path; SeafStat st; int ret = 0; full_path = g_build_path (PATH_SEPERATOR, worktree, path, NULL); if (seaf_stat (full_path, &st) < 0) { seaf_warning ("Failed to stat %s.\n", full_path); g_free (full_path); seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, path, 0, SYNC_STATUS_ERROR); /* Ignore error */ return 0; } if (S_ISREG(st.st_mode)) { ret = add_file (repo_id, version, modifier, istate, path, full_path, &st, crypt, total_size, remain_files, options); } else if (S_ISDIR(st.st_mode)) { AddParams params = { .repo_id = repo_id, .version = version, .modifier = modifier, .istate = istate, .worktree = worktree, .crypt = crypt, .ignore_empty_dir = ignore_empty_dir, .ignore_list = ignore_list, .total_size = total_size, .remain_files = remain_files, .options = options, }; ret = add_dir_recursive (path, full_path, &st, ¶ms, FALSE); } g_free (full_path); return ret; } static gboolean is_empty_dir (const char *path, GList *ignore_list) { WIN32_FIND_DATAW fdata; HANDLE handle; wchar_t *pattern; wchar_t *path_w; char *dname; int path_len_w; DWORD error; gboolean ret = TRUE; path_w = win32_long_path (path); path_len_w = wcslen(path_w); pattern = g_new0 (wchar_t, (path_len_w + 3)); wcscpy (pattern, path_w); wcscat (pattern, L"\\*"); handle = FindFirstFileW (pattern, &fdata); if (handle == INVALID_HANDLE_VALUE) { seaf_warning ("FindFirstFile failed %s: %lu.\n", path, GetLastError()); ret = FALSE; goto out; } do { if (wcscmp (fdata.cFileName, L".") == 0 || wcscmp (fdata.cFileName, L"..") == 0) continue; dname = g_utf16_to_utf8 (fdata.cFileName, -1, NULL, NULL, NULL); if (!should_ignore (path, dname, ignore_list)) { ret = FALSE; g_free (dname); FindClose (handle); goto out; } g_free (dname); } while (FindNextFileW (handle, &fdata) != 0); error = GetLastError(); if (error != ERROR_NO_MORE_FILES) { seaf_warning ("FindNextFile failed %s: %lu.\n", path, error); } FindClose (handle); out: g_free (path_w); g_free (pattern); return ret; } #endif /* WIN32 */ /* Returns whether the file should be removed from index. */ static gboolean check_locked_file_before_remove (LockedFileSet *fset, const char *path) { #ifdef WIN32 if (!fset) return TRUE; LockedFile *file = locked_file_set_lookup (fset, path); gboolean ret = TRUE; if (file) ret = FALSE; return ret; #else return TRUE; #endif } static void remove_deleted (struct index_state *istate, const char *worktree, const char *prefix, GList *ignore_list, LockedFileSet *fset, const char *repo_id, gboolean is_repo_ro, ChangeSet *changeset) { struct cache_entry **ce_array = istate->cache; struct cache_entry *ce; char path[SEAF_PATH_MAX]; unsigned int i; SeafStat st; int ret; gboolean not_exist; char *full_prefix = g_strconcat (prefix, "/", NULL); int len = strlen(full_prefix); for (i = 0; i < istate->cache_nr; ++i) { ce = ce_array[i]; if (!is_path_writable (repo_id, is_repo_ro, ce->name)) continue; if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, ce->name)) { seaf_debug ("Remove deleted: %s is locked on server, ignore.\n", ce->name); continue; } if (prefix[0] != 0 && strcmp (ce->name, prefix) != 0 && strncmp (ce->name, full_prefix, len) != 0) continue; snprintf (path, SEAF_PATH_MAX, "%s/%s", worktree, ce->name); not_exist = FALSE; ret = seaf_stat (path, &st); if (ret < 0 && errno == ENOENT) not_exist = TRUE; if (S_ISDIR (ce->ce_mode)) { if (ce->ce_ctime.sec != 0 || ce_stage(ce) != 0) { if (not_exist || (ret == 0 && !S_ISDIR (st.st_mode))) { /* Add to changeset only if dir is removed. */ ce->ce_flags |= CE_REMOVE; if (changeset) /* Remove the parent dir from change set if it becomes * empty. If in the work tree the empty dir still exist, * we'll add it back to changeset in add_recursive() later. */ remove_from_changeset (changeset, DIFF_STATUS_DIR_DELETED, ce->name, TRUE, prefix, TRUE); } else if (!is_empty_dir (path, ignore_list)) { /* Don't add to changeset if empty dir became non-empty. */ ce->ce_flags |= CE_REMOVE; } } } else { /* If ce->ctime is 0 and stage is 0, it was not successfully checked out. * In this case we don't want to mistakenly remove the file * from the repo. */ if ((not_exist || (ret == 0 && !S_ISREG (st.st_mode))) && (ce->ce_ctime.sec != 0 || ce_stage(ce) != 0) && check_locked_file_before_remove (fset, ce->name)) { ce_array[i]->ce_flags |= CE_REMOVE; if (changeset) remove_from_changeset (changeset, DIFF_STATUS_DELETED, ce->name, TRUE, prefix, TRUE); } } } remove_marked_cache_entries (istate); g_free (full_prefix); } static int scan_worktree_for_changes (struct index_state *istate, SeafRepo *repo, SeafileCrypt *crypt, GList *ignore_list, LockedFileSet *fset) { remove_deleted (istate, repo->worktree, "", ignore_list, fset, repo->id, repo->is_readonly, repo->changeset); AddOptions options; memset (&options, 0, sizeof(options)); options.fset = fset; options.is_repo_ro = repo->is_readonly; options.changeset = repo->changeset; if (add_recursive (repo->id, repo->version, repo->email, istate, repo->worktree, "", crypt, FALSE, ignore_list, NULL, NULL, &options) < 0) return -1; return 0; } static gboolean check_full_path_ignore (const char *worktree, const char *path, GList *ignore_list) { char **tokens; guint i; guint n; gboolean ret = FALSE; tokens = g_strsplit (path, "/", 0); n = g_strv_length (tokens); for (i = 0; i < n; ++i) { /* don't check ignore_list */ if (should_ignore (NULL, tokens[i], ignore_list)) { ret = TRUE; goto out; } } char *full_path = g_build_path ("/", worktree, path, NULL); if (seaf_repo_check_ignore_file (ignore_list, full_path)) ret = TRUE; g_free (full_path); out: g_strfreev (tokens); return ret; } #ifndef __APPLE__ static int add_path_to_index (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, const char *path, GList *ignore_list, GList **scanned_dirs, gint64 *total_size, GQueue **remain_files, LockedFileSet *fset) { char *full_path; SeafStat st; AddOptions options; /* When a repo is initially added, a SCAN_DIR event will be created * for the worktree root "". */ if (path[0] == 0) { remove_deleted (istate, repo->worktree, "", ignore_list, fset, repo->id, repo->is_readonly, repo->changeset); memset (&options, 0, sizeof(options)); options.fset = fset; options.is_repo_ro = repo->is_readonly; options.startup_scan = TRUE; options.changeset = repo->changeset; add_recursive (repo->id, repo->version, repo->email, istate, repo->worktree, path, crypt, FALSE, ignore_list, total_size, remain_files, &options); return 0; } /* If we've recursively scanned the parent directory, don't need to scan * any files under it any more. */ GList *ptr; char *dir, *full_dir; for (ptr = *scanned_dirs; ptr; ptr = ptr->next) { dir = ptr->data; /* exact match */ if (strcmp (dir, path) == 0) { seaf_debug ("%s has been scanned before, skip adding.\n", path); return 0; } /* prefix match. */ full_dir = g_strconcat (dir, "/", NULL); if (strncmp (full_dir, path, strlen(full_dir)) == 0) { g_free (full_dir); seaf_debug ("%s has been scanned before, skip adding.\n", path); return 0; } g_free (full_dir); } if (check_full_path_ignore (repo->worktree, path, ignore_list)) return 0; full_path = g_build_filename (repo->worktree, path, NULL); if (seaf_stat (full_path, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", path, strerror(errno)); g_free (full_path); return -1; } if (S_ISDIR(st.st_mode)) *scanned_dirs = g_list_prepend (*scanned_dirs, g_strdup(path)); memset (&options, 0, sizeof(options)); options.fset = fset; options.is_repo_ro = repo->is_readonly; options.changeset = repo->changeset; /* Add is always recursive */ add_recursive (repo->id, repo->version, repo->email, istate, repo->worktree, path, crypt, FALSE, ignore_list, total_size, remain_files, &options); g_free (full_path); return 0; } #else static int add_path_to_index (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, const char *path, GList *ignore_list, GList **scanned_dirs, gint64 *total_size, GQueue **remain_files, LockedFileSet *fset) { /* If we've recursively scanned the parent directory, don't need to scan * any files under it any more. */ GList *ptr; char *dir, *full_dir; for (ptr = *scanned_dirs; ptr; ptr = ptr->next) { dir = ptr->data; /* Have scanned from root directory. */ if (dir[0] == 0) { seaf_debug ("%s has been scanned before, skip adding.\n", path); return 0; } /* exact match */ if (strcmp (dir, path) == 0) { seaf_debug ("%s has been scanned before, skip adding.\n", path); return 0; } /* prefix match. */ full_dir = g_strconcat (dir, "/", NULL); if (strncmp (full_dir, path, strlen(full_dir)) == 0) { g_free (full_dir); seaf_debug ("%s has been scanned before, skip adding.\n", path); return 0; } g_free (full_dir); } if (path[0] != 0 && check_full_path_ignore (repo->worktree, path, ignore_list)) return 0; remove_deleted (istate, repo->worktree, path, ignore_list, NULL, repo->id, repo->is_readonly, repo->changeset); *scanned_dirs = g_list_prepend (*scanned_dirs, g_strdup(path)); AddOptions options; memset (&options, 0, sizeof(options)); options.fset = fset; options.is_repo_ro = repo->is_readonly; options.changeset = repo->changeset; /* When something is changed in the root directory, update active path * sync status when scanning the worktree. This is inaccurate. This will * be changed after we process fs events on Mac more precisely. */ if (path[0] == 0) options.startup_scan = TRUE; /* Add is always recursive */ add_recursive (repo->id, repo->version, repo->email, istate, repo->worktree, path, crypt, FALSE, ignore_list, total_size, remain_files, &options); return 0; } #endif /* __APPLE__ */ static int add_remain_files (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, GQueue *remain_files, GList *ignore_list, gint64 *total_size) { char *path; char *full_path; SeafStat st; struct cache_entry *ce; while ((path = g_queue_pop_head (remain_files)) != NULL) { full_path = g_build_filename (repo->worktree, path, NULL); if (seaf_stat (full_path, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_path, strerror(errno)); g_free (path); g_free (full_path); continue; } if (S_ISREG(st.st_mode)) { gboolean added = FALSE; int ret = 0; ret = add_to_index (repo->id, repo->version, istate, path, full_path, &st, 0, crypt, index_cb, repo->email, &added); if (added) { ce = index_name_exists (istate, path, strlen(path), 0); add_to_changeset (repo->changeset, DIFF_STATUS_ADDED, ce->sha1, &st, repo->email, path, NULL); *total_size += (gint64)(st.st_size); if (*total_size >= MAX_COMMIT_SIZE) { g_free (path); g_free (full_path); break; } } else { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFREG, SYNC_STATUS_SYNCED); } if (ret < 0) { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFREG, SYNC_STATUS_ERROR); /* send_sync_error_notification (repo->id, NULL, path, */ /* SYNC_ERROR_ID_INDEX_ERROR); */ } } else if (S_ISDIR(st.st_mode)) { if (is_empty_dir (full_path, ignore_list)) { int rc = add_empty_dir_to_index (istate, path, &st); if (rc == 1) { unsigned char allzero[20] = {0}; add_to_changeset (repo->changeset, DIFF_STATUS_DIR_ADDED, allzero, &st, NULL, path, NULL); } } } g_free (path); g_free (full_path); } return 0; } static void try_add_empty_parent_dir_entry (const char *worktree, struct index_state *istate, const char *path) { if (index_name_exists (istate, path, strlen(path), 0) != NULL) return; char *parent_dir = g_path_get_dirname (path); /* Parent dir is the worktree dir. */ if (strcmp (parent_dir, ".") == 0) { g_free (parent_dir); return; } char *full_dir = g_build_filename (worktree, parent_dir, NULL); SeafStat st; if (seaf_stat (full_dir, &st) < 0) { goto out; } add_empty_dir_to_index_with_check (istate, parent_dir, &st); out: g_free (parent_dir); g_free (full_dir); } static void try_add_empty_parent_dir_entry_from_wt (const char *worktree, struct index_state *istate, GList *ignore_list, const char *path) { if (index_name_exists (istate, path, strlen(path), 0) != NULL) return; char *parent_dir = g_path_get_dirname (path); /* Parent dir is the worktree dir. */ if (strcmp (parent_dir, ".") == 0) { g_free (parent_dir); return; } char *full_dir = g_build_filename (worktree, parent_dir, NULL); SeafStat st; if (seaf_stat (full_dir, &st) < 0) { goto out; } if (is_empty_dir (full_dir, ignore_list)) { #ifdef WIN32 wchar_t *parent_dir_w = g_utf8_to_utf16 (parent_dir, -1, NULL, NULL, NULL); wchar_t *pw; for (pw = parent_dir_w; *pw != L'\0'; ++pw) if (*pw == L'/') *pw = L'\\'; wchar_t *long_path = win32_83_path_to_long_path (worktree, parent_dir_w, wcslen(parent_dir_w)); g_free (parent_dir_w); if (!long_path) { seaf_warning ("Convert %s to long path failed.\n", parent_dir); goto out; } char *utf8_path = g_utf16_to_utf8 (long_path, -1, NULL, NULL, NULL); char *p; for (p = utf8_path; *p != 0; ++p) if (*p == '\\') *p = '/'; g_free (long_path); add_empty_dir_to_index (istate, utf8_path, &st); #else add_empty_dir_to_index (istate, parent_dir, &st); #endif } out: g_free (parent_dir); g_free (full_dir); } static void update_attributes (SeafRepo *repo, struct index_state *istate, const char *worktree, const char *path) { ChangeSet *changeset = repo->changeset; char *full_path; struct cache_entry *ce; SeafStat st; ce = index_name_exists (istate, path, strlen(path), 0); if (!ce) return; full_path = g_build_filename (worktree, path, NULL); if (seaf_stat (full_path, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_path, strerror(errno)); g_free (full_path); return; } unsigned int new_mode = create_ce_mode (st.st_mode); if (new_mode != ce->ce_mode || st.st_mtime != ce->ce_mtime.sec) { ce->ce_mode = new_mode; ce->ce_mtime.sec = st.st_mtime; istate->cache_changed = 1; add_to_changeset (changeset, DIFF_STATUS_MODIFIED, ce->sha1, &st, repo->email, path, NULL); } g_free (full_path); } #ifdef WIN32 static void scan_subtree_for_deletion (const char *repo_id, struct index_state *istate, const char *worktree, const char *path, GList *ignore_list, LockedFileSet *fset, gboolean is_readonly, GList **scanned_dirs, ChangeSet *changeset) { wchar_t *path_w; wchar_t *dir_w = NULL; wchar_t *p; char *dir = NULL; char *p2; /* In most file systems, like NTFS, 8.3 format path should contain ~. * Also note that *~ files are ignored. */ if (!strchr (path, '~') || path[strlen(path)-1] == '~') return; path_w = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); for (p = path_w; *p != L'\0'; ++p) if (*p == L'/') *p = L'\\'; while (1) { p = wcsrchr (path_w, L'\\'); if (p) *p = L'\0'; else break; dir_w = win32_83_path_to_long_path (worktree, path_w, wcslen(path_w)); if (dir_w) break; } if (!dir_w) dir_w = wcsdup(L""); dir = g_utf16_to_utf8 (dir_w, -1, NULL, NULL, NULL); for (p2 = dir; *p2 != 0; ++p2) if (*p2 == '\\') *p2 = '/'; /* If we've recursively scanned the parent directory, don't need to scan * any files under it any more. */ GList *ptr; char *s, *full_s; for (ptr = *scanned_dirs; ptr; ptr = ptr->next) { s = ptr->data; /* Have scanned from root directory. */ if (s[0] == 0) { goto out; } /* exact match */ if (strcmp (s, path) == 0) { goto out; } /* prefix match. */ full_s = g_strconcat (s, "/", NULL); if (strncmp (full_s, dir, strlen(full_s)) == 0) { g_free (full_s); goto out; } g_free (full_s); } *scanned_dirs = g_list_prepend (*scanned_dirs, g_strdup(dir)); remove_deleted (istate, worktree, dir, ignore_list, fset, repo_id, is_readonly, changeset); /* After remove_deleted(), empty dirs are left not removed in changeset. * This can be fixed by removing the accurate deleted path. In most cases, * basename doesn't contain ~, so we can always get the accurate path. */ /* if (!convertion_failed) { */ /* char *basename = strrchr (path, '/'); */ /* char *deleted_path = NULL; */ /* if (basename) { */ /* deleted_path = g_build_path ("/", dir, basename, NULL); */ /* add_to_changeset (changeset, */ /* DIFF_STATUS_DELETED, */ /* NULL, */ /* NULL, */ /* NULL, */ /* deleted_path, */ /* NULL, */ /* FALSE); */ /* g_free (deleted_path); */ /* } */ /* } */ out: g_free (path_w); g_free (dir_w); g_free (dir); } #else static void scan_subtree_for_deletion (const char *repo_id, struct index_state *istate, const char *worktree, const char *path, GList *ignore_list, LockedFileSet *fset, gboolean is_readonly, GList **scanned_dirs, ChangeSet *changeset) { } #endif /* Return TRUE if the caller should stop processing next event. */ static gboolean handle_add_files (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, GList *ignore_list, LockedFileSet *fset, WTStatus *status, WTEvent *event, GList **scanned_dirs, gint64 *total_size) { SyncInfo *info; if (!repo->create_partial_commit) { /* XXX: We now use remain_files = NULL to signify not creating * partial commits. It's better to use total_size = NULL for * that purpose. */ add_path_to_index (repo, istate, crypt, event->path, ignore_list, scanned_dirs, total_size, NULL, NULL); } else if (!event->remain_files) { GQueue *remain_files = NULL; add_path_to_index (repo, istate, crypt, event->path, ignore_list, scanned_dirs, total_size, &remain_files, fset); if (*total_size >= MAX_COMMIT_SIZE) { seaf_message ("Creating partial commit after adding %s.\n", event->path); status->partial_commit = TRUE; /* An event for a new folder may contain many files. * If the total_size become larger than 100MB after adding * some of these files, the remaining file paths will be * cached in remain files. This way we don't need to scan * the folder again next time. */ if (remain_files) { if (g_queue_get_length (remain_files) == 0) { g_queue_free (remain_files); return TRUE; } seaf_message ("Remain files for %s.\n", event->path); /* Cache remaining files in the event structure. */ event->remain_files = remain_files; pthread_mutex_lock (&status->q_lock); g_queue_push_head (status->event_q, event); pthread_mutex_unlock (&status->q_lock); info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo->id); if (!info->multipart_upload) { info->multipart_upload = TRUE; info->total_bytes = *total_size; } } return TRUE; } } else { seaf_message ("Adding remaining files for %s.\n", event->path); add_remain_files (repo, istate, crypt, event->remain_files, ignore_list, total_size); if (g_queue_get_length (event->remain_files) != 0) { pthread_mutex_lock (&status->q_lock); g_queue_push_head (status->event_q, event); pthread_mutex_unlock (&status->q_lock); return TRUE; } else { info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, repo->id); info->end_multipart_upload = TRUE; return TRUE; } if (*total_size >= MAX_COMMIT_SIZE) return TRUE; } return FALSE; } #ifdef __APPLE__ struct _WTDirent { char *dname; struct stat st; }; typedef struct _WTDirent WTDirent; static gint compare_wt_dirents (gconstpointer a, gconstpointer b) { const WTDirent *dent_a = a, *dent_b = b; return (strcmp (dent_a->dname, dent_b->dname)); } static GList * get_sorted_wt_dirents (const char *dir_path, const char *full_dir_path, gboolean *error) { GDir *dir; GError *err = NULL; const char *name; char *dname; char *full_sub_path, *sub_path; WTDirent *dent; GList *ret = NULL; dir = g_dir_open (full_dir_path, 0, &err); if (!dir) { seaf_warning ("Failed to open dir %s: %s.\n", full_dir_path, err->message); *error = TRUE; return NULL; } while ((name = g_dir_read_name(dir)) != NULL) { dname = g_utf8_normalize (name, -1, G_NORMALIZE_NFC); sub_path = g_strconcat (dir_path, "/", dname, NULL); full_sub_path = g_strconcat (full_dir_path, "/", dname, NULL); dent = g_new0 (WTDirent, 1); dent->dname = dname; if (stat (full_sub_path, &dent->st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_sub_path, strerror(errno)); g_free (dname); g_free (sub_path); g_free (full_sub_path); g_free (dent); continue; } ret = g_list_prepend (ret, dent); g_free (sub_path); g_free (full_sub_path); } g_dir_close (dir); ret = g_list_sort (ret, compare_wt_dirents); return ret; } static void wt_dirent_free (WTDirent *dent) { if (!dent) return; g_free (dent->dname); g_free (dent); } inline static char * concat_sub_path (const char *dir, const char *dname) { if (dir[0] != 0) return g_strconcat(dir, "/", dname, NULL); else return g_strdup(dname); } static int get_changed_paths_in_folder (SeafRepo *repo, struct index_state *istate, const char *dir_path, GList **add, GList **mod, GList **del) { char *full_dir_path; GList *wt_dents = NULL, *index_dents = NULL; gboolean error = FALSE; full_dir_path = g_build_filename(repo->worktree, dir_path, NULL); wt_dents = get_sorted_wt_dirents (dir_path, full_dir_path, &error); if (error) { g_free (full_dir_path); return -1; } index_dents = list_dirents_from_index (istate, dir_path); GList *p; IndexDirent *dent; for (p = index_dents; p; p = p->next) { dent = p->data; } GList *p1 = wt_dents, *p2 = index_dents; WTDirent *dent1; IndexDirent *dent2; while (p1 && p2) { dent1 = p1->data; dent2 = p2->data; int rc = strcmp (dent1->dname, dent2->dname); if (rc == 0) { if (S_ISREG(dent1->st.st_mode) && !dent2->is_dir) { if (dent1->st.st_mtime != dent2->ce->ce_mtime.sec) *mod = g_list_prepend (*mod, concat_sub_path(dir_path, dent1->dname)); } else if ((S_ISREG(dent1->st.st_mode) && dent2->is_dir) || (S_ISDIR(dent1->st.st_mode) && !dent2->is_dir)) { *add = g_list_prepend (*add, concat_sub_path(dir_path, dent1->dname)); *del = g_list_prepend (*del, concat_sub_path(dir_path, dent1->dname)); } p1 = p1->next; p2 = p2->next; } else if (rc < 0) { *add = g_list_prepend (*add, concat_sub_path(dir_path, dent1->dname)); p1 = p1->next; } else { *del = g_list_prepend (*del, concat_sub_path(dir_path, dent2->dname)); p2 = p2->next; } } while (p1) { dent1 = p1->data; *add = g_list_prepend (*add, concat_sub_path(dir_path, dent1->dname)); p1 = p1->next; } while (p2) { dent2 = p2->data; *del = g_list_prepend (*del, concat_sub_path(dir_path, dent2->dname)); p2 = p2->next; } g_free (full_dir_path); g_list_free_full (wt_dents, (GDestroyNotify)wt_dirent_free); g_list_free_full (index_dents, (GDestroyNotify)index_dirent_free); return 0; } #endif /* __APPLE__ */ static void update_active_file (SeafRepo *repo, const char *path, SeafStat *st, struct index_state *istate, gboolean ignored) { if (ignored) { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFREG, SYNC_STATUS_IGNORED); } else { SyncStatus status; gboolean is_writable; struct cache_entry *ce = index_name_exists(istate, path, strlen(path), 0); if (!ce || ie_match_stat(ce, st, 0) != 0) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; is_writable = is_path_writable (repo->id, repo->is_readonly, path); if (!is_writable && status == SYNC_STATUS_SYNCING) seaf_sync_manager_delete_active_path (seaf->sync_mgr, repo->id, path); else seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFREG, status); } } #ifdef WIN32 typedef struct _UpdatePathData { SeafRepo *repo; struct index_state *istate; GList *ignore_list; const char *parent; const char *full_parent; gboolean ignored; } UpdatePathData; static void update_active_path_recursive (SeafRepo *repo, const char *path, struct index_state *istate, GList *ignore_list, gboolean ignored); static int update_active_path_cb (wchar_t *full_parent_w, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { UpdatePathData *upd_data = user_data; char *dname; char *path; gboolean ignored = FALSE; SeafStat st; dname = g_utf16_to_utf8 (fdata->cFileName, -1, NULL, NULL, NULL); path = g_build_path ("/", upd_data->parent, dname, NULL); if (upd_data->ignored || should_ignore (upd_data->full_parent, dname, upd_data->ignore_list)) ignored = TRUE; seaf_stat_from_find_data (fdata, &st); if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { update_active_path_recursive (upd_data->repo, path, upd_data->istate, upd_data->ignore_list, ignored); } else { update_active_file (upd_data->repo, path, &st, upd_data->istate, ignored); } g_free (dname); g_free (path); return 0; } static void update_active_path_recursive (SeafRepo *repo, const char *path, struct index_state *istate, GList *ignore_list, gboolean ignored) { char *full_path; wchar_t *full_path_w; int ret = 0; UpdatePathData upd_data; full_path = g_build_filename (repo->worktree, path, NULL); memset (&upd_data, 0, sizeof(upd_data)); upd_data.repo = repo; upd_data.istate = istate; upd_data.ignore_list = ignore_list; upd_data.parent = path; upd_data.full_parent = full_path; upd_data.ignored = ignored; full_path_w = win32_long_path (full_path); ret = traverse_directory_win32 (full_path_w, update_active_path_cb, &upd_data); g_free (full_path_w); g_free (full_path); if (ret < 0) return; /* Don't set sync status for read-only paths, since changes to read-only * files are ignored. */ if (!is_path_writable (repo->id, repo->is_readonly, path)) return; /* traverse_directory_win32() returns number of entries in the directory. */ if (ret == 0 && path[0] != 0) { if (ignored) { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFDIR, SYNC_STATUS_IGNORED); } else { /* There is no need to update an empty dir. */ SyncStatus status; struct cache_entry *ce = index_name_exists(istate, path, strlen(path), 0); if (!ce) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFDIR, status); } } } #else static void update_active_path_recursive (SeafRepo *repo, const char *path, struct index_state *istate, GList *ignore_list, gboolean ignored) { GDir *dir; GError *error = NULL; const char *name; char *dname; char *full_path, *full_sub_path, *sub_path; struct stat st; gboolean ignore_sub; full_path = g_build_filename(repo->worktree, path, NULL); dir = g_dir_open (full_path, 0, &error); if (!dir) { seaf_warning ("Failed to open dir %s: %s.\n", full_path, error->message); g_free (full_path); return; } int n = 0; while ((name = g_dir_read_name(dir)) != NULL) { ++n; dname = g_utf8_normalize (name, -1, G_NORMALIZE_NFC); sub_path = g_strconcat (path, "/", dname, NULL); full_sub_path = g_strconcat (full_path, "/", dname, NULL); ignore_sub = FALSE; if (ignored || should_ignore(full_path, dname, ignore_list)) ignore_sub = TRUE; if (stat (full_sub_path, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_sub_path, strerror(errno)); g_free (dname); g_free (sub_path); g_free (full_sub_path); continue; } if (S_ISDIR(st.st_mode)) { update_active_path_recursive (repo, sub_path, istate, ignore_list, ignore_sub); } else if (S_ISREG(st.st_mode)) { update_active_file (repo, sub_path, &st, istate, ignore_sub); } g_free (dname); g_free (sub_path); g_free (full_sub_path); } g_dir_close (dir); g_free (full_path); /* Don't set sync status for read-only paths, since changes to read-only * files are ignored. */ if (!is_path_writable (repo->id, repo->is_readonly, path)) return; if (n == 0 && path[0] != 0) { if (ignored) { seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFDIR, SYNC_STATUS_IGNORED); } else { /* There is no need to update an empty dir. */ SyncStatus status; struct cache_entry *ce = index_name_exists(istate, path, strlen(path), 0); if (!ce) status = SYNC_STATUS_SYNCING; else status = SYNC_STATUS_SYNCED; seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFDIR, status); } } } #endif /* WIN32 */ static void process_active_path (SeafRepo *repo, const char *path, struct index_state *istate, GList *ignore_list) { SeafStat st; gboolean ignored = FALSE; char *fullpath = g_build_filename (repo->worktree, path, NULL); if (seaf_stat (fullpath, &st) < 0) { g_free (fullpath); return; } if (check_full_path_ignore (repo->worktree, path, ignore_list)) ignored = TRUE; if (S_ISREG(st.st_mode)) { if (!seaf_filelock_manager_is_file_locked(seaf->filelock_mgr, repo->id, path)) { update_active_file (repo, path, &st, istate, ignored); } } else { update_active_path_recursive (repo, path, istate, ignore_list, ignored); } g_free (fullpath); } #ifdef __APPLE__ static void process_active_folder (SeafRepo *repo, const char *dir, struct index_state *istate, GList *ignore_list) { GList *add = NULL, *mod = NULL, *del = NULL; GList *p; char *path; /* Delete event will be triggered on the deleted dir too. */ if (!g_file_test (dir, G_FILE_TEST_IS_DIR)) return; if (get_changed_paths_in_folder (repo, istate, dir, &add, &mod, &del) < 0) { seaf_warning ("Failed to get changed paths under %s.\n", dir); return; } for (p = add; p; p = p->next) { path = p->data; process_active_path (repo, path, istate, ignore_list); } for (p = mod; p; p = p->next) { path = p->data; process_active_path (repo, path, istate, ignore_list); } g_list_free_full (add, g_free); g_list_free_full (mod, g_free); g_list_free_full (del, g_free); } #endif /* __APPLE__ */ static void update_path_sync_status (SeafRepo *repo, WTStatus *status, struct index_state *istate, GList *ignore_list) { char *path; while (1) { pthread_mutex_lock (&status->ap_q_lock); path = g_queue_pop_head (status->active_paths); pthread_mutex_unlock (&status->ap_q_lock); if (!path) break; #ifdef __APPLE__ process_active_folder (repo, path, istate, ignore_list); #else process_active_path (repo, path, istate, ignore_list); #endif g_free (path); } } /* Excel first writes update to a temporary file and then rename the file to * xlsx. Unfortunately the temp file dosen't have specific pattern. * We can only ignore renaming from non xlsx file to xlsx file. */ static gboolean ignore_xlsx_update (const char *src_path, const char *dst_path) { GPatternSpec *pattern = g_pattern_spec_new ("*.xlsx"); int ret = FALSE; if (!g_pattern_match_string(pattern, src_path) && g_pattern_match_string(pattern, dst_path)) ret = TRUE; g_pattern_spec_free (pattern); return ret; } static gboolean is_seafile_backup_file (const char *path) { GPatternSpec *pattern = g_pattern_spec_new ("*.sbak"); int ret = FALSE; if (g_pattern_match_string(pattern, path)) ret = TRUE; g_pattern_spec_free (pattern); return ret; } static void handle_rename (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, GList *ignore_list, LockedFileSet *fset, WTEvent *event, GList **scanned_del_dirs, gint64 *total_size) { gboolean not_found, src_ignored, dst_ignored; seaf_sync_manager_delete_active_path (seaf->sync_mgr, repo->id, event->path); if (!is_path_writable(repo->id, repo->is_readonly, event->path) || !is_path_writable(repo->id, repo->is_readonly, event->new_path)) { seaf_debug ("Rename: %s or %s is not writable, ignore.\n", event->path, event->new_path); return; } if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo->id, event->path)) { seaf_debug ("Rename: %s is locked on server, ignore.\n", event->path); /* send_sync_error_notification (repo->id, NULL, event->path, */ /* SYNC_ERROR_ID_FILE_LOCKED); */ return; } if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo->id, event->new_path)) { seaf_debug ("Rename: %s is locked on server, ignore.\n", event->new_path); /* send_sync_error_notification (repo->id, NULL, event->new_path, */ /* SYNC_ERROR_ID_FILE_LOCKED); */ return; } src_ignored = check_full_path_ignore(repo->worktree, event->path, ignore_list); dst_ignored = check_full_path_ignore(repo->worktree, event->new_path, ignore_list); /* If the destination path is ignored, just remove the source path. */ if (dst_ignored) { if (!src_ignored && !is_seafile_backup_file (event->new_path) && check_locked_file_before_remove (fset, event->path)) { not_found = FALSE; remove_from_index_with_prefix (istate, event->path, ¬_found); if (not_found) scan_subtree_for_deletion (repo->id, istate, repo->worktree, event->path, ignore_list, fset, repo->is_readonly, scanned_del_dirs, repo->changeset); remove_from_changeset (repo->changeset, DIFF_STATUS_DELETED, event->path, FALSE, NULL, FALSE); } return; } /* Now the destination path is not ignored. */ if (!src_ignored && !ignore_xlsx_update (event->path, event->new_path) && check_locked_file_before_remove (fset, event->path)) { not_found = FALSE; rename_index_entries (istate, event->path, event->new_path, ¬_found, NULL, NULL); if (not_found) scan_subtree_for_deletion (repo->id, istate, repo->worktree, event->path, ignore_list, fset, repo->is_readonly, scanned_del_dirs, repo->changeset); /* Moving files out of a dir may make it empty. */ try_add_empty_parent_dir_entry_from_wt (repo->worktree, istate, ignore_list, event->path); add_to_changeset (repo->changeset, DIFF_STATUS_RENAMED, NULL, NULL, NULL, event->path, event->new_path); } AddOptions options; memset (&options, 0, sizeof(options)); options.fset = fset; options.is_repo_ro = repo->is_readonly; options.changeset = repo->changeset; /* We should always scan the destination to compare with the renamed * index entries. For example, in the following case: * 1. file a.txt is updated; * 2. a.txt is moved to test/a.txt; * If the two operations are executed in a batch, the updated content * of a.txt won't be committed if we don't scan the destination, because * when we process the update event, a.txt is already not in its original * place. */ add_recursive (repo->id, repo->version, repo->email, istate, repo->worktree, event->new_path, crypt, FALSE, ignore_list, total_size, NULL, &options); } #ifdef WIN32 typedef struct FindOfficeData { const char *lock_file_name; char *office_file_name; } FindOfficeData; static int find_office_file_cb (wchar_t *parent, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { FindOfficeData *data = user_data; const wchar_t *dname_w = fdata->cFileName; wchar_t *lock_name_w = NULL; if (wcslen(dname_w) < 2) return 0; if (wcsncmp (dname_w, L"~$", 2) == 0) return 0; lock_name_w = g_utf8_to_utf16 (data->lock_file_name, -1, NULL, NULL, NULL); /* Skip "~$" at the beginning. */ if (wcscmp (dname_w + 2, lock_name_w) == 0) { data->office_file_name = g_utf16_to_utf8 (dname_w, -1, NULL, NULL, NULL); *stop = TRUE; } g_free (lock_name_w); return 0; } static gboolean find_office_file_path (const char *worktree, const char *parent_dir, const char *lock_file_name, char **office_path) { char *fullpath = NULL; wchar_t *fullpath_w = NULL; FindOfficeData data; gboolean ret = FALSE; fullpath = g_build_path ("/", worktree, parent_dir, NULL); fullpath_w = win32_long_path (fullpath); data.lock_file_name = lock_file_name; data.office_file_name = NULL; if (traverse_directory_win32 (fullpath_w, find_office_file_cb, &data) < 0) { goto out; } if (data.office_file_name != NULL) { *office_path = g_build_path ("/", parent_dir, data.office_file_name, NULL); ret = TRUE; } out: g_free (fullpath); g_free (fullpath_w); return ret; } static gboolean is_office_lock_file (const char *worktree, const char *path, char **office_path) { gboolean ret; if (!g_regex_match (office_lock_pattern, path, 0, NULL)) return FALSE; /* Replace ~$abc.docx with abc.docx */ *office_path = g_regex_replace (office_lock_pattern, path, -1, 0, "\\1", 0, NULL); /* When the filename is long, sometimes the first two characters in the filename will be directly replaced with ~$. So if the office_path file doesn't exist, we have to match against all filenames in this directory, to find the office file's name. */ char *fullpath = g_build_path ("/", worktree, *office_path, NULL); if (seaf_util_exists (fullpath)) { g_free (fullpath); return TRUE; } g_free (fullpath); char *lock_file_name = g_path_get_basename(*office_path); char *parent_dir = g_path_get_dirname(*office_path); if (strcmp(parent_dir, ".") == 0) { g_free (parent_dir); parent_dir = g_strdup(""); } g_free (*office_path); *office_path = NULL; ret = find_office_file_path (worktree, parent_dir, lock_file_name, office_path); g_free (lock_file_name); g_free (parent_dir); return ret; } typedef struct LockOfficeJob { char repo_id[37]; char *path; gboolean lock; /* False if unlock */ } LockOfficeJob; static void lock_office_job_free (LockOfficeJob *job) { if (!job) return; g_free (job->path); g_free (job); } static void do_lock_office_file (LockOfficeJob *job) { SeafRepo *repo; char *fullpath = NULL; SeafStat st; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, job->repo_id); if (!repo) return; fullpath = g_build_path ("/", repo->worktree, job->path, NULL); if (seaf_stat (fullpath, &st) < 0 || !S_ISREG(st.st_mode)) { g_free (fullpath); return; } g_free (fullpath); int status = seaf_filelock_manager_get_lock_status (seaf->filelock_mgr, repo->id, job->path); if (status != FILE_NOT_LOCKED) { return; } if (http_tx_manager_lock_file (seaf->http_tx_mgr, repo->effective_host, repo->use_fileserver_port, repo->token, repo->id, job->path) < 0) { seaf_warning ("Failed to lock %s in repo %.8s on server.\n", job->path, repo->id); return; } /* Mark file as locked locally so that the user can see the effect immediately. */ seaf_filelock_manager_mark_file_locked (seaf->filelock_mgr, repo->id, job->path, TRUE); } static void do_unlock_office_file (LockOfficeJob *job) { SeafRepo *repo; char *fullpath = NULL; SeafStat st; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, job->repo_id); if (!repo) return; fullpath = g_build_path ("/", repo->worktree, job->path, NULL); if (seaf_stat (fullpath, &st) < 0 || !S_ISREG(st.st_mode)) { g_free (fullpath); return; } g_free (fullpath); int status = seaf_filelock_manager_get_lock_status (seaf->filelock_mgr, repo->id, job->path); if (status != FILE_LOCKED_BY_ME_AUTO) { return; } if (http_tx_manager_unlock_file (seaf->http_tx_mgr, repo->effective_host, repo->use_fileserver_port, repo->token, repo->id, job->path) < 0) { seaf_warning ("Failed to unlock %s in repo %.8s on server.\n", job->path, repo->id); return; } /* Mark file as unlocked locally so that the user can see the effect immediately. */ seaf_filelock_manager_mark_file_unlocked (seaf->filelock_mgr, repo->id, job->path); } #if 0 static void unlock_closed_office_files () { GList *locked_files, *ptr; SeafRepo *repo; FileLockInfo *info; LockOfficeJob *job; locked_files = seaf_filelock_manager_get_auto_locked_files (seaf->filelock_mgr); for (ptr = locked_files; ptr; ptr = ptr->next) { info = ptr->data; seaf_message ("%s %s.\n", info->repo_id, info->path); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, info->repo_id); if (!repo) continue; seaf_message ("1\n"); if (!do_check_file_locked (info->path, repo->worktree, FALSE)) { seaf_message ("2\n"); job = g_new0 (LockOfficeJob, 1); memcpy (job->repo_id, info->repo_id, 36); job->path = g_strdup(info->path); do_unlock_office_file (job); lock_office_job_free (job); } } g_list_free_full (locked_files, (GDestroyNotify)file_lock_info_free); } #endif static void * lock_office_file_worker (void *vdata) { GAsyncQueue *queue = (GAsyncQueue *)vdata; LockOfficeJob *job; /* unlock_closed_office_files (); */ while (1) { job = g_async_queue_pop (queue); if (!job) break; if (job->lock) do_lock_office_file (job); else do_unlock_office_file (job); lock_office_job_free (job); } return NULL; } static void lock_office_file_on_server (SeafRepo *repo, const char *path) { LockOfficeJob *job; GAsyncQueue *queue = seaf->repo_mgr->priv->lock_office_job_queue; if (!seaf_repo_manager_server_is_pro (seaf->repo_mgr, repo->server_url)) return; job = g_new0 (LockOfficeJob, 1); memcpy (job->repo_id, repo->id, 36); job->path = g_strdup(path); job->lock = TRUE; g_async_queue_push (queue, job); } static void unlock_office_file_on_server (SeafRepo *repo, const char *path) { LockOfficeJob *job; GAsyncQueue *queue = seaf->repo_mgr->priv->lock_office_job_queue; if (!seaf_repo_manager_server_is_pro (seaf->repo_mgr, repo->server_url)) return; job = g_new0 (LockOfficeJob, 1); memcpy (job->repo_id, repo->id, 36); job->path = g_strdup(path); job->lock = FALSE; g_async_queue_push (queue, job); } #endif /* WIN32 */ static int apply_worktree_changes_to_index (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, GList *ignore_list, LockedFileSet *fset) { WTStatus *status; WTEvent *event, *next_event; gboolean not_found; #ifdef WIN32 char *office_path = NULL; #endif status = seaf_wt_monitor_get_worktree_status (seaf->wt_monitor, repo->id); if (!status) { seaf_warning ("Can't find worktree status for repo %s(%.8s).\n", repo->name, repo->id); return -1; } update_path_sync_status (repo, status, istate, ignore_list); GList *scanned_dirs = NULL, *scanned_del_dirs = NULL; WTEvent *last_event; pthread_mutex_lock (&status->q_lock); last_event = g_queue_peek_tail (status->event_q); pthread_mutex_unlock (&status->q_lock); if (!last_event) { seaf_message ("All events are processed for repo %s.\n", repo->id); status->partial_commit = FALSE; goto out; } gint64 total_size = 0; while (1) { pthread_mutex_lock (&status->q_lock); event = g_queue_pop_head (status->event_q); next_event = g_queue_peek_head (status->event_q); pthread_mutex_unlock (&status->q_lock); if (!event) break; /* Scanned dirs list is used to avoid redundant scan of consecutive CREATE_OR_UPDATE events. When we see other events, we should clear the list. Otherwise in some cases we'll get wrong result. For example, the following sequence (run with a script): 1. Add a dir with files 2. Delete the dir with files 3. Add back the same dir again. */ if (event->ev_type != WT_EVENT_CREATE_OR_UPDATE) { g_list_free_full (scanned_dirs, g_free); scanned_dirs = NULL; } switch (event->ev_type) { case WT_EVENT_CREATE_OR_UPDATE: /* If consecutive CREATE_OR_UPDATE events present in the event queue, only process the last one. */ if (next_event && next_event->ev_type == event->ev_type && strcmp (next_event->path, event->path) == 0) break; /* CREATE_OR_UPDATE event tells us the exact path of changed file/dir. * If the event path is not writable, we don't need to check the paths * under the event path. */ if (!is_path_writable(repo->id, repo->is_readonly, event->path)) { seaf_debug ("%s is not writable, ignore.\n", event->path); break; } #ifdef WIN32 office_path = NULL; if (is_office_lock_file (repo->worktree, event->path, &office_path)) lock_office_file_on_server (repo, office_path); g_free (office_path); #endif if (handle_add_files (repo, istate, crypt, ignore_list, fset, status, event, &scanned_dirs, &total_size)) goto out; break; case WT_EVENT_SCAN_DIR: if (handle_add_files (repo, istate, crypt, ignore_list, fset, status, event, &scanned_dirs, &total_size)) goto out; break; case WT_EVENT_DELETE: seaf_sync_manager_delete_active_path (seaf->sync_mgr, repo->id, event->path); #ifdef WIN32 office_path = NULL; if (is_office_lock_file (repo->worktree, event->path, &office_path)) unlock_office_file_on_server (repo, office_path); g_free (office_path); #endif if (check_full_path_ignore(repo->worktree, event->path, ignore_list)) break; if (!is_path_writable(repo->id, repo->is_readonly, event->path)) { seaf_debug ("%s is not writable, ignore.\n", event->path); break; } if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo->id, event->path)) { seaf_debug ("Delete: %s is locked on server, ignore.\n", event->path); /* send_sync_error_notification (repo->id, NULL, event->path, */ /* SYNC_ERROR_ID_FILE_LOCKED); */ break; } if (check_locked_file_before_remove (fset, event->path)) { not_found = FALSE; remove_from_index_with_prefix (istate, event->path, ¬_found); if (not_found) scan_subtree_for_deletion (repo->id, istate, repo->worktree, event->path, ignore_list, fset, repo->is_readonly, &scanned_del_dirs, repo->changeset); remove_from_changeset (repo->changeset, DIFF_STATUS_DELETED, event->path, FALSE, NULL, TRUE); try_add_empty_parent_dir_entry_from_wt (repo->worktree, istate, ignore_list, event->path); } break; case WT_EVENT_RENAME: handle_rename (repo, istate, crypt, ignore_list, fset, event, &scanned_del_dirs, &total_size); break; case WT_EVENT_ATTRIB: if (!is_path_writable(repo->id, repo->is_readonly, event->path)) { seaf_debug ("%s is not writable, ignore.\n", event->path); break; } update_attributes (repo, istate, repo->worktree, event->path); break; case WT_EVENT_OVERFLOW: seaf_warning ("Kernel event queue overflowed, fall back to scan.\n"); scan_worktree_for_changes (istate, repo, crypt, ignore_list, fset); break; } if (event == last_event) { wt_event_free (event); seaf_message ("All events are processed for repo %s.\n", repo->id); status->partial_commit = FALSE; break; } else wt_event_free (event); } out: wt_status_unref (status); string_list_free (scanned_dirs); string_list_free (scanned_del_dirs); return 0; } static void handle_unmerged_index_entries (SeafRepo *repo, struct index_state *istate, SeafileCrypt *crypt, GList *ignore_list) { struct cache_entry **ce_array = istate->cache; struct cache_entry *ce; char path[SEAF_PATH_MAX]; unsigned int i; SeafStat st; int ret; GList *unmerged_paths = NULL; char *last_name = ""; retry: for (i = 0; i < istate->cache_nr; ++i) { ce = ce_array[i]; if (ce_stage(ce) == 0) continue; snprintf (path, SEAF_PATH_MAX, "%s/%s", repo->worktree, ce->name); ret = seaf_stat (path, &st); if (S_ISDIR (ce->ce_mode)) { if (ret < 0 || !S_ISDIR (st.st_mode) || !is_empty_dir (path, ignore_list)) ce->ce_flags |= CE_REMOVE; else if (strcmp (ce->name, last_name) != 0) { unmerged_paths = g_list_append (unmerged_paths, g_strdup(ce->name)); last_name = ce->name; } } else { if (ret < 0 || !S_ISREG (st.st_mode)) ce->ce_flags |= CE_REMOVE; else if (strcmp (ce->name, last_name) != 0) { unmerged_paths = g_list_append (unmerged_paths, g_strdup(ce->name)); last_name = ce->name; } } } remove_marked_cache_entries (istate); GList *ptr; char *ce_name; for (ptr = unmerged_paths; ptr; ptr = ptr->next) { ce_name = ptr->data; snprintf (path, SEAF_PATH_MAX, "%s/%s", repo->worktree, ce_name); ret = seaf_stat (path, &st); if (ret < 0) { seaf_warning ("Failed to stat %s: %s.\n", path, strerror(errno)); string_list_free (unmerged_paths); unmerged_paths = NULL; goto retry; } if (S_ISDIR (st.st_mode)) { if (is_empty_dir (path, ignore_list)) add_empty_dir_to_index (istate, ce_name, &st); } else { gboolean added; add_to_index (repo->id, repo->version, istate, ce_name, path, &st, 0, crypt, index_cb, repo->email, &added); } } string_list_free (unmerged_paths); } static int index_add (SeafRepo *repo, struct index_state *istate, gboolean is_force_commit, gboolean handle_unmerged) { SeafileCrypt *crypt = NULL; LockedFileSet *fset = NULL; GList *ignore_list = NULL; int ret = 0; if (repo->encrypted) { crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } #ifdef WIN32 if (repo->version > 0) fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo->id); #endif ignore_list = seaf_repo_load_ignore_files (repo->worktree); if (!is_force_commit) { if (apply_worktree_changes_to_index (repo, istate, crypt, ignore_list, fset) < 0) { seaf_warning ("Failed to apply worktree changes to index.\n"); ret = -1; } } else if (scan_worktree_for_changes (istate, repo, crypt, ignore_list, fset) < 0) { seaf_warning ("Failed to scan worktree for changes.\n"); ret = -1; } /* If the index contains unmerged entries, check and remove those entries * in the end, in cases where they were not completely handled in * apply_worktree_changes_to_index(). */ if (handle_unmerged) handle_unmerged_index_entries (repo, istate, crypt, ignore_list); seaf_repo_free_ignore_files (ignore_list); #ifdef WIN32 locked_file_set_free (fset); #endif g_free (crypt); return ret; } /* * Add the files in @worktree to index and return the corresponding * @root_id. The repo doesn't have to exist. */ int seaf_repo_index_worktree_files (const char *repo_id, int repo_version, const char *modifier, const char *worktree, const char *passwd, int enc_version, const char *random_key, char *root_id) { char index_path[SEAF_PATH_MAX]; struct index_state istate; unsigned char key[32], iv[16]; SeafileCrypt *crypt = NULL; struct cache_tree *it = NULL; GList *ignore_list = NULL; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", seaf->repo_mgr->index_dir, repo_id); /* Remove existing index. An existing index signifies an interrupted * clone-merge. Removing it assures that new blocks from the worktree * get added into the repo again (they're deleted by GC). */ seaf_util_unlink (index_path); if (read_index_from (&istate, index_path, repo_version) < 0) { seaf_warning ("Failed to load index.\n"); return -1; } if (passwd != NULL) { if (seafile_decrypt_repo_enc_key (enc_version, passwd, random_key, key, iv) < 0) { seaf_warning ("Failed to generate enc key for repo %s.\n", repo_id); goto error; } crypt = seafile_crypt_new (enc_version, key, iv); } ignore_list = seaf_repo_load_ignore_files(worktree); /* Add empty dir to index. Otherwise if the repo on relay contains an empty * dir, we'll fail to detect fast-forward relationship later. */ if (add_recursive (repo_id, repo_version, modifier, &istate, worktree, "", crypt, FALSE, ignore_list, NULL, NULL, NULL) < 0) goto error; remove_deleted (&istate, worktree, "", ignore_list, NULL, repo_id, FALSE, NULL); it = cache_tree (); if (cache_tree_update (repo_id, repo_version, worktree, it, istate.cache, istate.cache_nr, 0, 0, commit_trees_cb) < 0) { seaf_warning ("Failed to build cache tree"); goto error; } rawdata_to_hex (it->sha1, root_id, 20); if (update_index (&istate, index_path) < 0) goto error; discard_index (&istate); g_free (crypt); if (it) cache_tree_free (&it); seaf_repo_free_ignore_files(ignore_list); return 0; error: discard_index (&istate); g_free (crypt); if (it) cache_tree_free (&it); seaf_repo_free_ignore_files(ignore_list); return -1; } gboolean seaf_repo_is_worktree_changed (SeafRepo *repo) { SeafRepoManager *mgr = repo->manager; GList *res = NULL, *p; struct index_state istate; char index_path[SEAF_PATH_MAX]; DiffEntry *de; int pos; struct cache_entry *ce; SeafStat sb; char *full_path; if (!check_worktree_common (repo)) return FALSE; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { repo->index_corrupted = TRUE; seaf_warning ("Failed to load index.\n"); goto error; } repo->index_corrupted = FALSE; wt_status_collect_changes_worktree (&istate, &res, repo->worktree); if (res != NULL) goto changed; wt_status_collect_untracked (&istate, &res, repo->worktree, should_ignore); if (res != NULL) goto changed; wt_status_collect_changes_index (&istate, &res, repo); if (res != NULL) goto changed; discard_index (&istate); repo->wt_changed = FALSE; /* g_debug ("%s worktree is changed\n", repo->id); */ return FALSE; changed: g_message ("Worktree changes (at most 5 files are shown):\n"); int i = 0; for (p = res; p != NULL && i < 5; p = p->next, ++i) { de = p->data; full_path = g_build_path ("/", repo->worktree, de->name, NULL); if (seaf_stat (full_path, &sb) < 0) { seaf_warning ("Failed to stat %s: %s.\n", full_path, strerror(errno)); g_free (full_path); continue; } g_free (full_path); pos = index_name_pos (&istate, de->name, strlen(de->name)); if (pos < 0) { seaf_warning ("Cannot find diff entry %s in index.\n", de->name); continue; } ce = istate.cache[pos]; g_message ("type: %c, status: %c, name: %s, " "ce mtime: %"G_GINT64_FORMAT", ce size: %" G_GUINT64_FORMAT ", " "file mtime: %d, file size: %" G_GUINT64_FORMAT "\n", de->type, de->status, de->name, ce->ce_mtime.sec, ce->ce_size, (int)sb.st_mtime, sb.st_size); } for (p = res; p; p = p->next) { de = p->data; diff_entry_free (de); } g_list_free (res); discard_index (&istate); repo->wt_changed = TRUE; /* g_debug ("%s worktree is changed\n", repo->id); */ return TRUE; error: return FALSE; } gboolean seaf_repo_is_index_unmerged (SeafRepo *repo) { SeafRepoManager *mgr = repo->manager; struct index_state istate; char index_path[SEAF_PATH_MAX]; gboolean ret = FALSE; if (!repo->head) return FALSE; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); return FALSE; } if (unmerged_index (&istate)) ret = TRUE; discard_index (&istate); return ret; } static int commit_tree (SeafRepo *repo, const char *root_id, const char *desc, char commit_id[], gboolean unmerged) { SeafCommit *commit; commit = seaf_commit_new (NULL, repo->id, root_id, repo->email ? repo->email : seaf->session->base.user_name, seaf->session->base.id, desc, 0); commit->parent_id = g_strdup (repo->head->commit_id); /* Add this computer's name to commit. */ commit->device_name = g_strdup(seaf->client_name); commit->client_version = g_strdup (SEAFILE_CLIENT_VERSION); if (unmerged) { SeafRepoMergeInfo minfo; /* Don't use head commit of master branch since that branch may have * been updated after the last merge. */ memset (&minfo, 0, sizeof(minfo)); if (seaf_repo_manager_get_merge_info (repo->manager, repo->id, &minfo) < 0) { seaf_warning ("Failed to get merge info of repo %.10s.\n", repo->id); return -1; } commit->second_parent_id = g_strdup (minfo.remote_head); commit->new_merge = TRUE; commit->conflict = TRUE; } seaf_repo_to_commit (repo, commit); if (seaf_commit_manager_add_commit (seaf->commit_mgr, commit) < 0) return -1; seaf_branch_set_commit (repo->head, commit->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, repo->head); strcpy (commit_id, commit->commit_id); seaf_commit_unref (commit); return 0; } static gboolean need_handle_unmerged_index (SeafRepo *repo, struct index_state *istate) { if (!unmerged_index (istate)) return FALSE; /* Syncing with an existing directory may require a real merge. * If the merge produced conflicts, the index will be unmerged. * But we don't want to generate a merge commit in this case. * An "index" branch should exist in this case. */ if (seaf_branch_manager_branch_exists (seaf->branch_mgr, repo->id, "index")) return FALSE; return TRUE; } static gboolean compare_index_changeset (struct index_state *istate, ChangeSet *changeset) { struct cache_entry *ce; int i; gboolean ret = TRUE; for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; if (!(ce->ce_flags & CE_ADDED)) continue; seaf_message ("checking %s in changeset.\n", ce->name); if (!changeset_check_path (changeset, ce->name, ce->sha1, ce->ce_mode, ce->ce_mtime.sec)) ret = FALSE; } return ret; } #if 0 static int print_index (struct index_state *istate) { int i; struct cache_entry *ce; char id[41]; seaf_message ("Totally %u entries in index, version %u.\n", istate->cache_nr, istate->version); for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; rawdata_to_hex (ce->sha1, id, 20); seaf_message ("%s, %s, %o, %"G_GINT64_FORMAT", %s, %"G_GINT64_FORMAT", %d\n", ce->name, id, ce->ce_mode, ce->ce_mtime.sec, ce->modifier, ce->ce_size, ce_stage(ce)); } return 0; } #endif char * seaf_repo_index_commit (SeafRepo *repo, const char *desc, gboolean is_force_commit, gboolean is_initial_commit, GError **error) { SeafRepoManager *mgr = repo->manager; struct index_state istate; char index_path[SEAF_PATH_MAX]; SeafCommit *head = NULL; char *new_root_id = NULL; char commit_id[41]; gboolean unmerged = FALSE; ChangeSet *changeset = NULL; char *my_desc = NULL; char *ret = NULL; if (!check_worktree_common (repo)) return NULL; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal data structure error"); return NULL; } if (need_handle_unmerged_index (repo, &istate)) unmerged = TRUE; changeset = changeset_new (repo->id); if (!changeset) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal data structure error"); goto out; } repo->changeset = changeset; if (index_add (repo, &istate, is_force_commit, unmerged) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to add"); goto out; } if (!istate.cache_changed) goto out; my_desc = diff_results_to_description (changeset->diff); if (!my_desc) my_desc = g_strdup(""); if (!is_initial_commit && !is_force_commit) { new_root_id = commit_tree_from_changeset (changeset); if (!new_root_id) { seaf_warning ("Create commit tree failed for repo %s\n", repo->id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Failed to generate commit"); goto out; } } else { char hex[41]; struct cache_tree *it = cache_tree (); if (cache_tree_update (repo->id, repo->version, repo->worktree, it, istate.cache, istate.cache_nr, 0, 0, commit_trees_cb) < 0) { seaf_warning ("Failed to build cache tree"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal data structure error"); cache_tree_free (&it); goto out; } rawdata_to_hex (it->sha1, hex, 20); new_root_id = g_strdup(hex); cache_tree_free (&it); } head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { seaf_warning ("Head commit %s for repo %s not found\n", repo->head->commit_id, repo->id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Data corrupt"); goto out; } if (strcmp (head->root_id, new_root_id) == 0) { seaf_message ("No change to the fs tree of repo %s\n", repo->id); /* If no file modification and addition are missing, and the new root * id is the same as the old one, skip commiting. */ if (!is_initial_commit && !is_force_commit) compare_index_changeset (&istate, changeset); update_index (&istate, index_path); goto out; } if (commit_tree (repo, new_root_id, my_desc, commit_id, unmerged) < 0) { seaf_warning ("Failed to save commit file"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal error"); goto out; } if (update_index (&istate, index_path) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_INTERNAL, "Internal error"); goto out; } g_signal_emit_by_name (seaf, "repo-committed", repo); ret = g_strdup(commit_id); out: g_free (my_desc); seaf_commit_unref (head); g_free (new_root_id); changeset_free (changeset); discard_index (&istate); return ret; } #ifdef DEBUG_UNPACK_TREES static void print_unpack_result (struct index_state *result) { int i; struct cache_entry *ce; for (i = 0; i < result->cache_nr; ++i) { ce = result->cache[i]; printf ("%s\t", ce->name); if (ce->ce_flags & CE_UPDATE) printf ("update/add\n"); else if (ce->ce_flags & CE_WT_REMOVE) printf ("remove\n"); else printf ("unchange\n"); } } static int print_index (struct index_state *istate) { printf ("Index timestamp: %d\n", istate->timestamp.sec); int i; struct cache_entry *ce; char id[41]; printf ("Totally %u entries in index.\n", istate->cache_nr); for (i = 0; i < istate->cache_nr; ++i) { ce = istate->cache[i]; rawdata_to_hex (ce->sha1, id, 20); printf ("%s\t%s\t%o\t%d\t%d\n", ce->name, id, ce->ce_mode, ce->ce_ctime.sec, ce->ce_mtime.sec); } return 0; } #endif /* DEBUG_UNPACK_TREES */ int seaf_repo_checkout_commit (SeafRepo *repo, SeafCommit *commit, gboolean recover_merge, char **error) { SeafRepoManager *mgr = repo->manager; char index_path[SEAF_PATH_MAX]; struct tree_desc trees[2]; struct unpack_trees_options topts; struct index_state istate; gboolean initial_checkout; GString *err_msgs; int ret = 0; memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); return -1; } repo->index_corrupted = FALSE; initial_checkout = is_index_unborn(&istate); if (!initial_checkout) { if (!repo->head) { /* TODO: Set error string*/ seaf_warning ("Repo corrupt: Index exists but head branch is not set\n"); return -1; } SeafCommit *head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { seaf_warning ("Failed to get commit %s:%s.\n", repo->id, repo->head->commit_id); discard_index (&istate); return -1; } fill_tree_descriptor (repo->id, repo->version, &trees[0], head->root_id); seaf_commit_unref (head); } else { fill_tree_descriptor (repo->id, repo->version, &trees[0], NULL); } fill_tree_descriptor (repo->id, repo->version, &trees[1], commit->root_id); /* 2-way merge to the new branch */ memset(&topts, 0, sizeof(topts)); memcpy (topts.repo_id, repo->id, 36); topts.version = repo->version; topts.base = repo->worktree; topts.head_idx = -1; topts.src_index = &istate; /* topts.dst_index = &istate; */ topts.initial_checkout = initial_checkout; topts.update = 1; topts.merge = 1; topts.gently = 0; topts.verbose_update = 0; /* topts.debug_unpack = 1; */ topts.fn = twoway_merge; if (repo->encrypted) { topts.crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } if (unpack_trees (2, trees, &topts) < 0) { seaf_warning ("Failed to merge commit %s with work tree.\n", commit->commit_id); ret = -1; goto out; } #ifdef WIN32 if (!initial_checkout && !recover_merge && files_locked_on_windows(&topts.result, repo->worktree)) { g_debug ("[checkout] files are locked, quit checkout now.\n"); ret = -1; goto out; } #endif int *finished_entries = NULL; CheckoutTask *c_task = seaf_repo_manager_get_checkout_task (repo->manager, repo->id); if (c_task) { finished_entries = &c_task->finished_files; } if (update_worktree (&topts, recover_merge, initial_checkout ? NULL : commit->commit_id, commit->creator_name, finished_entries) < 0) { seaf_warning ("Failed to update worktree.\n"); /* Still finish checkout even have I/O errors. */ } discard_index (&istate); istate = topts.result; if (update_index (&istate, index_path) < 0) { seaf_warning ("Failed to update index.\n"); ret = -1; goto out; } out: err_msgs = g_string_new (""); get_unpack_trees_error_msgs (&topts, err_msgs, OPR_CHECKOUT); *error = g_string_free (err_msgs, FALSE); tree_desc_free (&trees[0]); tree_desc_free (&trees[1]); g_free (topts.crypt); discard_index (&istate); return ret; } /** * Checkout the content of "local" branch to /repo-name. * The worktree will be set to this place too. */ int seaf_repo_checkout (SeafRepo *repo, const char *worktree, char **error) { const char *commit_id; SeafBranch *branch; SeafCommit *commit; GString *err_msgs; /* remove original index */ char index_path[SEAF_PATH_MAX]; snprintf (index_path, SEAF_PATH_MAX, "%s/%s", repo->manager->index_dir, repo->id); seaf_util_unlink (index_path); branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!branch) { seaf_warning ("[repo-mgr] Checkout repo failed: local branch does not exists\n"); *error = g_strdup ("Repo's local branch does not exists."); goto error; } commit_id = branch->commit_id; commit = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, commit_id); if (!commit) { err_msgs = g_string_new (""); g_string_append_printf (err_msgs, "Commit %s does not exist.\n", commit_id); seaf_warning ("%s", err_msgs->str); *error = g_string_free (err_msgs, FALSE); seaf_branch_unref (branch); goto error; } if (strcmp(repo->id, commit->repo_id) != 0) { err_msgs = g_string_new (""); g_string_append_printf (err_msgs, "Commit %s is not in Repo %s.\n", commit_id, repo->id); seaf_warning ("%s", err_msgs->str); *error = g_string_free (err_msgs, FALSE); seaf_commit_unref (commit); if (branch) seaf_branch_unref (branch); goto error; } CheckoutTask *task = seaf_repo_manager_get_checkout_task (seaf->repo_mgr, repo->id); if (!task) { seaf_warning ("No checkout task found for repo %.10s.\n", repo->id); goto error; } task->total_files = seaf_fs_manager_count_fs_files (seaf->fs_mgr, repo->id, repo->version, commit->root_id); if (task->total_files < 0) { seaf_warning ("Failed to count files for repo %.10s .\n", repo->id); goto error; } if (seaf_repo_checkout_commit (repo, commit, FALSE, error) < 0) { seaf_commit_unref (commit); if (branch) seaf_branch_unref (branch); goto error; } seaf_branch_unref (branch); seaf_commit_unref (commit); return 0; error: return -1; } int seaf_repo_merge (SeafRepo *repo, const char *branch, char **error, int *merge_status) { SeafBranch *remote_branch; int ret = 0; if (!check_worktree_common (repo)) return -1; remote_branch = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, branch); if (!remote_branch) { *error = g_strdup("Invalid remote branch.\n"); goto error; } if (g_strcmp0 (remote_branch->repo_id, repo->id) != 0) { *error = g_strdup ("Remote branch is not in this repository.\n"); seaf_branch_unref (remote_branch); goto error; } ret = merge_branches (repo, remote_branch, error, merge_status); seaf_branch_unref (remote_branch); return ret; error: return -1; } GList * seaf_repo_diff (SeafRepo *repo, const char *old, const char *new, int fold_dir_diff, char **error) { SeafCommit *c1 = NULL, *c2 = NULL; int ret = 0; GList *diff_entries = NULL; c2 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, new); if (!c2) { *error = g_strdup("Can't find new commit"); return NULL; } if (old == NULL || old[0] == '\0') { if (c2->parent_id && c2->second_parent_id) { ret = diff_merge (c2, &diff_entries, fold_dir_diff); seaf_commit_unref (c2); if (ret < 0) { *error = g_strdup("Failed to do diff"); g_list_free_full (diff_entries, (GDestroyNotify)diff_entry_free); return NULL; } return diff_entries; } if (!c2->parent_id) { seaf_commit_unref (c2); return NULL; } c1 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, c2->parent_id); } else { c1 = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, old); } if (!c1) { *error = g_strdup("Can't find old commit"); seaf_commit_unref (c2); return NULL; } /* do diff */ ret = diff_commits (c1, c2, &diff_entries, fold_dir_diff); if (ret < 0) { g_list_free_full (diff_entries, (GDestroyNotify)diff_entry_free); diff_entries = NULL; *error = g_strdup("Failed to do diff"); } seaf_commit_unref (c1); seaf_commit_unref (c2); return diff_entries; } int checkout_file (const char *repo_id, int repo_version, const char *worktree, const char *name, const char *file_id, gint64 mtime, unsigned int mode, SeafileCrypt *crypt, struct cache_entry *ce, TransferTask *task, HttpTxTask *http_task, gboolean is_http, const char *conflict_head_id, GHashTable *conflict_hash, GHashTable *no_conflict_hash, gboolean download_only) { char *path; SeafStat st, st2; unsigned char sha1[20]; gboolean path_exists = FALSE; gboolean case_conflict = FALSE; gboolean force_conflict = FALSE; gboolean update_mode_only = FALSE; path = build_checkout_path (worktree, name, strlen(name)); if (!path) return FETCH_CHECKOUT_FAILED; hex_to_rawdata (file_id, sha1, 20); path_exists = (seaf_stat (path, &st) == 0); if (path_exists && S_ISREG(st.st_mode)) { if (st.st_mtime == ce->ce_mtime.sec) { /* Worktree and index are consistent. */ if (memcmp (sha1, ce->sha1, 20) == 0) { if (mode == ce->ce_mode) { /* Worktree and index are all uptodate, no need to checkout. * This may happen after an interrupted checkout. */ seaf_debug ("wt and index are consistent. no need to checkout.\n"); goto update_cache; } else update_mode_only = TRUE; } /* otherwise we have to checkout the file. */ } else { if (compare_file_content (path, &st, sha1, crypt, repo_version) == 0) { /* This happens after the worktree file was updated, * but the index was not. Just need to update the index. */ seaf_debug ("update index only.\n"); goto update_cache; } else { /* Conflict. The worktree file was updated by the user. */ seaf_message ("File %s is updated by user. " "Will checkout to conflict file later.\n", path); force_conflict = TRUE; } } } if (update_mode_only) { #ifdef WIN32 g_free (path); return FETCH_CHECKOUT_SUCCESS; #else chmod (path, mode & ~S_IFMT); ce->ce_mode = mode; g_free (path); return FETCH_CHECKOUT_SUCCESS; #endif } /* Download the blocks of this file. */ int rc; if (!is_http) { rc = seaf_transfer_manager_download_file_blocks (seaf->transfer_mgr, task, file_id); switch (rc) { case BLOCK_CLIENT_SUCCESS: break; case BLOCK_CLIENT_UNKNOWN: case BLOCK_CLIENT_FAILED: case BLOCK_CLIENT_NET_ERROR: case BLOCK_CLIENT_SERVER_ERROR: g_free (path); return FETCH_CHECKOUT_TRANSFER_ERROR; case BLOCK_CLIENT_CANCELED: g_free (path); return FETCH_CHECKOUT_CANCELED; } } else { rc = http_tx_task_download_file_blocks (http_task, file_id); if (http_task->state == HTTP_TASK_STATE_CANCELED) { g_free (path); return FETCH_CHECKOUT_CANCELED; } if (rc < 0) { g_free (path); return FETCH_CHECKOUT_TRANSFER_ERROR; } } if (download_only) { g_free (path); return FETCH_CHECKOUT_SUCCESS; } /* The worktree file may have been changed when we're downloading the blocks. */ if (path_exists && S_ISREG(st.st_mode) && !force_conflict) { seaf_stat (path, &st2); if (st.st_mtime != st2.st_mtime) { seaf_message ("File %s is updated by user. " "Will checkout to conflict file later.\n", path); force_conflict = TRUE; } } /* Temporarily unlock the file if it's locked on server, so that the client * itself can write to it. */ if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, name)) seaf_filelock_manager_unlock_wt_file (seaf->filelock_mgr, repo_id, name); /* then checkout the file. */ gboolean conflicted = FALSE; if (seaf_fs_manager_checkout_file (seaf->fs_mgr, repo_id, repo_version, file_id, path, mode, mtime, crypt, name, conflict_head_id, force_conflict, &conflicted, is_http ? http_task->email : task->email) < 0) { seaf_warning ("Failed to checkout file %s.\n", path); g_free (path); if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, name)) seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo_id, name); return FETCH_CHECKOUT_FAILED; } if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, name)) seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo_id, name); /* If case conflict, this file has been checked out to another path. * Remove the current entry, otherwise it won't be removed later * since it's timestamp is 0. */ if (case_conflict) { ce->ce_flags |= CE_REMOVE; g_free (path); return FETCH_CHECKOUT_SUCCESS; } update_cache: /* finally fill cache_entry info */ /* Only update index if we checked out the file without any error * or conflicts. The timestamp of the entry will remain 0 if error * or conflicted. */ seaf_stat (path, &st); fill_stat_cache_info (ce, &st); g_free (path); return FETCH_CHECKOUT_SUCCESS; } int checkout_empty_dir (const char *worktree, const char *name, gint64 mtime, struct cache_entry *ce, GHashTable *conflict_hash, GHashTable *no_conflict_hash) { char *path; gboolean case_conflict = FALSE; path = build_checkout_path (worktree, name, strlen(name)); if (!path) return FETCH_CHECKOUT_FAILED; if (!seaf_util_exists (path) && seaf_util_mkdir (path, 0777) < 0) { seaf_warning ("Failed to create empty dir %s in checkout.\n", path); g_free (path); return FETCH_CHECKOUT_FAILED; } if (mtime != 0 && seaf_set_file_time (path, mtime) < 0) { seaf_warning ("Failed to set mtime for %s.\n", path); } if (case_conflict) { ce->ce_flags |= CE_REMOVE; g_free (path); return FETCH_CHECKOUT_SUCCESS; } SeafStat st; seaf_stat (path, &st); fill_stat_cache_info (ce, &st); g_free (path); return FETCH_CHECKOUT_SUCCESS; } static struct cache_entry * cache_entry_from_diff_entry (DiffEntry *de) { int size, namelen; struct cache_entry *ce; namelen = strlen(de->name); size = cache_entry_size(namelen); ce = calloc(1, size); memcpy(ce->name, de->name, namelen); ce->ce_flags = namelen; memcpy (ce->sha1, de->sha1, 20); ce->modifier = g_strdup(de->modifier); ce->ce_size = de->size; ce->ce_mtime.sec = de->mtime; if (S_ISREG(de->mode)) ce->ce_mode = create_ce_mode (de->mode); else ce->ce_mode = S_IFDIR; return ce; } static void cleanup_file_blocks (const char *repo_id, int version, const char *file_id) { Seafile *file; int i; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo_id, version, file_id); if (!file) { seaf_warning ("Failed to load seafile object %s:%s\n", repo_id, file_id); return; } for (i = 0; i < file->n_blocks; ++i) seaf_block_manager_remove_block (seaf->block_mgr, repo_id, version, file->blk_sha1s[i]); seafile_unref (file); } #define UPDATE_CACHE_SIZE_LIMIT 100 * (1 << 20) /* 100MB */ static int download_files_no_http (const char *repo_id, int repo_version, const char *worktree, struct index_state *istate, const char *index_path, SeafileCrypt *crypt, TransferTask *task, GList *results, GHashTable *conflict_hash, GHashTable *no_conflict_hash, const char *remote_head_id, LockedFileSet *fset) { GList *ptr; struct cache_entry *ce; DiffEntry *de; gint64 checkout_size = 0; int rc; gboolean is_clone = task->is_clone; int ret = FETCH_CHECKOUT_SUCCESS; for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_ADDED || de->status == DIFF_STATUS_MODIFIED) { seaf_debug ("Checkout file %s.\n", de->name); gboolean add_ce = FALSE; gboolean is_locked = FALSE; char file_id[41]; rawdata_to_hex (de->sha1, file_id, 20); ce = index_name_exists (istate, de->name, strlen(de->name), 0); if (!ce) { ce = cache_entry_from_diff_entry (de); add_ce = TRUE; } if (!should_ignore_on_checkout (de->name, NULL)) { #ifdef WIN32 is_locked = do_check_file_locked (de->name, worktree, FALSE); #endif if (!is_clone) seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, de->name, de->mode, SYNC_STATUS_SYNCING); rc = checkout_file (repo_id, repo_version, worktree, de->name, file_id, de->mtime, de->mode, crypt, ce, task, NULL, FALSE, remote_head_id, conflict_hash, no_conflict_hash, is_locked); /* Even if the file failed to check out, still need to update index. * But we have to stop after transfer errors. */ if (rc == FETCH_CHECKOUT_CANCELED) { seaf_debug ("Transfer canceled.\n"); ret = FETCH_CHECKOUT_CANCELED; if (add_ce) cache_entry_free (ce); return ret; } else if (rc == FETCH_CHECKOUT_TRANSFER_ERROR) { seaf_warning ("Transfer failed.\n"); ret = FETCH_CHECKOUT_TRANSFER_ERROR; if (add_ce) cache_entry_free (ce); return ret; } if (!is_locked) { cleanup_file_blocks (repo_id, repo_version, file_id); } else { #ifdef WIN32 locked_file_set_add_update (fset, de->name, LOCKED_OP_UPDATE, ce->ce_mtime.sec, file_id); /* Stay in syncing status if the file is locked. */ #endif } } ++(task->n_downloaded); if (add_ce) { if (!(ce->ce_flags & CE_REMOVE)) { add_index_entry (istate, ce, (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)); } } else { ce->ce_mtime.sec = de->mtime; ce->ce_size = de->size; memcpy (ce->sha1, de->sha1, 20); if (ce->modifier) g_free (ce->modifier); ce->modifier = g_strdup(de->modifier); ce->ce_mode = create_ce_mode (de->mode); } /* Save index file to disk after checking out some size of files. * This way we don't need to re-compare too many files if this * checkout is interrupted. */ checkout_size += ce->ce_size; if (checkout_size >= UPDATE_CACHE_SIZE_LIMIT) { seaf_debug ("Save index file.\n"); update_index (istate, index_path); checkout_size = 0; } } else if (de->status == DIFF_STATUS_DIR_ADDED) { seaf_debug ("Checkout empty dir %s.\n", de->name); gboolean add_ce = FALSE; ce = index_name_exists (istate, de->name, strlen(de->name), 0); if (!ce) { ce = cache_entry_from_diff_entry (de); add_ce = TRUE; } checkout_empty_dir (worktree, de->name, de->mtime, ce, conflict_hash, no_conflict_hash); if (add_ce) { if (!(ce->ce_flags & CE_REMOVE)) { add_index_entry (istate, ce, (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)); } } else ce->ce_mtime.sec = de->mtime; } } update_index (istate, index_path); return FETCH_CHECKOUT_SUCCESS; } typedef struct FileTxData { char repo_id[37]; int repo_version; SeafileCrypt *crypt; HttpTxTask *http_task; char conflict_head_id[41]; GAsyncQueue *finished_tasks; } FileTxData; typedef struct FileTxTask { char *path; struct cache_entry *ce; DiffEntry *de; gboolean new_ce; gboolean skip_fetch; int result; gboolean no_checkout; gboolean force_conflict; } FileTxTask; static void file_tx_task_free (FileTxTask *task) { if (!task) return; g_free (task->path); g_free (task); } static int fetch_file_http (FileTxData *data, FileTxTask *file_task) { int repo_version = data->repo_version; struct cache_entry *ce = file_task->ce; DiffEntry *de = file_task->de; SeafileCrypt *crypt = data->crypt; char *path = file_task->path; HttpTxTask *http_task = data->http_task; SeafStat st; char file_id[41]; gboolean path_exists = FALSE; rawdata_to_hex (de->sha1, file_id, 20); path_exists = (seaf_stat (path, &st) == 0); if (path_exists && S_ISREG(st.st_mode)) { if (st.st_mtime == ce->ce_mtime.sec) { /* Worktree and index are consistent. */ if (memcmp (de->sha1, ce->sha1, 20) == 0) { seaf_debug ("wt and index are consistent. no need to checkout.\n"); file_task->no_checkout = TRUE; /* Update mode if necessary. */ if (de->mode != ce->ce_mode) { #ifndef WIN32 chmod (path, de->mode & ~S_IFMT); ce->ce_mode = de->mode; #endif } /* Update mtime if necessary. */ if (de->mtime != ce->ce_mtime.sec) { seaf_set_file_time (path, de->mtime); ce->ce_mtime.sec = de->mtime; } fill_stat_cache_info (ce, &st); return FETCH_CHECKOUT_SUCCESS; } /* otherwise we have to checkout the file. */ } else { if (compare_file_content (path, &st, de->sha1, crypt, repo_version) == 0) { /* This happens after the worktree file was updated, * but the index was not. Just need to update the index. */ seaf_debug ("update index only.\n"); file_task->no_checkout = TRUE; fill_stat_cache_info (ce, &st); return FETCH_CHECKOUT_SUCCESS; } else { /* Conflict. The worktree file was updated by the user. */ seaf_message ("File %s is updated by user. " "Will checkout to conflict file later.\n", path); file_task->force_conflict = TRUE; } } } /* Download the blocks of this file. */ int rc; rc = http_tx_task_download_file_blocks (http_task, file_id); if (http_task->state == HTTP_TASK_STATE_CANCELED) { return FETCH_CHECKOUT_CANCELED; } if (rc < 0) { return FETCH_CHECKOUT_TRANSFER_ERROR; } return FETCH_CHECKOUT_SUCCESS; } static void fetch_file_thread_func (gpointer data, gpointer user_data) { FileTxTask *task = data; FileTxData *tx_data = user_data; GAsyncQueue *finished_tasks = tx_data->finished_tasks; DiffEntry *de = task->de; char *repo_id = tx_data->repo_id; char file_id[41]; gboolean is_clone = tx_data->http_task->is_clone; int rc = FETCH_CHECKOUT_SUCCESS; if (task->skip_fetch) goto out; rawdata_to_hex (de->sha1, file_id, 20); /* seaf_message ("Download file %s for repo %s\n", de->name, repo_id); */ if (!is_clone) seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, de->name, de->mode, SYNC_STATUS_SYNCING); rc = fetch_file_http (tx_data, task); /* Even if the file failed to check out, still need to update index. * But we have to stop after transfer errors. */ if (rc == FETCH_CHECKOUT_CANCELED) { seaf_debug ("Transfer canceled.\n"); } else if (rc == FETCH_CHECKOUT_TRANSFER_ERROR) { seaf_warning ("Transfer failed.\n"); } out: task->result = rc; g_async_queue_push (finished_tasks, task); } static int schedule_file_fetch (GThreadPool *tpool, const char *repo_id, const char *repo_name, const char *worktree, struct index_state *istate, DiffEntry *de, GHashTable *pending_tasks, GHashTable *conflict_hash, GHashTable *no_conflict_hash) { struct cache_entry *ce; gboolean new_ce = FALSE; gboolean skip_fetch = FALSE; char *path = NULL; FileTxTask *file_task; ce = index_name_exists (istate, de->name, strlen(de->name), 0); if (!ce) { ce = cache_entry_from_diff_entry (de); new_ce = TRUE; } IgnoreReason reason; if (should_ignore_on_checkout (de->name, &reason)) { seaf_message ("Path %s is invalid on Windows, skip checkout\n", de->name); if (reason == IGNORE_REASON_END_SPACE_PERIOD) send_sync_error_notification (repo_id, repo_name, de->name, SYNC_ERROR_ID_PATH_END_SPACE_PERIOD); else if (reason == IGNORE_REASON_INVALID_CHARACTER) send_sync_error_notification (repo_id, repo_name, de->name, SYNC_ERROR_ID_PATH_INVALID_CHARACTER); skip_fetch = TRUE; } if (!skip_fetch) { path = build_checkout_path (worktree, de->name, strlen(de->name)); if (!path) { if (new_ce) cache_entry_free (ce); return FETCH_CHECKOUT_FAILED; } } file_task = g_new0 (FileTxTask, 1); file_task->de = de; file_task->ce = ce; file_task->path = path; file_task->new_ce = new_ce; file_task->skip_fetch = skip_fetch; if (!g_hash_table_lookup (pending_tasks, de->name)) { g_hash_table_insert (pending_tasks, g_strdup(de->name), file_task); g_thread_pool_push (tpool, file_task, NULL); } else { file_tx_task_free (file_task); } return FETCH_CHECKOUT_SUCCESS; } static void cleanup_file_blocks_http (HttpTxTask *task, const char *file_id) { Seafile *file; int i; char *block_id; int *pcnt; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file_id); if (!file) { seaf_warning ("Failed to load seafile object %s:%s\n", task->repo_id, file_id); return; } for (i = 0; i < file->n_blocks; ++i) { block_id = file->blk_sha1s[i]; pthread_mutex_lock (&task->ref_cnt_lock); pcnt = g_hash_table_lookup (task->blk_ref_cnts, block_id); if (pcnt) { --(*pcnt); if (*pcnt > 0) { pthread_mutex_unlock (&task->ref_cnt_lock); continue; } } seaf_block_manager_remove_block (seaf->block_mgr, task->repo_id, task->repo_version, block_id); g_hash_table_remove (task->blk_ref_cnts, block_id); pthread_mutex_unlock (&task->ref_cnt_lock); } seafile_unref (file); } static gboolean check_path_conflict (const char *path, char **orig_path) { gboolean is_conflict = FALSE; GError *error = NULL; is_conflict = g_regex_match (conflict_pattern, path, 0, NULL); if (is_conflict) { *orig_path = g_regex_replace_literal (conflict_pattern, path, -1, 0, "", 0, &error); if (!*orig_path) is_conflict = FALSE; } return is_conflict; } static int checkout_file_http (FileTxData *data, FileTxTask *file_task, const char *worktree, GHashTable *conflict_hash, GHashTable *no_conflict_hash, const char *conflict_head_id, LockedFileSet *fset) { char *repo_id = data->repo_id; int repo_version = data->repo_version; struct cache_entry *ce = file_task->ce; DiffEntry *de = file_task->de; SeafileCrypt *crypt = data->crypt; gboolean no_checkout = file_task->no_checkout; gboolean force_conflict = file_task->force_conflict; HttpTxTask *http_task = data->http_task; gboolean path_exists; gboolean case_conflict = FALSE; SeafStat st; char file_id[41]; gboolean locked_on_server = FALSE; if (no_checkout) return FETCH_CHECKOUT_SUCCESS; if (should_ignore_on_checkout (de->name, NULL)) return FETCH_CHECKOUT_SUCCESS; rawdata_to_hex (de->sha1, file_id, 20); locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, de->name); #ifdef WIN32 if (do_check_file_locked (de->name, worktree, locked_on_server)) { if (!locked_file_set_lookup (fset, de->name)) send_sync_error_notification (repo_id, NULL, de->name, SYNC_ERROR_ID_FILE_LOCKED_BY_APP); locked_file_set_add_update (fset, de->name, LOCKED_OP_UPDATE, ce->ce_mtime.sec, file_id); /* Stay in syncing status if the file is locked. */ return FETCH_CHECKOUT_SUCCESS; } #endif path_exists = (seaf_stat (file_task->path, &st) == 0); /* The worktree file may have been changed when we're downloading the blocks. */ if (!file_task->new_ce && path_exists && S_ISREG(st.st_mode) && !force_conflict) { if (st.st_mtime != ce->ce_mtime.sec) { seaf_message ("File %s is updated by user. " "Will checkout to conflict file later.\n", file_task->path); force_conflict = TRUE; } } /* Temporarily unlock the file if it's locked on server, so that the client * itself can write to it. */ if (locked_on_server) seaf_filelock_manager_unlock_wt_file (seaf->filelock_mgr, repo_id, de->name); /* then checkout the file. */ gboolean conflicted = FALSE; if (seaf_fs_manager_checkout_file (seaf->fs_mgr, repo_id, repo_version, file_id, file_task->path, de->mode, de->mtime, crypt, de->name, conflict_head_id, force_conflict, &conflicted, http_task->email) < 0) { seaf_warning ("Failed to checkout file %s.\n", file_task->path); if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, de->name)) seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo_id, de->name); return FETCH_CHECKOUT_FAILED; } if (locked_on_server) seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo_id, de->name); cleanup_file_blocks_http (http_task, file_id); if (conflicted) { http_tx_manager_notify_conflict (http_task, de->name); } else if (!http_task->is_clone) { char *orig_path = NULL; if (check_path_conflict (de->name, &orig_path)) http_tx_manager_notify_conflict (http_task, orig_path); g_free (orig_path); } /* If case conflict, this file will be checked out to another path. * Remove the current entry, otherwise it won't be removed later * since it's timestamp is 0. */ if (case_conflict) ce->ce_flags |= CE_REMOVE; /* finally fill cache_entry info */ /* Only update index if we checked out the file without any error * or conflicts. The ctime of the entry will remain 0 if error. */ seaf_stat (file_task->path, &st); fill_stat_cache_info (ce, &st); return FETCH_CHECKOUT_SUCCESS; } static void handle_dir_added_de (const char *repo_id, const char *repo_name, const char *worktree, struct index_state *istate, DiffEntry *de, GHashTable *conflict_hash, GHashTable *no_conflict_hash) { seaf_debug ("Checkout empty dir %s.\n", de->name); struct cache_entry *ce; gboolean add_ce = FALSE; ce = index_name_exists (istate, de->name, strlen(de->name), 0); if (!ce) { ce = cache_entry_from_diff_entry (de); add_ce = TRUE; } IgnoreReason reason; if (should_ignore_on_checkout (de->name, &reason)) { seaf_message ("Path %s is invalid on Windows, skip checkout\n", de->name); if (reason == IGNORE_REASON_END_SPACE_PERIOD) send_sync_error_notification (repo_id, repo_name, de->name, SYNC_ERROR_ID_PATH_END_SPACE_PERIOD); else if (reason == IGNORE_REASON_INVALID_CHARACTER) send_sync_error_notification (repo_id, repo_name, de->name, SYNC_ERROR_ID_PATH_INVALID_CHARACTER); goto update_index; } checkout_empty_dir (worktree, de->name, de->mtime, ce, conflict_hash, no_conflict_hash); seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, de->name, de->mode, SYNC_STATUS_SYNCED); update_index: if (add_ce) { if (!(ce->ce_flags & CE_REMOVE)) { add_index_entry (istate, ce, (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)); } } else ce->ce_mtime.sec = de->mtime; } #define DEFAULT_DOWNLOAD_THREADS 3 static int download_files_http (const char *repo_id, int repo_version, const char *worktree, struct index_state *istate, const char *index_path, SeafileCrypt *crypt, HttpTxTask *http_task, GList *results, GHashTable *conflict_hash, GHashTable *no_conflict_hash, const char *conflict_head_id, LockedFileSet *fset) { struct cache_entry *ce; DiffEntry *de; gint64 checkout_size = 0; GThreadPool *tpool; GAsyncQueue *finished_tasks; GHashTable *pending_tasks; GList *ptr; FileTxTask *task; int ret = FETCH_CHECKOUT_SUCCESS; finished_tasks = g_async_queue_new (); FileTxData data; memset (&data, 0, sizeof(data)); memcpy (data.repo_id, repo_id, 36); data.repo_version = repo_version; data.crypt = crypt; data.http_task = http_task; memcpy (data.conflict_head_id, conflict_head_id, 40); data.finished_tasks = finished_tasks; tpool = g_thread_pool_new (fetch_file_thread_func, &data, DEFAULT_DOWNLOAD_THREADS, FALSE, NULL); pending_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)file_tx_task_free); for (ptr = results; ptr != NULL; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_DIR_ADDED) { handle_dir_added_de (repo_id, http_task->repo_name, worktree, istate, de, conflict_hash, no_conflict_hash); } else if (de->status == DIFF_STATUS_ADDED || de->status == DIFF_STATUS_MODIFIED) { if (FETCH_CHECKOUT_FAILED == schedule_file_fetch (tpool, repo_id, http_task->repo_name, worktree, istate, de, pending_tasks, conflict_hash, no_conflict_hash)) continue; } } /* If there is no file need to be downloaded, return immediately. */ if (g_hash_table_size(pending_tasks) == 0) { if (results != NULL) update_index (istate, index_path); goto out; } char file_id[41]; while ((task = g_async_queue_pop (finished_tasks)) != NULL) { ce = task->ce; de = task->de; rawdata_to_hex (de->sha1, file_id, 20); /* seaf_message ("Finished downloading file %s for repo %s\n", */ /* de->name, repo_id); */ if (task->result == FETCH_CHECKOUT_CANCELED || task->result == FETCH_CHECKOUT_TRANSFER_ERROR) { ret = task->result; if (task->new_ce) cache_entry_free (task->ce); http_task->all_stop = TRUE; goto out; } int rc = checkout_file_http (&data, task, worktree, conflict_hash, no_conflict_hash, conflict_head_id, fset); if (!http_task->is_clone) { SyncStatus status; if (rc == FETCH_CHECKOUT_FAILED) status = SYNC_STATUS_ERROR; else status = SYNC_STATUS_SYNCED; seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, de->name, de->mode, status); } ++(http_task->done_files); if (task->new_ce) { if (!(ce->ce_flags & CE_REMOVE)) { add_index_entry (istate, task->ce, (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE)); } } else { ce->ce_mtime.sec = de->mtime; ce->ce_size = de->size; memcpy (ce->sha1, de->sha1, 20); if (ce->modifier) g_free (ce->modifier); ce->modifier = g_strdup(de->modifier); ce->ce_mode = create_ce_mode (de->mode); } g_hash_table_remove (pending_tasks, de->name); if (g_hash_table_size (pending_tasks) == 0) break; /* Save index file to disk after checking out some size of files. * This way we don't need to re-compare too many files if this * checkout is interrupted. */ checkout_size += ce->ce_size; if (checkout_size >= UPDATE_CACHE_SIZE_LIMIT) { update_index (istate, index_path); checkout_size = 0; } } update_index (istate, index_path); out: /* Wait until all threads exit. * This is necessary when the download is canceled or encountered error. */ g_thread_pool_free (tpool, TRUE, TRUE); /* Free all pending file task structs. */ g_hash_table_destroy (pending_tasks); g_async_queue_unref (finished_tasks); return ret; } static gboolean expand_dir_added_cb (SeafFSManager *mgr, const char *path, SeafDirent *dent, void *user_data, gboolean *stop) { GList **expanded = user_data; DiffEntry *de = NULL; unsigned char sha1[20]; hex_to_rawdata (dent->id, sha1, 20); if (S_ISDIR(dent->mode) && strcmp(dent->id, EMPTY_SHA1) == 0) de = diff_entry_new (DIFF_TYPE_COMMITS, DIFF_STATUS_DIR_ADDED, sha1, path); else if (S_ISREG(dent->mode)) de = diff_entry_new (DIFF_TYPE_COMMITS, DIFF_STATUS_ADDED, sha1, path); if (de) { de->mtime = dent->mtime; de->mode = dent->mode; de->modifier = g_strdup(dent->modifier); de->size = dent->size; *expanded = g_list_prepend (*expanded, de); } return TRUE; } /* * Expand DIR_ADDED results into multiple ADDED results. */ static int expand_diff_results (const char *repo_id, int version, const char *remote_root, const char *local_root, GList **results) { GList *ptr, *next; DiffEntry *de; char obj_id[41]; GList *expanded = NULL; ptr = *results; while (ptr) { de = ptr->data; next = ptr->next; if (de->status == DIFF_STATUS_DIR_ADDED) { *results = g_list_delete_link (*results, ptr); rawdata_to_hex (de->sha1, obj_id, 20); if (seaf_fs_manager_traverse_path (seaf->fs_mgr, repo_id, version, remote_root, de->name, expand_dir_added_cb, &expanded) < 0) { diff_entry_free (de); goto error; } diff_entry_free (de); } ptr = next; } expanded = g_list_reverse (expanded); *results = g_list_concat (*results, expanded); return 0; error: g_list_free_full (expanded, (GDestroyNotify)diff_entry_free); return -1; } static int do_rename_in_worktree (DiffEntry *de, const char *worktree, GHashTable *conflict_hash, GHashTable *no_conflict_hash) { char *old_path, *new_path; int ret = 0; old_path = g_build_filename (worktree, de->name, NULL); if (seaf_util_exists (old_path)) { new_path = build_checkout_path (worktree, de->new_name, strlen(de->new_name)); if (!new_path) { ret = -1; goto out; } if (seaf_util_rename (old_path, new_path) < 0) { seaf_warning ("Failed to rename %s to %s: %s.\n", old_path, new_path, strerror(errno)); ret = -1; } g_free (new_path); } out: g_free (old_path); return ret; } static gboolean is_built_in_ignored_file (const char *filename) { GPatternSpec **spec = ignore_patterns; while (*spec) { if (g_pattern_match_string(*spec, filename)) return TRUE; spec++; } if (!seaf->sync_extra_temp_file) { spec = office_temp_ignore_patterns; while (*spec) { if (g_pattern_match_string(*spec, filename)) return TRUE; spec++; } } return FALSE; } #ifdef WIN32 /* * @path: path relative to the worktree, utf-8 encoded * @path_w: absolute path include worktree, utf-16 encoded. * Return 0 when successfully deleted the folder; otherwise -1. */ static int delete_worktree_dir_recursive_win32 (struct index_state *istate, const char *path, const wchar_t *path_w) { struct cache_entry *ce; WIN32_FIND_DATAW fdata; HANDLE handle; wchar_t *pattern; wchar_t *sub_path_w; char *sub_path, *dname; int path_len_w; DWORD error; int ret = 0; guint64 mtime; gboolean builtin_ignored = FALSE; path_len_w = wcslen(path_w); pattern = g_new0 (wchar_t, (path_len_w + 3)); wcscpy (pattern, path_w); wcscat (pattern, L"\\*"); handle = FindFirstFileW (pattern, &fdata); g_free (pattern); if (handle == INVALID_HANDLE_VALUE) { seaf_warning ("FindFirstFile failed %s: %lu.\n", path, GetLastError()); return -1; } do { if (wcscmp (fdata.cFileName, L".") == 0 || wcscmp (fdata.cFileName, L"..") == 0) continue; sub_path_w = g_new0 (wchar_t, path_len_w + wcslen(fdata.cFileName) + 2); wcscpy (sub_path_w, path_w); wcscat (sub_path_w, L"\\"); wcscat (sub_path_w, fdata.cFileName); dname = g_utf16_to_utf8 (fdata.cFileName, -1, NULL, NULL, NULL); sub_path = g_strconcat (path, "/", dname, NULL); builtin_ignored = is_built_in_ignored_file(dname); g_free (dname); if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (delete_worktree_dir_recursive_win32 (istate, sub_path, sub_path_w) < 0) { ret = -1; } } else { /* Files like .DS_Store and Thumbs.db should be deleted any way. */ if (!builtin_ignored) { mtime = (guint64)file_time_to_unix_time (&fdata.ftLastWriteTime); ce = index_name_exists (istate, sub_path, strlen(sub_path), 0); if (!ce || ce->ce_mtime.sec != mtime) { seaf_message ("File %s is changed, skip deleting it.\n", sub_path); g_free (sub_path_w); g_free (sub_path); ret = -1; continue; } } if (!DeleteFileW (sub_path_w)) { error = GetLastError(); seaf_warning ("Failed to delete file %s: %lu.\n", sub_path, error); ret = -1; } } g_free (sub_path_w); g_free (sub_path); } while (FindNextFileW (handle, &fdata) != 0); error = GetLastError(); if (error != ERROR_NO_MORE_FILES) { seaf_warning ("FindNextFile failed %s: %lu.\n", path, error); ret = -1; } FindClose (handle); if (ret < 0) return ret; int n = 0; while (!RemoveDirectoryW (path_w)) { error = GetLastError(); seaf_warning ("Failed to remove dir %s: %lu.\n", path, error); if (error != ERROR_DIR_NOT_EMPTY) { ret = -1; break; } if (++n >= 3) { ret = -1; break; } /* Sleep 100ms and retry. */ g_usleep (100000); seaf_warning ("Retry remove dir %s.\n", path); } return ret; } #else static int delete_worktree_dir_recursive (struct index_state *istate, const char *path, const char *full_path) { GDir *dir; const char *dname; char *dname_nfc; GError *error = NULL; char *sub_path, *full_sub_path; SeafStat st; struct cache_entry *ce; int ret = 0; gboolean builtin_ignored = FALSE; dir = g_dir_open (full_path, 0, &error); if (!dir) { seaf_warning ("Failed to open dir %s: %s.\n", full_path, error->message); return -1; } while ((dname = g_dir_read_name (dir)) != NULL) { dname_nfc = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC); sub_path = g_build_path ("/", path, dname_nfc, NULL); full_sub_path = g_build_path ("/", full_path, dname_nfc, NULL); builtin_ignored = is_built_in_ignored_file (dname_nfc); g_free (dname_nfc); if (lstat (full_sub_path, &st) < 0) { seaf_warning ("Failed to stat %s.\n", full_sub_path); g_free (sub_path); g_free (full_sub_path); ret = -1; continue; } if (S_ISDIR(st.st_mode)) { if (delete_worktree_dir_recursive (istate, sub_path, full_sub_path) < 0) ret = -1; } else { /* Files like .DS_Store and Thumbs.db should be deleted any way. */ if (!builtin_ignored) { ce = index_name_exists (istate, sub_path, strlen(sub_path), 0); if (!ce || ce->ce_mtime.sec != st.st_mtime) { seaf_message ("File %s is changed, skip deleting it.\n", full_sub_path); g_free (sub_path); g_free (full_sub_path); ret = -1; continue; } } /* Delete all other file types. */ if (seaf_util_unlink (full_sub_path) < 0) { seaf_warning ("Failed to delete file %s: %s.\n", full_sub_path, strerror(errno)); ret = -1; } } g_free (sub_path); g_free (full_sub_path); } g_dir_close (dir); if (ret < 0) return ret; if (g_rmdir (full_path) < 0) { seaf_warning ("Failed to delete dir %s: %s.\n", full_path, strerror(errno)); ret = -1; } return ret; } #endif /* WIN32 */ static void delete_worktree_dir (struct index_state *istate, const char *worktree, const char *path) { char *full_path = g_build_path ("/", worktree, path, NULL); #ifdef WIN32 wchar_t *full_path_w = win32_long_path (full_path); delete_worktree_dir_recursive_win32 (istate, path, full_path_w); g_free (full_path_w); #else delete_worktree_dir_recursive(istate, path, full_path); #endif g_free (full_path); } static void update_sync_status (struct cache_entry *ce, void *user_data) { char *repo_id = user_data; seaf_sync_manager_update_active_path (seaf->sync_mgr, repo_id, ce->name, ce->ce_mode, SYNC_STATUS_SYNCED); } #ifdef WIN32 static int convert_rename_to_checkout (const char *repo_id, int repo_version, const char *root_id, DiffEntry *de, GList **entries) { if (de->status == DIFF_STATUS_RENAMED) { char file_id[41]; SeafDirent *dent = NULL; DiffEntry *new_de = NULL; rawdata_to_hex (de->sha1, file_id, 20); dent = seaf_fs_manager_get_dirent_by_path (seaf->fs_mgr, repo_id, repo_version, root_id, de->new_name, NULL); if (!dent) { seaf_warning ("Failed to find %s in repo %s\n", de->new_name, repo_id); return -1; } new_de = diff_entry_new (DIFF_TYPE_COMMITS, DIFF_STATUS_ADDED, de->sha1, de->new_name); if (new_de) { new_de->mtime = dent->mtime; new_de->mode = dent->mode; new_de->modifier = g_strdup(dent->modifier); new_de->size = dent->size; *entries = g_list_prepend (*entries, new_de); } seaf_dirent_free (dent); } else if (de->status == DIFF_STATUS_DIR_RENAMED) { GList *expanded = NULL; if (seaf_fs_manager_traverse_path (seaf->fs_mgr, repo_id, repo_version, root_id, de->new_name, expand_dir_added_cb, &expanded) < 0) { g_list_free_full (expanded, (GDestroyNotify)diff_entry_free); return -1; } *entries = g_list_concat (*entries, expanded); } return 0; } #endif /* WIN32 */ int seaf_repo_fetch_and_checkout (TransferTask *task, HttpTxTask *http_task, gboolean is_http, const char *remote_head_id) { char *repo_id; int repo_version; gboolean is_clone; char *worktree; char *passwd; SeafRepo *repo = NULL; SeafBranch *master = NULL; SeafCommit *remote_head = NULL, *master_head = NULL; char index_path[SEAF_PATH_MAX]; struct index_state istate; int ret = FETCH_CHECKOUT_SUCCESS; GList *results = NULL; SeafileCrypt *crypt = NULL; GHashTable *conflict_hash = NULL, *no_conflict_hash = NULL; GList *ignore_list = NULL; LockedFileSet *fset = NULL; if (is_http) { repo_id = http_task->repo_id; repo_version = http_task->repo_version; is_clone = http_task->is_clone; worktree = http_task->worktree; passwd = http_task->passwd; } else { repo_id = task->repo_id; repo_version = task->repo_version; is_clone = task->is_clone; worktree = task->worktree; passwd = task->passwd; } memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", seaf->repo_mgr->index_dir, repo_id); if (read_index_from (&istate, index_path, repo_version) < 0) { seaf_warning ("Failed to load index.\n"); return FETCH_CHECKOUT_FAILED; } if (!is_clone) { repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("Failed to get repo %.8s.\n", repo_id); goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, repo_id, "master"); if (!master) { seaf_warning ("Failed to get master branch for repo %.8s.\n", repo_id); ret = FETCH_CHECKOUT_FAILED; goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo_version, master->commit_id); if (!master_head) { seaf_warning ("Failed to get master head %s of repo %.8s.\n", repo_id, master->commit_id); ret = FETCH_CHECKOUT_FAILED; goto out; } } if (!is_clone) worktree = repo->worktree; remote_head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo_id, repo_version, remote_head_id); if (!remote_head) { seaf_warning ("Failed to get remote head %s of repo %.8s.\n", repo_id, remote_head_id); ret = FETCH_CHECKOUT_FAILED; goto out; } if (diff_commit_roots (repo_id, repo_version, master_head ? master_head->root_id : EMPTY_SHA1, remote_head->root_id, &results, TRUE) < 0) { seaf_warning ("Failed to diff for repo %.8s.\n", repo_id); ret = FETCH_CHECKOUT_FAILED; goto out; } GList *ptr; DiffEntry *de; /* Expand DIR_ADDED diff entries. */ if (expand_diff_results (repo_id, repo_version, remote_head->root_id, master_head ? master_head->root_id : EMPTY_SHA1, &results) < 0) { ret = FETCH_CHECKOUT_FAILED; goto out; } #ifdef WIN32 for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_DIR_RENAMED || de->status == DIFF_STATUS_DIR_DELETED) { if (do_check_dir_locked (de->name, worktree)) { seaf_message ("File(s) in dir %s are locked by other program, " "skip rename/delete.\n", de->name); send_sync_error_notification (repo_id, NULL, de->name, SYNC_ERROR_ID_FOLDER_LOCKED_BY_APP); ret = FETCH_CHECKOUT_LOCKED; goto out; } } else if (de->status == DIFF_STATUS_RENAMED) { gboolean locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, de->name); if (do_check_file_locked (de->name, worktree, locked_on_server)) { seaf_message ("File %s is locked by other program, skip rename.\n", de->name); send_sync_error_notification (repo_id, NULL, de->name, SYNC_ERROR_ID_FILE_LOCKED_BY_APP); ret = FETCH_CHECKOUT_LOCKED; goto out; } } } #endif if (remote_head->encrypted) { if (!is_clone) { crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); } else { unsigned char enc_key[32], enc_iv[16]; seafile_decrypt_repo_enc_key (remote_head->enc_version, passwd, remote_head->random_key, enc_key, enc_iv); crypt = seafile_crypt_new (remote_head->enc_version, enc_key, enc_iv); } } conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); no_conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ignore_list = seaf_repo_load_ignore_files (worktree); struct cache_entry *ce; #ifdef WIN32 fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo_id); #endif for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_DELETED) { seaf_debug ("Delete file %s.\n", de->name); if (should_ignore_on_checkout (de->name, NULL)) { seaf_message ("Path %s is invalid on Windows, skip delete.\n", de->name); continue; } ce = index_name_exists (&istate, de->name, strlen(de->name), 0); if (!ce) continue; gboolean locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, de->name); if (locked_on_server) seaf_filelock_manager_unlock_wt_file (seaf->filelock_mgr, repo_id, de->name); #ifdef WIN32 if (!do_check_file_locked (de->name, worktree, locked_on_server)) { locked_file_set_remove (fset, de->name, FALSE); delete_path (worktree, de->name, de->mode, ce->ce_mtime.sec); } else { if (is_http && !locked_file_set_lookup (fset, de->name)) send_sync_error_notification (repo_id, http_task->repo_name, de->name, SYNC_ERROR_ID_FILE_LOCKED_BY_APP); locked_file_set_add_update (fset, de->name, LOCKED_OP_DELETE, ce->ce_mtime.sec, NULL); } #else delete_path (worktree, de->name, de->mode, ce->ce_mtime.sec); #endif /* No need to lock wt file again since it's deleted. */ remove_from_index_with_prefix (&istate, de->name, NULL); try_add_empty_parent_dir_entry (worktree, &istate, de->name); } else if (de->status == DIFF_STATUS_DIR_DELETED) { seaf_debug ("Delete dir %s.\n", de->name); if (should_ignore_on_checkout (de->name, NULL)) { seaf_message ("Path %s is invalid on Windows, skip delete.\n", de->name); continue; } /* Nothing to delete. */ if (!master_head || strcmp(master_head->root_id, EMPTY_SHA1) == 0) continue; delete_worktree_dir (&istate, worktree, de->name); /* Remove all index entries under this directory */ remove_from_index_with_prefix (&istate, de->name, NULL); try_add_empty_parent_dir_entry (worktree, &istate, de->name); } } for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_RENAMED || de->status == DIFF_STATUS_DIR_RENAMED) { seaf_debug ("Rename %s to %s.\n", de->name, de->new_name); #ifdef WIN32 IgnoreReason reason; if (should_ignore_on_checkout (de->new_name, &reason)) { seaf_message ("Path %s is invalid on Windows, skip rename.\n", de->new_name); if (is_http) { if (reason == IGNORE_REASON_END_SPACE_PERIOD) send_sync_error_notification (repo_id, http_task->repo_name, de->new_name, SYNC_ERROR_ID_PATH_END_SPACE_PERIOD); else if (reason == IGNORE_REASON_INVALID_CHARACTER) send_sync_error_notification (repo_id, http_task->repo_name, de->new_name, SYNC_ERROR_ID_PATH_INVALID_CHARACTER); } continue; } else if (should_ignore_on_checkout (de->name, NULL)) { /* If the server renames an invalid path to a valid path, * directly checkout the valid path. The checkout will merge * with any existing files. */ convert_rename_to_checkout (repo_id, repo_version, remote_head->root_id, de, &results); continue; } #endif if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, de->name)) seaf_filelock_manager_unlock_wt_file (seaf->filelock_mgr, repo_id, de->name); do_rename_in_worktree (de, worktree, conflict_hash, no_conflict_hash); /* update_sync_status updates the sync status for each renamed path. * The renamed file/folder becomes "synced" immediately after rename. */ if (!is_clone) rename_index_entries (&istate, de->name, de->new_name, NULL, update_sync_status, repo_id); else rename_index_entries (&istate, de->name, de->new_name, NULL, NULL, NULL); /* Moving files out of a dir may make it empty. */ try_add_empty_parent_dir_entry (worktree, &istate, de->name); } } if (istate.cache_changed) update_index (&istate, index_path); for (ptr = results; ptr; ptr = ptr->next) { de = ptr->data; if (de->status == DIFF_STATUS_ADDED || de->status == DIFF_STATUS_MODIFIED) { if (!is_http) ++(task->n_to_download); else ++(http_task->n_files); } } if (is_http) { ret = download_files_http (repo_id, repo_version, worktree, &istate, index_path, crypt, http_task, results, conflict_hash, no_conflict_hash, remote_head_id, fset); } else { ret = download_files_no_http (repo_id, repo_version, worktree, &istate, index_path, crypt, task, results, conflict_hash, no_conflict_hash, remote_head_id, fset); } out: discard_index (&istate); seaf_branch_unref (master); seaf_commit_unref (master_head); seaf_commit_unref (remote_head); g_list_free_full (results, (GDestroyNotify)diff_entry_free); g_free (crypt); if (conflict_hash) g_hash_table_destroy (conflict_hash); if (no_conflict_hash) g_hash_table_destroy (no_conflict_hash); if (ignore_list) seaf_repo_free_ignore_files (ignore_list); #ifdef WIN32 locked_file_set_free (fset); #endif return ret; } int seaf_repo_manager_set_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo, const char *worktree) { if (g_access(worktree, F_OK) != 0) return -1; if (repo->worktree) g_free (repo->worktree); repo->worktree = g_strdup(worktree); if (seaf_repo_manager_set_repo_property (mgr, repo->id, "worktree", repo->worktree) < 0) return -1; repo->worktree_invalid = FALSE; return 0; } void seaf_repo_manager_invalidate_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo) { if (repo->worktree_invalid) return; repo->worktree_invalid = TRUE; if (repo->auto_sync && (repo->sync_interval == 0)) { if (seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id) < 0) { seaf_warning ("failed to unwatch repo %s.\n", repo->id); } } } void seaf_repo_manager_validate_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo) { if (!repo->worktree_invalid) return; repo->worktree_invalid = FALSE; if (repo->auto_sync && (repo->sync_interval == 0)) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s.\n", repo->id); } } } SeafRepoManager* seaf_repo_manager_new (SeafileSession *seaf) { SeafRepoManager *mgr = g_new0 (SeafRepoManager, 1); mgr->priv = g_new0 (SeafRepoManagerPriv, 1); mgr->seaf = seaf; mgr->index_dir = g_build_path (PATH_SEPERATOR, seaf->seaf_dir, INDEX_DIR, NULL); pthread_mutex_init (&mgr->priv->db_lock, NULL); mgr->priv->checkout_tasks_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ignore_patterns = g_new0 (GPatternSpec*, G_N_ELEMENTS(ignore_table)); int i; for (i = 0; ignore_table[i] != NULL; i++) { ignore_patterns[i] = g_pattern_spec_new (ignore_table[i]); } office_temp_ignore_patterns[0] = g_pattern_spec_new("~$*"); /* for files like ~WRL0001.tmp for docx and *.tmp for xlsx and pptx */ office_temp_ignore_patterns[1] = g_pattern_spec_new("*.tmp"); office_temp_ignore_patterns[2] = g_pattern_spec_new(".~lock*#"); office_temp_ignore_patterns[3] = NULL; GError *error = NULL; conflict_pattern = g_regex_new (CONFLICT_PATTERN, 0, 0, &error); if (error) { seaf_warning ("Failed to create regex '%s': %s\n", CONFLICT_PATTERN, error->message); g_clear_error (&error); } office_lock_pattern = g_regex_new (OFFICE_LOCK_PATTERN, 0, 0, &error); if (error) { seaf_warning ("Failed to create regex '%s': %s\n", OFFICE_LOCK_PATTERN, error->message); g_clear_error (&error); } mgr->priv->repo_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); pthread_rwlock_init (&mgr->priv->lock, NULL); mgr->priv->lock_office_job_queue = g_async_queue_new (); return mgr; } int seaf_repo_manager_init (SeafRepoManager *mgr) { if (checkdir_with_mkdir (mgr->index_dir) < 0) { seaf_warning ("Index dir %s does not exist and is unable to create\n", mgr->index_dir); return -1; } mgr->priv->cevent_id = cevent_manager_register (seaf->ev_mgr, (cevent_handler)notify_sync_error, NULL); /* Load all the repos into memory on the client side. */ load_repos (mgr, mgr->seaf->seaf_dir); /* Load folder permissions from db. */ init_folder_perms (mgr); return 0; } static void watch_repos (SeafRepoManager *mgr) { GHashTableIter iter; SeafRepo *repo; gpointer key, value; g_hash_table_iter_init (&iter, mgr->priv->repo_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { repo = value; if (repo->auto_sync && !repo->worktree_invalid && (repo->sync_interval == 0)) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s.\n", repo->id); /* If we fail to add watch at the beginning, sync manager * will periodically check repo status and retry. */ } } } } #define REMOVE_OBJECTS_BATCH 1000 static int remove_store (const char *top_store_dir, const char *store_id, int *count) { char *obj_dir = NULL; GDir *dir1, *dir2; const char *dname1, *dname2; char *path1, *path2; obj_dir = g_build_filename (top_store_dir, store_id, NULL); dir1 = g_dir_open (obj_dir, 0, NULL); if (!dir1) { g_free (obj_dir); return 0; } seaf_message ("Removing store %s\n", obj_dir); while ((dname1 = g_dir_read_name(dir1)) != NULL) { path1 = g_build_filename (obj_dir, dname1, NULL); dir2 = g_dir_open (path1, 0, NULL); if (!dir2) { seaf_warning ("Failed to open obj dir %s.\n", path1); g_dir_close (dir1); g_free (path1); g_free (obj_dir); return -1; } while ((dname2 = g_dir_read_name(dir2)) != NULL) { path2 = g_build_filename (path1, dname2, NULL); g_unlink (path2); /* To prevent using too much IO, only remove 1000 objects per 5 seconds. */ if (++(*count) > REMOVE_OBJECTS_BATCH) { g_usleep (5 * G_USEC_PER_SEC); *count = 0; } g_free (path2); } g_dir_close (dir2); g_rmdir (path1); g_free (path1); } g_dir_close (dir1); g_rmdir (obj_dir); g_free (obj_dir); return 0; } static void cleanup_deleted_stores_by_type (const char *type) { char *top_store_dir; const char *repo_id; top_store_dir = g_build_filename (seaf->seaf_dir, "deleted_store", type, NULL); GError *error = NULL; GDir *dir = g_dir_open (top_store_dir, 0, &error); if (!dir) { seaf_warning ("Failed to open store dir %s: %s.\n", top_store_dir, error->message); g_free (top_store_dir); return; } int count = 0; while ((repo_id = g_dir_read_name(dir)) != NULL) { remove_store (top_store_dir, repo_id, &count); } g_free (top_store_dir); g_dir_close (dir); } static void * cleanup_deleted_stores (void *vdata) { while (1) { cleanup_deleted_stores_by_type ("commits"); cleanup_deleted_stores_by_type ("fs"); cleanup_deleted_stores_by_type ("blocks"); g_usleep (60 * G_USEC_PER_SEC); } return NULL; } int seaf_repo_manager_start (SeafRepoManager *mgr) { pthread_t tid; int rc; watch_repos (mgr); rc = pthread_create (&tid, NULL, cleanup_deleted_stores, NULL); if (rc != 0) { seaf_warning ("Failed to start cleanup thread: %s\n", strerror(rc)); } #ifdef WIN32 rc = pthread_create (&tid, NULL, lock_office_file_worker, mgr->priv->lock_office_job_queue); if (rc != 0) { seaf_warning ("Failed to start lock office file thread: %s\n", strerror(rc)); } #endif return 0; } SeafRepo* seaf_repo_manager_create_new_repo (SeafRepoManager *mgr, const char *name, const char *desc) { SeafRepo *repo; char *repo_id; repo_id = gen_uuid (); repo = seaf_repo_new (repo_id, name, desc); if (!repo) { g_free (repo_id); return NULL; } g_free (repo_id); /* we directly create dir because it shouldn't exist */ /* if (seaf_repo_mkdir (repo, base) < 0) { */ /* seaf_repo_free (repo); */ /* goto out; */ /* } */ seaf_repo_manager_add_repo (mgr, repo); return repo; } int seaf_repo_manager_add_repo (SeafRepoManager *manager, SeafRepo *repo) { char sql[256]; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "REPLACE INTO Repo VALUES ('%s');", repo->id); sqlite_query_exec (db, sql); pthread_mutex_unlock (&manager->priv->db_lock); /* There may be a "deletion record" for this repo when it was deleted * last time. */ seaf_repo_manager_remove_garbage_repo (manager, repo->id); repo->manager = manager; if (pthread_rwlock_wrlock (&manager->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return -1; } g_hash_table_insert (manager->priv->repo_hash, g_strdup(repo->id), repo); pthread_rwlock_unlock (&manager->priv->lock); return 0; } int seaf_repo_manager_mark_repo_deleted (SeafRepoManager *mgr, SeafRepo *repo) { char sql[256]; pthread_mutex_lock (&mgr->priv->db_lock); snprintf (sql, sizeof(sql), "INSERT INTO DeletedRepo VALUES ('%s')", repo->id); if (sqlite_query_exec (mgr->priv->db, sql) < 0) { pthread_mutex_unlock (&mgr->priv->db_lock); return -1; } pthread_mutex_unlock (&mgr->priv->db_lock); repo->delete_pending = TRUE; return 0; } static gboolean get_garbage_repo_id (sqlite3_stmt *stmt, void *vid_list) { GList **ret = vid_list; char *repo_id; repo_id = g_strdup((const char *)sqlite3_column_text (stmt, 0)); *ret = g_list_prepend (*ret, repo_id); return TRUE; } GList * seaf_repo_manager_list_garbage_repos (SeafRepoManager *mgr) { GList *repo_ids = NULL; pthread_mutex_lock (&mgr->priv->db_lock); sqlite_foreach_selected_row (mgr->priv->db, "SELECT repo_id FROM GarbageRepos", get_garbage_repo_id, &repo_ids); pthread_mutex_unlock (&mgr->priv->db_lock); return repo_ids; } void seaf_repo_manager_remove_garbage_repo (SeafRepoManager *mgr, const char *repo_id) { char sql[256]; pthread_mutex_lock (&mgr->priv->db_lock); snprintf (sql, sizeof(sql), "DELETE FROM GarbageRepos WHERE repo_id='%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); } void seaf_repo_manager_remove_repo_ondisk (SeafRepoManager *mgr, const char *repo_id, gboolean add_deleted_record) { char sql[256]; /* We don't need to care about I/O errors here, since we can * GC any unreferenced repo data later. */ if (add_deleted_record) { snprintf (sql, sizeof(sql), "REPLACE INTO GarbageRepos VALUES ('%s')", repo_id); if (sqlite_query_exec (mgr->priv->db, sql) < 0) goto out; } /* Once the item in Repo table is deleted, the repo is gone. * This is the "commit point". */ pthread_mutex_lock (&mgr->priv->db_lock); snprintf (sql, sizeof(sql), "DELETE FROM Repo WHERE repo_id = '%s'", repo_id); if (sqlite_query_exec (mgr->priv->db, sql) < 0) goto out; snprintf (sql, sizeof(sql), "DELETE FROM DeletedRepo WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); /* remove index */ char path[SEAF_PATH_MAX]; snprintf (path, SEAF_PATH_MAX, "%s/%s", mgr->index_dir, repo_id); seaf_util_unlink (path); /* remove branch */ GList *p; GList *branch_list = seaf_branch_manager_get_branch_list (seaf->branch_mgr, repo_id); for (p = branch_list; p; p = p->next) { SeafBranch *b = (SeafBranch *)p->data; seaf_repo_manager_branch_repo_unmap (mgr, b); seaf_branch_manager_del_branch (seaf->branch_mgr, repo_id, b->name); } seaf_branch_list_free (branch_list); /* delete repo property firstly */ seaf_repo_manager_del_repo_property (mgr, repo_id); pthread_mutex_lock (&mgr->priv->db_lock); snprintf (sql, sizeof(sql), "DELETE FROM RepoPasswd WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); snprintf (sql, sizeof(sql), "DELETE FROM RepoKeys WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); snprintf (sql, sizeof(sql), "DELETE FROM MergeInfo WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); #ifdef WIN32 snprintf (sql, sizeof(sql), "DELETE FROM LockedFiles WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); #endif snprintf (sql, sizeof(sql), "DELETE FROM FolderUserPerms WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); snprintf (sql, sizeof(sql), "DELETE FROM FolderGroupPerms WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); snprintf (sql, sizeof(sql), "DELETE FROM FolderPermTimestamp WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); seaf_filelock_manager_remove (seaf->filelock_mgr, repo_id); out: pthread_mutex_unlock (&mgr->priv->db_lock); } static char * gen_deleted_store_path (const char *type, const char *repo_id) { int n = 1; char *path = NULL; char *name = NULL; path = g_build_filename (seaf->deleted_store, type, repo_id, NULL); while (g_access(path, F_OK) == 0 && n < 10) { g_free (path); name = g_strdup_printf ("%s(%d)", repo_id, n); path = g_build_filename (seaf->deleted_store, type, name, NULL); g_free (name); ++n; } if (n == 10) { g_free (path); return NULL; } return path; } void seaf_repo_manager_move_repo_store (SeafRepoManager *mgr, const char *type, const char *repo_id) { char *src = NULL; char *dst = NULL; src = g_build_filename (seaf->seaf_dir, "storage", type, repo_id, NULL); dst = gen_deleted_store_path (type, repo_id); if (dst) { g_rename (src, dst); } g_free (src); g_free (dst); } /* Move commits, fs stores into "deleted_store" directory. */ static void move_repo_stores (SeafRepoManager *mgr, SeafRepo *repo) { seaf_repo_manager_move_repo_store (mgr, "commits", repo->id); seaf_repo_manager_move_repo_store (mgr, "fs", repo->id); } int seaf_repo_manager_del_repo (SeafRepoManager *mgr, SeafRepo *repo) { seaf_repo_manager_remove_repo_ondisk (mgr, repo->id, (repo->version > 0) ? TRUE : FALSE); seaf_sync_manager_remove_active_path_info (seaf->sync_mgr, repo->id); remove_folder_perms (mgr, repo->id); move_repo_stores (mgr, repo); if (pthread_rwlock_wrlock (&mgr->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return -1; } g_hash_table_remove (mgr->priv->repo_hash, repo->id); pthread_rwlock_unlock (&mgr->priv->lock); seaf_repo_free (repo); return 0; } /* Return the internal Repo in hashtable. The caller should not free the returned Repo. */ SeafRepo* seaf_repo_manager_get_repo (SeafRepoManager *manager, const gchar *id) { SeafRepo *res; if (pthread_rwlock_rdlock (&manager->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return NULL; } res = g_hash_table_lookup (manager->priv->repo_hash, id); pthread_rwlock_unlock (&manager->priv->lock); if (res && !res->delete_pending) return res; return NULL; } gboolean seaf_repo_manager_repo_exists (SeafRepoManager *manager, const gchar *id) { SeafRepo *res; if (pthread_rwlock_rdlock (&manager->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return FALSE; } res = g_hash_table_lookup (manager->priv->repo_hash, id); pthread_rwlock_unlock (&manager->priv->lock); if (res && !res->delete_pending) return TRUE; return FALSE; } static int save_branch_repo_map (SeafRepoManager *manager, SeafBranch *branch) { char *sql; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); sql = sqlite3_mprintf ("REPLACE INTO RepoBranch VALUES (%Q, %Q)", branch->repo_id, branch->name); sqlite_query_exec (db, sql); sqlite3_free (sql); pthread_mutex_unlock (&manager->priv->db_lock); return 0; } int seaf_repo_manager_branch_repo_unmap (SeafRepoManager *manager, SeafBranch *branch) { char *sql; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); sql = sqlite3_mprintf ("DELETE FROM RepoBranch WHERE branch_name = %Q" " AND repo_id = %Q", branch->name, branch->repo_id); if (sqlite_query_exec (db, sql) < 0) { seaf_warning ("Unmap branch repo failed\n"); pthread_mutex_unlock (&manager->priv->db_lock); sqlite3_free (sql); return -1; } sqlite3_free (sql); pthread_mutex_unlock (&manager->priv->db_lock); return 0; } static void load_repo_commit (SeafRepoManager *manager, SeafRepo *repo, SeafBranch *branch) { SeafCommit *commit; commit = seaf_commit_manager_get_commit_compatible (manager->seaf->commit_mgr, repo->id, branch->commit_id); if (!commit) { seaf_warning ("Commit %s is missing\n", branch->commit_id); repo->is_corrupted = TRUE; return; } set_head_common (repo, branch); seaf_repo_from_commit (repo, commit); seaf_commit_unref (commit); } static gboolean load_keys_cb (sqlite3_stmt *stmt, void *vrepo) { SeafRepo *repo = vrepo; const char *key, *iv; key = (const char *)sqlite3_column_text(stmt, 0); iv = (const char *)sqlite3_column_text(stmt, 1); if (repo->enc_version == 1) { hex_to_rawdata (key, repo->enc_key, 16); hex_to_rawdata (iv, repo->enc_iv, 16); } else if (repo->enc_version == 2) { hex_to_rawdata (key, repo->enc_key, 32); hex_to_rawdata (iv, repo->enc_iv, 16); } return FALSE; } static int load_repo_passwd (SeafRepoManager *manager, SeafRepo *repo) { sqlite3 *db = manager->priv->db; char sql[256]; int n; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "SELECT key, iv FROM RepoKeys WHERE repo_id='%s'", repo->id); n = sqlite_foreach_selected_row (db, sql, load_keys_cb, repo); if (n < 0) { pthread_mutex_unlock (&manager->priv->db_lock); return -1; } pthread_mutex_unlock (&manager->priv->db_lock); return 0; } static gboolean load_property_cb (sqlite3_stmt *stmt, void *pvalue) { char **value = pvalue; char *v = (char *) sqlite3_column_text (stmt, 0); *value = g_strdup (v); /* Only one result. */ return FALSE; } static char * load_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key) { sqlite3 *db = manager->priv->db; char sql[256]; char *value = NULL; pthread_mutex_lock (&manager->priv->db_lock); snprintf(sql, 256, "SELECT value FROM RepoProperty WHERE " "repo_id='%s' and key='%s'", repo_id, key); if (sqlite_foreach_selected_row (db, sql, load_property_cb, &value) < 0) { seaf_warning ("Error read property %s for repo %s.\n", key, repo_id); pthread_mutex_unlock (&manager->priv->db_lock); return NULL; } pthread_mutex_unlock (&manager->priv->db_lock); return value; } static gboolean load_branch_cb (sqlite3_stmt *stmt, void *vrepo) { SeafRepo *repo = vrepo; SeafRepoManager *manager = repo->manager; char *branch_name = (char *) sqlite3_column_text (stmt, 0); SeafBranch *branch = seaf_branch_manager_get_branch (manager->seaf->branch_mgr, repo->id, branch_name); if (branch == NULL) { seaf_warning ("Broken branch name for repo %s\n", repo->id); repo->is_corrupted = TRUE; return FALSE; } load_repo_commit (manager, repo, branch); seaf_branch_unref (branch); /* Only one result. */ return FALSE; } static gboolean is_wt_repo_name_same (const char *worktree, const char *repo_name) { char *basename = g_path_get_basename (worktree); gboolean ret = FALSE; ret = (strcmp (basename, repo_name) == 0); g_free (basename); return ret; } static SeafRepo * load_repo (SeafRepoManager *manager, const char *repo_id) { char sql[256]; SeafRepo *repo = seaf_repo_new(repo_id, NULL, NULL); if (!repo) { seaf_warning ("[repo mgr] failed to alloc repo.\n"); return NULL; } repo->manager = manager; snprintf(sql, 256, "SELECT branch_name FROM RepoBranch WHERE repo_id='%s'", repo->id); if (sqlite_foreach_selected_row (manager->priv->db, sql, load_branch_cb, repo) < 0) { seaf_warning ("Error read branch for repo %s.\n", repo->id); seaf_repo_free (repo); return NULL; } /* If repo head is set but failed to load branch or commit. */ if (repo->is_corrupted) { seaf_repo_free (repo); /* remove_repo_ondisk (manager, repo_id); */ return NULL; } /* Repo head may be not set if it's just cloned but not checked out yet. */ if (repo->head == NULL) { /* the repo do not have a head branch, try to load 'master' branch */ SeafBranch *branch = seaf_branch_manager_get_branch (manager->seaf->branch_mgr, repo->id, "master"); if (branch != NULL) { SeafCommit *commit; commit = seaf_commit_manager_get_commit_compatible (manager->seaf->commit_mgr, repo->id, branch->commit_id); if (commit) { seaf_repo_from_commit (repo, commit); seaf_commit_unref (commit); } else { seaf_warning ("[repo-mgr] Can not find commit %s\n", branch->commit_id); repo->is_corrupted = TRUE; } seaf_branch_unref (branch); } else { seaf_warning ("[repo-mgr] Failed to get branch master"); repo->is_corrupted = TRUE; } } if (repo->is_corrupted) { seaf_repo_free (repo); /* remove_repo_ondisk (manager, repo_id); */ return NULL; } load_repo_passwd (manager, repo); char *value; value = load_repo_property (manager, repo->id, REPO_AUTO_SYNC); if (g_strcmp0(value, "false") == 0) { repo->auto_sync = 0; } g_free (value); repo->worktree = load_repo_property (manager, repo->id, "worktree"); if (repo->worktree) repo->worktree_invalid = FALSE; repo->relay_id = load_repo_property (manager, repo->id, REPO_RELAY_ID); if (repo->relay_id && strlen(repo->relay_id) != 40) { g_free (repo->relay_id); repo->relay_id = NULL; } repo->email = load_repo_property (manager, repo->id, REPO_PROP_EMAIL); repo->token = load_repo_property (manager, repo->id, REPO_PROP_TOKEN); /* May be NULL if this property is not set in db. */ repo->server_url = load_repo_property (manager, repo->id, REPO_PROP_SERVER_URL); if (repo->head != NULL && seaf_repo_check_worktree (repo) < 0) { if (seafile_session_config_get_allow_invalid_worktree(seaf)) { seaf_warning ("Worktree for repo \"%s\" is invalid, but still keep it.\n", repo->name); repo->worktree_invalid = TRUE; } else { seaf_message ("Worktree for repo \"%s\" is invalid, delete it.\n", repo->name); seaf_repo_manager_del_repo (manager, repo); return NULL; } } /* load readonly property */ value = load_repo_property (manager, repo->id, REPO_PROP_IS_READONLY); if (g_strcmp0(value, "true") == 0) repo->is_readonly = TRUE; else repo->is_readonly = FALSE; g_free (value); /* load sync period property */ value = load_repo_property (manager, repo->id, REPO_PROP_SYNC_INTERVAL); if (value) { int interval = atoi(value); if (interval > 0) repo->sync_interval = interval; } g_free (value); gboolean wt_repo_name_same = is_wt_repo_name_same (repo->worktree, repo->name); value = load_repo_property (manager, repo->id, REPO_SYNC_WORKTREE_NAME); if (g_strcmp0 (value, "true") == 0) { /* If need to sync worktree name with library name, update worktree folder name. */ if (!wt_repo_name_same) update_repo_worktree_name (repo, repo->name, FALSE); } else { /* If an existing repo's worktree folder name is the same as repo name, but * sync_worktree_name property is not set, set it. */ if (wt_repo_name_same) save_repo_property (manager, repo->id, REPO_SYNC_WORKTREE_NAME, "true"); } g_free (value); g_hash_table_insert (manager->priv->repo_hash, g_strdup(repo->id), repo); return repo; } static sqlite3* open_db (SeafRepoManager *manager, const char *seaf_dir) { sqlite3 *db; char *db_path; db_path = g_build_filename (seaf_dir, "repo.db", NULL); if (sqlite_open_db (db_path, &db) < 0) return NULL; g_free (db_path); manager->priv->db = db; char *sql = "CREATE TABLE IF NOT EXISTS Repo (repo_id TEXT PRIMARY KEY);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS DeletedRepo (repo_id TEXT PRIMARY KEY);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoBranch (" "repo_id TEXT PRIMARY KEY, branch_name TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoLanToken (" "repo_id TEXT PRIMARY KEY, token TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoTmpToken (" "repo_id TEXT, peer_id TEXT, token TEXT, timestamp INTEGER, " "PRIMARY KEY (repo_id, peer_id));"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoPasswd " "(repo_id TEXT PRIMARY KEY, passwd TEXT NOT NULL);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoKeys " "(repo_id TEXT PRIMARY KEY, key TEXT NOT NULL, iv TEXT NOT NULL);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS RepoProperty (" "repo_id TEXT, key TEXT, value TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE INDEX IF NOT EXISTS RepoIndex ON RepoProperty (repo_id);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS MergeInfo (" "repo_id TEXT PRIMARY KEY, in_merge INTEGER, branch TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS CommonAncestor (" "repo_id TEXT PRIMARY KEY, ca_id TEXT, head_id TEXT);"; sqlite_query_exec (db, sql); /* Version 1 repos will be added to this table after deletion. * GC will scan this table and remove the objects and blocks for the repos. */ sql = "CREATE TABLE IF NOT EXISTS GarbageRepos (repo_id TEXT PRIMARY KEY);"; sqlite_query_exec (db, sql); #ifdef WIN32 sql = "CREATE TABLE IF NOT EXISTS LockedFiles (repo_id TEXT, path TEXT, " "operation TEXT, old_mtime INTEGER, file_id TEXT, new_path TEXT, " "PRIMARY KEY (repo_id, path));"; sqlite_query_exec (db, sql); #endif sql = "CREATE TABLE IF NOT EXISTS FolderUserPerms (" "repo_id TEXT, path TEXT, permission TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE INDEX IF NOT EXISTS folder_user_perms_repo_id_idx " "ON FolderUserPerms (repo_id);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS FolderGroupPerms (" "repo_id TEXT, path TEXT, permission TEXT);"; sqlite_query_exec (db, sql); sql = "CREATE INDEX IF NOT EXISTS folder_group_perms_repo_id_idx " "ON FolderGroupPerms (repo_id);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS FolderPermTimestamp (" "repo_id TEXT, timestamp INTEGER, PRIMARY KEY (repo_id));"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS ServerProperty (" "server_url TEXT, key TEXT, value TEXT, PRIMARY KEY (server_url, key));"; sqlite_query_exec (db, sql); sql = "CREATE INDEX IF NOT EXISTS ServerIndex ON ServerProperty (server_url);"; sqlite_query_exec (db, sql); sql = "CREATE TABLE IF NOT EXISTS FileSyncError (" "id INTEGER PRIMARY KEY AUTOINCREMENT, repo_id TEXT, repo_name TEXT, " "path TEXT, err_id INTEGER, timestamp INTEGER);"; sqlite_query_exec (db, sql); return db; } static gboolean load_repo_cb (sqlite3_stmt *stmt, void *vmanager) { SeafRepoManager *manager = vmanager; const char *repo_id; repo_id = (const char *) sqlite3_column_text (stmt, 0); load_repo (manager, repo_id); return TRUE; } static gboolean remove_deleted_repo (sqlite3_stmt *stmt, void *vmanager) { SeafRepoManager *manager = vmanager; const char *repo_id; repo_id = (const char *) sqlite3_column_text (stmt, 0); seaf_repo_manager_remove_repo_ondisk (manager, repo_id, TRUE); return TRUE; } static void load_repos (SeafRepoManager *manager, const char *seaf_dir) { sqlite3 *db = open_db(manager, seaf_dir); if (!db) return; char *sql; sql = "SELECT repo_id FROM DeletedRepo"; if (sqlite_foreach_selected_row (db, sql, remove_deleted_repo, manager) < 0) { seaf_warning ("Error removing deleted repos.\n"); return; } sql = "SELECT repo_id FROM Repo;"; if (sqlite_foreach_selected_row (db, sql, load_repo_cb, manager) < 0) { seaf_warning ("Error read repo db.\n"); return; } } static void save_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key, const char *value) { char *sql; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); sql = sqlite3_mprintf ("SELECT repo_id FROM RepoProperty WHERE repo_id=%Q AND key=%Q", repo_id, key); if (sqlite_check_for_existence(db, sql)) { sqlite3_free (sql); sql = sqlite3_mprintf ("UPDATE RepoProperty SET value=%Q" "WHERE repo_id=%Q and key=%Q", value, repo_id, key); sqlite_query_exec (db, sql); sqlite3_free (sql); } else { sqlite3_free (sql); sql = sqlite3_mprintf ("INSERT INTO RepoProperty VALUES (%Q, %Q, %Q)", repo_id, key, value); sqlite_query_exec (db, sql); sqlite3_free (sql); } pthread_mutex_unlock (&manager->priv->db_lock); } int seaf_repo_manager_set_repo_relay_id (SeafRepoManager *mgr, SeafRepo *repo, const char *relay_id) { if (relay_id && strlen(relay_id) != 40) return -1; save_repo_property (mgr, repo->id, REPO_RELAY_ID, relay_id); g_free (repo->relay_id); if (relay_id) repo->relay_id = g_strdup (relay_id); else repo->relay_id = NULL; return 0; } static char * canonical_server_url (const char *url_in) { char *url = g_strdup(url_in); int len = strlen(url); if (url[len - 1] == '/') url[len - 1] = 0; return url; } int seaf_repo_manager_set_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key, const char *value) { SeafRepo *repo; repo = seaf_repo_manager_get_repo (manager, repo_id); if (!repo) return -1; if (strcmp(key, REPO_AUTO_SYNC) == 0) { if (!seaf->started) { seaf_message ("System not started, skip setting auto sync value.\n"); return 0; } if (g_strcmp0(value, "true") == 0) { repo->auto_sync = 1; if (repo->sync_interval == 0) seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree); repo->last_sync_time = 0; } else { repo->auto_sync = 0; if (repo->sync_interval == 0) seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id); /* Cancel current sync task if any. */ seaf_sync_manager_cancel_sync_task (seaf->sync_mgr, repo->id); seaf_sync_manager_remove_active_path_info (seaf->sync_mgr, repo->id); } } if (strcmp(key, REPO_PROP_SYNC_INTERVAL) == 0) { if (!seaf->started) { seaf_message ("System not started, skip setting auto sync value.\n"); return 0; } int interval = atoi(value); if (interval > 0) { repo->sync_interval = interval; if (repo->auto_sync) seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id); } else { repo->sync_interval = 0; if (repo->auto_sync) seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree); } } if (strcmp(key, REPO_RELAY_ID) == 0) return seaf_repo_manager_set_repo_relay_id (manager, repo, value); if (strcmp (key, REPO_PROP_SERVER_URL) == 0) { char *url = canonical_server_url (value); if (!repo->server_url) { /* Called from clone-mgr. */ repo->server_url = url; } else { g_free (repo->server_url); repo->server_url = url; g_free (repo->effective_host); repo->effective_host = NULL; } save_repo_property (manager, repo_id, key, url); return 0; } save_repo_property (manager, repo_id, key, value); return 0; } char * seaf_repo_manager_get_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key) { return load_repo_property (manager, repo_id, key); } static void seaf_repo_manager_del_repo_property (SeafRepoManager *manager, const char *repo_id) { char *sql; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); sql = sqlite3_mprintf ("DELETE FROM RepoProperty WHERE repo_id = %Q", repo_id); sqlite_query_exec (db, sql); sqlite3_free (sql); pthread_mutex_unlock (&manager->priv->db_lock); } static void seaf_repo_manager_del_repo_property_by_key (SeafRepoManager *manager, const char *repo_id, const char *key) { char *sql; sqlite3 *db = manager->priv->db; pthread_mutex_lock (&manager->priv->db_lock); sql = sqlite3_mprintf ("DELETE FROM RepoProperty " "WHERE repo_id = %Q " " AND key = %Q", repo_id, key); sqlite_query_exec (db, sql); sqlite3_free (sql); pthread_mutex_unlock (&manager->priv->db_lock); } static int save_repo_enc_info (SeafRepoManager *manager, SeafRepo *repo) { sqlite3 *db = manager->priv->db; char sql[512]; char key[65], iv[33]; if (repo->enc_version == 1) { rawdata_to_hex (repo->enc_key, key, 16); rawdata_to_hex (repo->enc_iv, iv, 16); } else if (repo->enc_version == 2) { rawdata_to_hex (repo->enc_key, key, 32); rawdata_to_hex (repo->enc_iv, iv, 16); } snprintf (sql, sizeof(sql), "REPLACE INTO RepoKeys VALUES ('%s', '%s', '%s')", repo->id, key, iv); if (sqlite_query_exec (db, sql) < 0) return -1; return 0; } int seaf_repo_manager_set_repo_passwd (SeafRepoManager *manager, SeafRepo *repo, const char *passwd) { int ret; if (seafile_decrypt_repo_enc_key (repo->enc_version, passwd, repo->random_key, repo->enc_key, repo->enc_iv) < 0) return -1; pthread_mutex_lock (&manager->priv->db_lock); ret = save_repo_enc_info (manager, repo); pthread_mutex_unlock (&manager->priv->db_lock); return ret; } int seaf_repo_manager_set_merge (SeafRepoManager *manager, const char *repo_id, const char *remote_head) { char sql[256]; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "REPLACE INTO MergeInfo VALUES ('%s', 1, '%s');", repo_id, remote_head); int ret = sqlite_query_exec (manager->priv->db, sql); pthread_mutex_unlock (&manager->priv->db_lock); return ret; } int seaf_repo_manager_clear_merge (SeafRepoManager *manager, const char *repo_id) { char sql[256]; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "UPDATE MergeInfo SET in_merge=0 WHERE repo_id='%s';", repo_id); int ret = sqlite_query_exec (manager->priv->db, sql); pthread_mutex_unlock (&manager->priv->db_lock); return ret; } static gboolean get_merge_info (sqlite3_stmt *stmt, void *vinfo) { SeafRepoMergeInfo *info = vinfo; int in_merge; in_merge = sqlite3_column_int (stmt, 1); if (in_merge == 0) info->in_merge = FALSE; else info->in_merge = TRUE; /* * Note that compatibility, we store remote_head in the "branch" column. */ const char *remote_head = (const char *) sqlite3_column_text (stmt, 2); memcpy (info->remote_head, remote_head, 40); return FALSE; } int seaf_repo_manager_get_merge_info (SeafRepoManager *manager, const char *repo_id, SeafRepoMergeInfo *info) { char sql[256]; /* Default not in_merge, if no row is found in db. */ info->in_merge = FALSE; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "SELECT * FROM MergeInfo WHERE repo_id='%s';", repo_id); if (sqlite_foreach_selected_row (manager->priv->db, sql, get_merge_info, info) < 0) { pthread_mutex_unlock (&manager->priv->db_lock); return -1; } pthread_mutex_unlock (&manager->priv->db_lock); return 0; } typedef struct { char common_ancestor[41]; char head_id[41]; } CAInfo; static gboolean get_common_ancestor (sqlite3_stmt *stmt, void *vinfo) { CAInfo *info = vinfo; const char *ancestor = (const char *) sqlite3_column_text (stmt, 0); const char *head_id = (const char *) sqlite3_column_text (stmt, 1); memcpy (info->common_ancestor, ancestor, 40); memcpy (info->head_id, head_id, 40); return FALSE; } int seaf_repo_manager_get_common_ancestor (SeafRepoManager *manager, const char *repo_id, char *common_ancestor, char *head_id) { char sql[256]; CAInfo info; memset (&info, 0, sizeof(info)); pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "SELECT ca_id, head_id FROM CommonAncestor WHERE repo_id='%s';", repo_id); if (sqlite_foreach_selected_row (manager->priv->db, sql, get_common_ancestor, &info) < 0) { pthread_mutex_unlock (&manager->priv->db_lock); return -1; } pthread_mutex_unlock (&manager->priv->db_lock); memcpy (common_ancestor, info.common_ancestor, 41); memcpy (head_id, info.head_id, 41); return 0; } int seaf_repo_manager_set_common_ancestor (SeafRepoManager *manager, const char *repo_id, const char *common_ancestor, const char *head_id) { char sql[256]; pthread_mutex_lock (&manager->priv->db_lock); snprintf (sql, sizeof(sql), "REPLACE INTO CommonAncestor VALUES ('%s', '%s', '%s');", repo_id, common_ancestor, head_id); int ret = sqlite_query_exec (manager->priv->db, sql); pthread_mutex_unlock (&manager->priv->db_lock); return ret; } GList* seaf_repo_manager_get_repo_list (SeafRepoManager *manager, int start, int limit) { GList *repo_list = NULL; GHashTableIter iter; SeafRepo *repo; gpointer key, value; if (pthread_rwlock_rdlock (&manager->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return NULL; } g_hash_table_iter_init (&iter, manager->priv->repo_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { repo = value; if (!repo->delete_pending) repo_list = g_list_prepend (repo_list, repo); } pthread_rwlock_unlock (&manager->priv->lock); return repo_list; } GList * seaf_repo_manager_get_repo_id_list_by_server (SeafRepoManager *manager, const char *server_url) { GList *repo_id_list = NULL; GHashTableIter iter; SeafRepo *repo; gpointer key, value; if (pthread_rwlock_rdlock (&manager->priv->lock) < 0) { seaf_warning ("[repo mgr] failed to lock repo cache.\n"); return NULL; } g_hash_table_iter_init (&iter, manager->priv->repo_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { repo = value; if (!repo->delete_pending && g_strcmp0 (repo->server_url, server_url) == 0) repo_id_list = g_list_prepend (repo_id_list, g_strdup(repo->id)); } pthread_rwlock_unlock (&manager->priv->lock); return repo_id_list; } typedef struct { SeafRepo *repo; CheckoutTask *task; CheckoutDoneCallback done_cb; void *cb_data; } CheckoutData; static void checkout_job_done (void *vresult) { if (!vresult) return; CheckoutData *cdata = vresult; SeafRepo *repo = cdata->repo; SeafBranch *local = NULL; if (!cdata->task->success) goto out; seaf_repo_manager_set_repo_worktree (repo->manager, repo, cdata->task->worktree); local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("Cannot get branch local for repo %s(%.10s).\n", repo->name, repo->id); return; } /* Set repo head to mark checkout done. */ seaf_repo_set_head (repo, local); seaf_branch_unref (local); if (repo->auto_sync && (repo->sync_interval == 0)) { if (seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree) < 0) { seaf_warning ("failed to watch repo %s(%.10s).\n", repo->name, repo->id); return; } } out: if (cdata->done_cb) cdata->done_cb (cdata->task, cdata->repo, cdata->cb_data); /* g_hash_table_remove (mgr->priv->checkout_tasks_hash, cdata->repo->id); */ } static void * checkout_repo_job (void *data) { SeafRepoManager *mgr = seaf->repo_mgr; CheckoutData *cdata = data; SeafRepo *repo = cdata->repo; CheckoutTask *task; task = g_hash_table_lookup (mgr->priv->checkout_tasks_hash, repo->id); if (!task) { seaf_warning ("Failed to find checkout task for repo %.10s\n", repo->id); return NULL; } repo->worktree = g_strdup (task->worktree); char *error_msg = NULL; if (seaf_repo_checkout (repo, task->worktree, &error_msg) < 0) { seaf_warning ("Failed to checkout repo %.10s to %s : %s\n", repo->id, task->worktree, error_msg); g_free (error_msg); task->success = FALSE; goto ret; } task->success = TRUE; ret: return data; } int seaf_repo_manager_add_checkout_task (SeafRepoManager *mgr, SeafRepo *repo, const char *worktree, CheckoutDoneCallback done_cb, void *cb_data) { if (!repo || !worktree) { seaf_warning ("Invaid args\n"); return -1; } CheckoutTask *task = g_new0 (CheckoutTask, 1); memcpy (task->repo_id, repo->id, 36); g_return_val_if_fail (strlen(worktree) < SEAF_PATH_MAX, -1); strcpy (task->worktree, worktree); g_hash_table_insert (mgr->priv->checkout_tasks_hash, g_strdup(repo->id), task); CheckoutData *cdata = g_new0 (CheckoutData, 1); cdata->repo = repo; cdata->task = task; cdata->done_cb = done_cb; cdata->cb_data = cb_data; ccnet_job_manager_schedule_job(seaf->job_mgr, (JobThreadFunc)checkout_repo_job, (JobDoneCallback)checkout_job_done, cdata); return 0; } CheckoutTask * seaf_repo_manager_get_checkout_task (SeafRepoManager *mgr, const char *repo_id) { if (!repo_id || strlen(repo_id) != 36) { seaf_warning ("Invalid args\n"); return NULL; } return g_hash_table_lookup(mgr->priv->checkout_tasks_hash, repo_id); } int seaf_repo_manager_set_repo_email (SeafRepoManager *mgr, SeafRepo *repo, const char *email) { g_free (repo->email); repo->email = g_strdup(email); save_repo_property (mgr, repo->id, REPO_PROP_EMAIL, email); return 0; } int seaf_repo_manager_set_repo_token (SeafRepoManager *manager, SeafRepo *repo, const char *token) { g_free (repo->token); repo->token = g_strdup(token); save_repo_property (manager, repo->id, REPO_PROP_TOKEN, token); return 0; } int seaf_repo_manager_remove_repo_token (SeafRepoManager *manager, SeafRepo *repo) { g_free (repo->token); repo->token = NULL; seaf_repo_manager_del_repo_property_by_key(manager, repo->id, REPO_PROP_TOKEN); return 0; } int seaf_repo_manager_set_repo_relay_info (SeafRepoManager *mgr, const char *repo_id, const char *relay_addr, const char *relay_port) { save_repo_property (mgr, repo_id, REPO_PROP_RELAY_ADDR, relay_addr); save_repo_property (mgr, repo_id, REPO_PROP_RELAY_PORT, relay_port); return 0; } void seaf_repo_manager_get_repo_relay_info (SeafRepoManager *mgr, const char *repo_id, char **relay_addr, char **relay_port) { char *addr, *port; addr = load_repo_property (mgr, repo_id, REPO_PROP_RELAY_ADDR); port = load_repo_property (mgr, repo_id, REPO_PROP_RELAY_PORT); if (relay_addr && addr) *relay_addr = addr; if (relay_port && port) *relay_port = port; } int seaf_repo_manager_update_repo_relay_info (SeafRepoManager *mgr, SeafRepo *repo, const char *new_addr, const char *new_port) { GList *ptr, *repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, 0, -1); SeafRepo *r; for (ptr = repos; ptr; ptr = ptr->next) { r = ptr->data; if (g_strcmp0(r->relay_id, repo->relay_id) != 0) continue; char *relay_addr = NULL; char *relay_port = NULL; seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, r->id, &relay_addr, &relay_port); if (g_strcmp0(relay_addr, new_addr) != 0 || g_strcmp0(relay_port, new_port) != 0) { seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, r->id, new_addr, new_port); } g_free (relay_addr); g_free (relay_port); } g_list_free (repos); return 0; } static void update_server_properties (SeafRepoManager *mgr, const char *repo_id, const char *new_server_url) { char *old_server_url = NULL; char *sql = NULL; old_server_url = seaf_repo_manager_get_repo_property (mgr, repo_id, REPO_PROP_SERVER_URL); if (!old_server_url) return; pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("UPDATE ServerProperty SET server_url=%Q WHERE " "server_url=%Q;", new_server_url, old_server_url); sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); sqlite3_free (sql); g_free (old_server_url); } int seaf_repo_manager_update_repos_server_host (SeafRepoManager *mgr, const char *old_host, const char *new_host, const char *new_server_url) { GList *ptr, *repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, 0, -1); SeafRepo *r; char *canon_server_url = canonical_server_url(new_server_url); for (ptr = repos; ptr; ptr = ptr->next) { r = ptr->data; char *relay_addr = NULL; char *relay_port = NULL; seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, r->id, &relay_addr, &relay_port); if (g_strcmp0(relay_addr, old_host) == 0) { seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, r->id, new_host, relay_port); /* Update server property before server_url is changed. */ update_server_properties (mgr, r->id, canon_server_url); seaf_repo_manager_set_repo_property ( seaf->repo_mgr, r->id, REPO_PROP_SERVER_URL, canon_server_url); } g_free (relay_addr); g_free (relay_port); } g_list_free (repos); g_free (canon_server_url); return 0; } char * seaf_repo_manager_get_server_property (SeafRepoManager *mgr, const char *server_url, const char *key) { char *sql = sqlite3_mprintf ("SELECT value FROM ServerProperty WHERE " "server_url=%Q AND key=%Q;", server_url, key); char *value; pthread_mutex_lock (&mgr->priv->db_lock); value = sqlite_get_string (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); sqlite3_free (sql); return value; } int seaf_repo_manager_set_server_property (SeafRepoManager *mgr, const char *server_url, const char *key, const char *value) { char *sql; int ret; char *canon_server_url = canonical_server_url(server_url); pthread_mutex_lock (&mgr->priv->db_lock); sql = sqlite3_mprintf ("REPLACE INTO ServerProperty VALUES (%Q, %Q, %Q);", canon_server_url, key, value); ret = sqlite_query_exec (mgr->priv->db, sql); pthread_mutex_unlock (&mgr->priv->db_lock); sqlite3_free (sql); g_free (canon_server_url); return ret; } gboolean seaf_repo_manager_server_is_pro (SeafRepoManager *mgr, const char *server_url) { gboolean ret = FALSE; char *is_pro = seaf_repo_manager_get_server_property (seaf->repo_mgr, server_url, SERVER_PROP_IS_PRO); if (is_pro != NULL && strcasecmp (is_pro, "true") == 0) ret = TRUE; g_free (is_pro); return ret; } /* * Read ignored files from ignore.txt */ GList *seaf_repo_load_ignore_files (const char *worktree) { GList *list = NULL; SeafStat st; FILE *fp; char *full_path, *pattern; char path[PATH_MAX]; full_path = g_build_path (PATH_SEPERATOR, worktree, IGNORE_FILE, NULL); if (seaf_stat (full_path, &st) < 0) goto error; if (!S_ISREG(st.st_mode)) goto error; fp = g_fopen(full_path, "r"); if (fp == NULL) goto error; while (fgets(path, PATH_MAX, fp) != NULL) { /* remove leading and trailing whitespace, including \n \r. */ g_strstrip (path); /* ignore comment and blank line */ if (path[0] == '#' || path[0] == '\0') continue; /* Change 'foo/' to 'foo/ *'. */ if (path[strlen(path)-1] == '/') pattern = g_strdup_printf("%s/%s*", worktree, path); else pattern = g_strdup_printf("%s/%s", worktree, path); list = g_list_prepend(list, pattern); } fclose(fp); g_free (full_path); return list; error: g_free (full_path); return NULL; } gboolean seaf_repo_check_ignore_file (GList *ignore_list, const char *fullpath) { char *str; SeafStat st; GPatternSpec *ignore_spec; GList *p; str = g_strdup(fullpath); int rc = seaf_stat(str, &st); if (rc == 0 && S_ISDIR(st.st_mode)) { g_free (str); str = g_strconcat (fullpath, "/", NULL); } for (p = ignore_list; p != NULL; p = p->next) { char *pattern = (char *)p->data; ignore_spec = g_pattern_spec_new(pattern); if (g_pattern_match_string(ignore_spec, str)) { g_free (str); g_pattern_spec_free(ignore_spec); return TRUE; } g_pattern_spec_free(ignore_spec); } g_free (str); return FALSE; } /* * Free ignored file list */ void seaf_repo_free_ignore_files (GList *ignore_list) { GList *p; if (ignore_list == NULL) return; for (p = ignore_list; p != NULL; p = p->next) free(p->data); g_list_free (ignore_list); } seafile-6.1.5/daemon/repo-mgr.h000066400000000000000000000350611323477647300163240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAF_REPO_MGR_H #define SEAF_REPO_MGR_H #include "common.h" #include #include "seafile-object.h" #include "commit-mgr.h" #include "branch-mgr.h" #define REPO_AUTO_SYNC "auto-sync" #define REPO_RELAY_ID "relay-id" #define REPO_REMOTE_HEAD "remote-head" #define REPO_LOCAL_HEAD "local-head" #define REPO_PROP_EMAIL "email" #define REPO_PROP_TOKEN "token" #define REPO_PROP_RELAY_ADDR "relay-address" #define REPO_PROP_RELAY_PORT "relay-port" #define REPO_PROP_DOWNLOAD_HEAD "download-head" #define REPO_PROP_IS_READONLY "is-readonly" #define REPO_PROP_SERVER_URL "server-url" #define REPO_PROP_SYNC_INTERVAL "sync-interval" #define REPO_SYNC_WORKTREE_NAME "sync-worktree-name" struct _SeafRepoManager; typedef struct _SeafRepo SeafRepo; struct _ChangeSet; /* The caller can use the properties directly. But the caller should * always write on repos via the API. */ struct _SeafRepo { struct _SeafRepoManager *manager; gchar id[37]; gchar *name; gchar *desc; gchar *category; /* not used yet */ gboolean encrypted; int enc_version; gchar magic[65]; /* hash(repo_id + passwd), key stretched. */ gchar random_key[97]; /* key length is 48 after encryption */ gboolean no_local_history; gint64 last_modify; SeafBranch *head; gchar root_id[41]; gboolean is_corrupted; gboolean delete_pending; gchar *relay_id; gchar *worktree; gboolean wt_changed; int wt_check_time; int last_sync_time; /* Last time check locked files. */ int last_check_locked_time; gboolean checking_locked_files; unsigned char enc_key[32]; /* 256-bit encryption key */ unsigned char enc_iv[16]; gchar *email; /* email of the user on the relay */ gchar *token; /* token for access this repo on server */ pthread_mutex_t lock; gboolean worktree_invalid; /* true if worktree moved or deleted */ gboolean index_corrupted; gboolean is_readonly; unsigned int auto_sync : 1; unsigned int quota_full_notified : 1; unsigned int access_denied_notified : 1; int version; gboolean create_partial_commit; /* Used for http sync. */ char *server_url; /* Can be server_url or server_url:8082, depends on which one works. */ char *effective_host; gboolean use_fileserver_port; /* Detected file change set during indexing. * Added to here to avoid passing additional arguments. */ struct _ChangeSet *changeset; /* Non-zero if periodic sync is set for this repo. */ int sync_interval; }; gboolean is_repo_id_valid (const char *id); SeafRepo* seaf_repo_new (const char *id, const char *name, const char *desc); void seaf_repo_free (SeafRepo *repo); int seaf_repo_set_head (SeafRepo *repo, SeafBranch *branch); SeafCommit * seaf_repo_get_head_commit (const char *repo_id); void seaf_repo_set_readonly (SeafRepo *repo); void seaf_repo_unset_readonly (SeafRepo *repo); int seaf_repo_checkdir (SeafRepo *repo); /* Update repo name, desc, magic etc from commit. */ void seaf_repo_from_commit (SeafRepo *repo, SeafCommit *commit); /* Update repo-related fields to commit. */ void seaf_repo_to_commit (SeafRepo *repo, SeafCommit *commit); void seaf_repo_set_name (SeafRepo *repo, const char *new_name); /* * Returns a list of all commits belongs to the repo. * The commits in the repos are all unique. */ GList * seaf_repo_get_commits (SeafRepo *repo); int seaf_repo_index_add (SeafRepo *repo, const char *path); int seaf_repo_index_worktree_files (const char *repo_id, int version, const char *modifier, const char *worktree, const char *passwd, int enc_version, const char *random_key, char *root_id); int seaf_repo_index_rm (SeafRepo *repo, const char *path); char * seaf_repo_status (SeafRepo *repo); gboolean seaf_repo_is_worktree_changed (SeafRepo *repo); gboolean seaf_repo_is_index_unmerged (SeafRepo *repo); char * seaf_repo_index_commit (SeafRepo *repo, const char *desc, gboolean is_force_commit, gboolean is_initial_commit, GError **error); int seaf_repo_checkout (SeafRepo *repo, const char *worktree_parent, char **error); int seaf_repo_checkout_commit (SeafRepo *repo, SeafCommit *commit, gboolean recover_merge, char **error); enum { MERGE_STATUS_UNKNOWN = 0, MERGE_STATUS_UPTODATE, MERGE_STATUS_FAST_FORWARD, MERGE_STATUS_REAL_MERGE, }; int seaf_repo_merge (SeafRepo *repo, const char *branch, char **error, int *merge_status); GList * seaf_repo_diff (SeafRepo *repo, const char *old, const char *new, int fold_dir_diff, char **error); typedef struct _SeafRepoManager SeafRepoManager; typedef struct _SeafRepoManagerPriv SeafRepoManagerPriv; struct _SeafRepoManager { struct _SeafileSession *seaf; char *index_dir; SeafRepoManagerPriv *priv; }; SeafRepoManager* seaf_repo_manager_new (struct _SeafileSession *seaf); int seaf_repo_manager_init (SeafRepoManager *mgr); int seaf_repo_manager_start (SeafRepoManager *mgr); int seaf_repo_manager_add_repo (SeafRepoManager *mgr, SeafRepo *repo); int seaf_repo_manager_mark_repo_deleted (SeafRepoManager *mgr, SeafRepo *repo); int seaf_repo_manager_del_repo (SeafRepoManager *mgr, SeafRepo *repo); void seaf_repo_manager_move_repo_store (SeafRepoManager *mgr, const char *type, const char *repo_id); void seaf_repo_manager_remove_repo_ondisk (SeafRepoManager *mgr, const char *repo_id, gboolean add_deleted_record); SeafRepo* seaf_repo_manager_create_new_repo (SeafRepoManager *mgr, const char *name, const char *desc); SeafRepo* seaf_repo_manager_get_repo (SeafRepoManager *manager, const gchar *id); gboolean seaf_repo_manager_repo_exists (SeafRepoManager *manager, const gchar *id); GList* seaf_repo_manager_get_repo_list (SeafRepoManager *mgr, int start, int limit); GList * seaf_repo_manager_get_repo_id_list_by_server (SeafRepoManager *mgr, const char *server_url); GList * seaf_repo_manager_list_garbage_repos (SeafRepoManager *mgr); void seaf_repo_manager_remove_garbage_repo (SeafRepoManager *mgr, const char *repo_id); #define MAX_REPO_TOKEN 64 #define DEFAULT_REPO_TOKEN "default" int seaf_repo_manager_set_repo_token (SeafRepoManager *manager, SeafRepo *repo, const char *token); int seaf_repo_manager_remove_repo_token (SeafRepoManager *manager, SeafRepo *repo); int seaf_repo_manager_set_repo_email (SeafRepoManager *manager, SeafRepo *repo, const char *email); int seaf_repo_manager_set_repo_relay_info (SeafRepoManager *manager, const char *repo_id, const char *relay_addr, const char *relay_port); void seaf_repo_manager_get_repo_relay_info (SeafRepoManager *mgr, const char *repo_id, char **relay_addr, char **relay_port); int seaf_repo_manager_branch_repo_unmap (SeafRepoManager *manager, SeafBranch *branch); int seaf_repo_manager_set_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key, const char *value); char * seaf_repo_manager_get_repo_property (SeafRepoManager *manager, const char *repo_id, const char *key); void seaf_repo_mamager_del_repo_property (SeafRepoManager *manager, SeafRepo *repo); int seaf_repo_check_worktree (SeafRepo *repo); int seaf_repo_manager_set_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo, const char *worktree); void seaf_repo_manager_invalidate_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo); void seaf_repo_manager_validate_repo_worktree (SeafRepoManager *mgr, SeafRepo *repo); int seaf_repo_manager_set_repo_passwd (SeafRepoManager *manager, SeafRepo *repo, const char *passwd); int seaf_repo_manager_set_repo_relay_id (SeafRepoManager *mgr, SeafRepo *repo, const char *relay_id); int seaf_repo_manager_set_merge (SeafRepoManager *manager, const char *repo_id, const char *remote_head); int seaf_repo_manager_clear_merge (SeafRepoManager *manager, const char *repo_id); typedef struct { gboolean in_merge; char remote_head[41]; } SeafRepoMergeInfo; int seaf_repo_manager_get_merge_info (SeafRepoManager *manager, const char *repo_id, SeafRepoMergeInfo *info); int seaf_repo_manager_get_common_ancestor (SeafRepoManager *manager, const char *repo_id, char *common_ancestor, char *head_id); int seaf_repo_manager_set_common_ancestor (SeafRepoManager *manager, const char *repo_id, const char *common_ancestor, const char *head_id); typedef struct { char repo_id[41]; char worktree[SEAF_PATH_MAX]; int total_files; int finished_files; gboolean success; } CheckoutTask; typedef void (*CheckoutDoneCallback) (CheckoutTask *, SeafRepo *, void *); int seaf_repo_manager_add_checkout_task (SeafRepoManager *mgr, SeafRepo *repo, const char *worktree, CheckoutDoneCallback done_cb, void *cb_data); CheckoutTask * seaf_repo_manager_get_checkout_task (SeafRepoManager *mgr, const char *repo_id); int seaf_repo_manager_update_repo_relay_info (SeafRepoManager *mgr, SeafRepo *repo, const char *new_addr, const char *new_port); int seaf_repo_manager_update_repos_server_host (SeafRepoManager *mgr, const char *old_host, const char *new_host, const char *new_server_url); #define SERVER_PROP_IS_PRO "is_pro" char * seaf_repo_manager_get_server_property (SeafRepoManager *mgr, const char *server_url, const char *key); int seaf_repo_manager_set_server_property (SeafRepoManager *mgr, const char *server_url, const char *key, const char *value); gboolean seaf_repo_manager_server_is_pro (SeafRepoManager *mgr, const char *server_url); GList * seaf_repo_load_ignore_files (const char *worktree); gboolean seaf_repo_check_ignore_file (GList *ignore_list, const char *fullpath); void seaf_repo_free_ignore_files (GList *ignore_list); enum { FETCH_CHECKOUT_SUCCESS = 0, FETCH_CHECKOUT_CANCELED, FETCH_CHECKOUT_FAILED, FETCH_CHECKOUT_TRANSFER_ERROR, FETCH_CHECKOUT_LOCKED, }; struct _TransferTask; struct _HttpTxTask; int seaf_repo_fetch_and_checkout (struct _TransferTask *task, struct _HttpTxTask *http_task, gboolean is_http, const char *remote_head_id); gboolean seaf_repo_manager_is_ignored_hidden_file (const char *filename); /* Locked files. */ #define LOCKED_OP_UPDATE "update" #define LOCKED_OP_DELETE "delete" typedef struct _LockedFile { char *operation; gint64 old_mtime; char file_id[41]; } LockedFile; typedef struct _LockedFileSet { SeafRepoManager *mgr; char repo_id[37]; GHashTable *locked_files; } LockedFileSet; LockedFileSet * seaf_repo_manager_get_locked_file_set (SeafRepoManager *mgr, const char *repo_id); void locked_file_set_free (LockedFileSet *fset); int locked_file_set_add_update (LockedFileSet *fset, const char *path, const char *operation, gint64 old_mtime, const char *file_id); int locked_file_set_remove (LockedFileSet *fset, const char *path, gboolean db_only); LockedFile * locked_file_set_lookup (LockedFileSet *fset, const char *path); /* Folder Permissions. */ typedef enum FolderPermType { FOLDER_PERM_TYPE_USER = 0, FOLDER_PERM_TYPE_GROUP, } FolderPermType; typedef struct _FolderPerm { char *path; char *permission; } FolderPerm; void folder_perm_free (FolderPerm *perm); int seaf_repo_manager_update_folder_perms (SeafRepoManager *mgr, const char *repo_id, FolderPermType type, GList *folder_perms); int seaf_repo_manager_update_folder_perm_timestamp (SeafRepoManager *mgr, const char *repo_id, gint64 timestamp); gint64 seaf_repo_manager_get_folder_perm_timestamp (SeafRepoManager *mgr, const char *repo_id); gboolean seaf_repo_manager_is_path_writable (SeafRepoManager *mgr, const char *repo_id, const char *path); /* File Sync Errors. */ GList * seaf_repo_manager_get_file_sync_errors (SeafRepoManager *mgr, int offset, int limit); #endif seafile-6.1.5/daemon/seaf-daemon.c000066400000000000000000000523571323477647300167550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #ifdef WIN32 #include #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_BREAKPAD_SUPPORT #include #endif // HAVE_BREAKPAD_SUPPORT #include #include #include #include "seafile-session.h" #include "seafile-rpc.h" #include #include #include "log.h" #include "utils.h" #include "vc-utils.h" #include "seafile-config.h" #ifndef USE_GPL_CRYPTO #include "curl-init.h" #endif #include "cdc/cdc.h" #ifndef SEAFILE_CLIENT_VERSION #define SEAFILE_CLIENT_VERSION PACKAGE_VERSION #endif SeafileSession *seaf; SearpcClient *ccnetrpc_client; SearpcClient *appletrpc_client; CcnetClient *bind_client; static const char *short_options = "hvc:d:w:l:D:bg:G:"; static struct option long_options[] = { { "help", no_argument, NULL, 'h', }, { "version", no_argument, NULL, 'v', }, { "config-file", required_argument, NULL, 'c' }, { "seafdir", required_argument, NULL, 'd' }, { "daemon", no_argument, NULL, 'b' }, { "debug", required_argument, NULL, 'D' }, { "worktree", required_argument, NULL, 'w' }, { "log", required_argument, NULL, 'l' }, { "ccnet-debug-level", required_argument, NULL, 'g' }, { "seafile-debug-level", required_argument, NULL, 'G' }, { NULL, 0, NULL, 0, }, }; static void usage () { fprintf (stderr, "usage: seaf-daemon [-c config_dir] [-d seafile_dir] [-w worktree_dir] [--daemon]\n"); } #include #include "searpc-signature.h" #include "searpc-marshal.h" static void start_rpc_service (CcnetClient *client) { searpc_server_init (register_marshals); searpc_create_service ("seafile-rpcserver"); ccnet_register_service (client, "seafile-rpcserver", "rpc-inner", CCNET_TYPE_RPCSERVER_PROC, NULL); searpc_create_service ("seafile-threaded-rpcserver"); ccnet_register_service (client, "seafile-threaded-rpcserver", "rpc-inner", CCNET_TYPE_THREADED_RPCSERVER_PROC, NULL); /* seafile-rpcserver */ searpc_server_register_function ("seafile-rpcserver", seafile_get_session_info, "seafile_get_session_info", searpc_signature_object__void()); searpc_server_register_function ("seafile-rpcserver", seafile_get_config, "seafile_get_config", searpc_signature_string__string()); searpc_server_register_function ("seafile-rpcserver", seafile_set_config, "seafile_set_config", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_config_int, "seafile_get_config_int", searpc_signature_int__string()); searpc_server_register_function ("seafile-rpcserver", seafile_set_config_int, "seafile_set_config_int", searpc_signature_int__string_int()); searpc_server_register_function ("seafile-rpcserver", seafile_set_upload_rate_limit, "seafile_set_upload_rate_limit", searpc_signature_int__int()); searpc_server_register_function ("seafile-rpcserver", seafile_set_download_rate_limit, "seafile_set_download_rate_limit", searpc_signature_int__int()); searpc_server_register_function ("seafile-rpcserver", seafile_unsync_repos_by_account, "seafile_unsync_repos_by_account", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_remove_repo_tokens_by_account, "seafile_remove_repo_tokens_by_account", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_set_repo_token, "seafile_set_repo_token", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_upload_rate, "seafile_get_upload_rate", searpc_signature_int__void()); searpc_server_register_function ("seafile-rpcserver", seafile_get_download_rate, "seafile_get_download_rate", searpc_signature_int__void()); searpc_server_register_function ("seafile-rpcserver", seafile_destroy_repo, "seafile_destroy_repo", searpc_signature_int__string()); searpc_server_register_function ("seafile-rpcserver", seafile_set_repo_property, "seafile_set_repo_property", searpc_signature_int__string_string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_property, "seafile_get_repo_property", searpc_signature_string__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_relay_address, "seafile_get_repo_relay_address", searpc_signature_string__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_relay_port, "seafile_get_repo_relay_port", searpc_signature_string__string()); searpc_server_register_function ("seafile-rpcserver", seafile_update_repo_relay_info, "seafile_update_repo_relay_info", searpc_signature_int__string_string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_update_repos_server_host, "seafile_update_repos_server_host", searpc_signature_int__string_string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_disable_auto_sync, "seafile_disable_auto_sync", searpc_signature_int__void()); searpc_server_register_function ("seafile-rpcserver", seafile_enable_auto_sync, "seafile_enable_auto_sync", searpc_signature_int__void()); searpc_server_register_function ("seafile-rpcserver", seafile_is_auto_sync_enabled, "seafile_is_auto_sync_enabled", searpc_signature_int__void()); searpc_server_register_function ("seafile-rpcserver", seafile_branch_gets, "seafile_branch_gets", searpc_signature_objlist__string()); searpc_server_register_function ("seafile-rpcserver", seafile_gen_default_worktree, "gen_default_worktree", searpc_signature_string__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_check_path_for_clone, "seafile_check_path_for_clone", searpc_signature_int__string()); /* clone means sync with existing folder, download means sync to a new folder. */ searpc_server_register_function ("seafile-rpcserver", seafile_clone, "seafile_clone", searpc_signature_string__string_int_string_string_string_string_string_string_string_string_string_string_int_string()); searpc_server_register_function ("seafile-rpcserver", seafile_download, "seafile_download", searpc_signature_string__string_int_string_string_string_string_string_string_string_string_string_string_int_string()); searpc_server_register_function ("seafile-rpcserver", seafile_cancel_clone_task, "seafile_cancel_clone_task", searpc_signature_int__string()); searpc_server_register_function ("seafile-rpcserver", seafile_remove_clone_task, "seafile_remove_clone_task", searpc_signature_int__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_clone_tasks, "seafile_get_clone_tasks", searpc_signature_objlist__void()); searpc_server_register_function ("seafile-rpcserver", seafile_sync, "seafile_sync", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_list, "seafile_get_repo_list", searpc_signature_objlist__int_int()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo, "seafile_get_repo", searpc_signature_object__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_sync_task_list, "seafile_get_sync_task_list", searpc_signature_objlist__void()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_sync_task, "seafile_get_repo_sync_task", searpc_signature_object__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_repo_sync_info, "seafile_get_repo_sync_info", searpc_signature_object__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_commit, "seafile_get_commit", searpc_signature_object__string_int_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_commit_list, "seafile_get_commit_list", searpc_signature_objlist__string_int_int()); searpc_server_register_function ("seafile-rpcserver", seafile_find_transfer_task, "seafile_find_transfer_task", searpc_signature_object__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_checkout_task, "seafile_get_checkout_task", searpc_signature_object__string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_path_sync_status, "seafile_get_path_sync_status", searpc_signature_string__string_string_int()); searpc_server_register_function ("seafile-rpcserver", seafile_mark_file_locked, "seafile_mark_file_locked", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_mark_file_unlocked, "seafile_mark_file_unlocked", searpc_signature_int__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_generate_magic_and_random_key, "seafile_generate_magic_and_random_key", searpc_signature_object__int_string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_server_property, "seafile_get_server_property", searpc_signature_string__string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_set_server_property, "seafile_set_server_property", searpc_signature_int__string_string_string()); searpc_server_register_function ("seafile-rpcserver", seafile_get_file_sync_errors, "seafile_get_file_sync_errors", searpc_signature_objlist__int_int()); /* Need to run in a thread since diff may take long. */ searpc_server_register_function ("seafile-threaded-rpcserver", seafile_diff, "seafile_diff", searpc_signature_objlist__string_string_string_int()); } static void set_signal_handlers (SeafileSession *session) { #ifndef WIN32 signal (SIGPIPE, SIG_IGN); #endif } static void create_sync_rpc_clients (const char *config_dir) { CcnetClient *sync_client; /* sync client and rpc client */ sync_client = ccnet_client_new (); if ( (ccnet_client_load_confdir(sync_client, NULL, config_dir)) < 0 ) { seaf_warning ("Read config dir error\n"); exit(1); } if (ccnet_client_connect_daemon (sync_client, CCNET_CLIENT_SYNC) < 0) { seaf_warning ("Connect to server fail: %s\n", strerror(errno)); exit(1); } ccnetrpc_client = ccnet_create_rpc_client (sync_client, NULL, "ccnet-rpcserver"); } #ifdef WIN32 /* Get the commandline arguments in unicode, then convert them to utf8 */ static char ** get_argv_utf8 (int *argc) { int i = 0; char **argv = NULL; const wchar_t *cmdline = NULL; wchar_t **argv_w = NULL; cmdline = GetCommandLineW(); argv_w = CommandLineToArgvW (cmdline, argc); if (!argv_w) { printf("failed to CommandLineToArgvW(), GLE=%lu\n", GetLastError()); return NULL; } argv = (char **)malloc (sizeof(char*) * (*argc)); for (i = 0; i < *argc; i++) { argv[i] = wchar_to_utf8 (argv_w[i]); } return argv; } #endif /* * Bind to an unused service to make sure only one instance of seaf-daemon * is running. */ static gboolean bind_ccnet_service (const char *config_dir) { gboolean ret = TRUE; bind_client = ccnet_client_new (); if ( (ccnet_client_load_confdir(bind_client, NULL, config_dir)) < 0 ) { seaf_warning ("Read config dir error\n"); exit(1); } if (ccnet_client_connect_daemon (bind_client, CCNET_CLIENT_SYNC) < 0) { seaf_warning ("Connect to server fail: %s\n", strerror(errno)); exit(1); } if (!ccnet_register_service_sync (bind_client, "seafile-dummy-service", "rpc-inner")) ret = FALSE; return ret; } int main (int argc, char **argv) { #ifdef HAVE_BREAKPAD_SUPPORT #ifdef WIN32 #define DUMPS_DIR "~/ccnet/logs/dumps/" #else #define DUMPS_DIR "~/.ccnet/logs/dumps/" #endif const char *dump_dir = ccnet_expand_path(DUMPS_DIR); checkdir_with_mkdir(dump_dir); CBPWrapperExceptionHandler bp_exception_handler = newCBPWrapperExceptionHandler(dump_dir); #endif int c; char *config_dir = DEFAULT_CONFIG_DIR; char *seafile_dir = NULL; char *worktree_dir = NULL; char *logfile = NULL; const char *debug_str = NULL; int daemon_mode = 0; CcnetClient *client; char *ccnet_debug_level_str = "info"; char *seafile_debug_level_str = "debug"; #ifdef WIN32 LoadLibraryA ("exchndl.dll"); argv = get_argv_utf8 (&argc); #endif while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != EOF) { switch (c) { case 'h': usage(); exit (1); break; case 'v': exit (1); break; case 'c': config_dir = optarg; break; case 'd': seafile_dir = g_strdup(optarg); break; case 'b': daemon_mode = 1; break; case 'D': debug_str = optarg; break; case 'w': worktree_dir = g_strdup(optarg); break; case 'l': logfile = g_strdup(optarg); break; case 'g': ccnet_debug_level_str = optarg; break; case 'G': seafile_debug_level_str = optarg; break; default: usage (); exit (1); } } argc -= optind; argv += optind; #ifndef WIN32 if (daemon_mode) { #ifndef __APPLE__ daemon (1, 0); #else /* __APPLE */ /* daemon is deprecated under APPLE * use fork() instead * */ switch (fork ()) { case -1: seaf_warning ("Failed to daemonize"); exit (-1); break; case 0: /* all good*/ break; default: /* kill origin process */ exit (0); } #endif /* __APPLE */ } #endif /* !WIN32 */ cdc_init (); curl_global_init (CURL_GLOBAL_ALL); #if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init(); #endif #if !GLIB_CHECK_VERSION(2, 31, 0) g_thread_init(NULL); #endif if (!debug_str) debug_str = g_getenv("SEAFILE_DEBUG"); seafile_debug_set_flags_string (debug_str); if (logfile == NULL) logfile = g_build_filename (config_dir, "logs", "seafile.log", NULL); if (seafile_log_init (logfile, ccnet_debug_level_str, seafile_debug_level_str) < 0) { seaf_warning ("Failed to init log.\n"); exit (1); } if (!bind_ccnet_service (config_dir)) { seaf_warning ("Failed to bind ccnet service\n"); exit (1); } /* init ccnet */ client = ccnet_init (NULL, config_dir); if (!client) exit (1); start_rpc_service (client); create_sync_rpc_clients (config_dir); appletrpc_client = ccnet_create_async_rpc_client (client, NULL, "applet-rpcserver"); /* init seafile */ if (seafile_dir == NULL) seafile_dir = g_build_filename (config_dir, "seafile-data", NULL); if (worktree_dir == NULL) worktree_dir = g_build_filename (g_get_home_dir(), "seafile", NULL); seaf = seafile_session_new (seafile_dir, worktree_dir, client); if (!seaf) { seaf_warning ("Failed to create seafile session.\n"); exit (1); } seaf->ccnetrpc_client = ccnetrpc_client; seaf->appletrpc_client = appletrpc_client; seaf_message ("starting seafile client "SEAFILE_CLIENT_VERSION"\n"); #if defined(SEAFILE_SOURCE_COMMIT_ID) seaf_message ("seafile source code version "SEAFILE_SOURCE_COMMIT_ID"\n"); #endif g_free (seafile_dir); g_free (worktree_dir); g_free (logfile); set_signal_handlers (seaf); #ifndef USE_GPL_CRYPTO seafile_curl_init(); #endif seafile_session_prepare (seaf); seafile_session_start (seaf); seafile_session_config_set_string (seaf, "wktree", seaf->worktree_dir); ccnet_main (client); #ifndef USE_GPL_CRYPTO seafile_curl_deinit(); #endif return 0; } seafile-6.1.5/daemon/seafile-config.c000066400000000000000000000122361323477647300174410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "db.h" #include "seafile-config.h" gboolean seafile_session_config_exists (SeafileSession *session, const char *key) { char sql[256]; snprintf (sql, sizeof(sql), "SELECT 1 FROM Config WHERE key = '%s'", key); return sqlite_check_for_existence (session->config_db, sql); } static gboolean get_value (sqlite3_stmt *stmt, void *data) { char **p_value = data; *p_value = g_strdup((char *) sqlite3_column_text (stmt, 0)); /* Only one result. */ return FALSE; } static char * config_get_string (sqlite3 *config_db, const char *key) { char sql[256]; char *value = NULL; snprintf (sql, sizeof(sql), "SELECT value FROM Config WHERE key='%s';", key); if (sqlite_foreach_selected_row (config_db, sql, get_value, &value) < 0) return NULL; return value; } char * seafile_session_config_get_string (SeafileSession *session, const char *key) { return (config_get_string (session->config_db, key)); } int seafile_session_config_get_int (SeafileSession *session, const char *key, gboolean *exists) { char *value; int ret; value = config_get_string (session->config_db, key); if (!value) { if (exists) *exists = FALSE; return -1; } if (exists) *exists = TRUE; ret = atoi (value); g_free (value); return ret; } gboolean seafile_session_config_get_bool (SeafileSession *session, const char *key) { char *value; gboolean ret = FALSE; value = config_get_string (session->config_db, key); if (g_strcmp0(value, "true") == 0) ret = TRUE; g_free (value); return ret; } int seafile_session_config_set_string (SeafileSession *session, const char *key, const char *value) { char sql[256]; sqlite3_snprintf (sizeof(sql), sql, "REPLACE INTO Config VALUES ('%q', '%q');", key, value); if (sqlite_query_exec (session->config_db, sql) < 0) return -1; if (g_strcmp0 (key, KEY_CLIENT_NAME) == 0) { g_free (session->client_name); session->client_name = g_strdup(value); } if (g_strcmp0(key, KEY_SYNC_EXTRA_TEMP_FILE) == 0) { if (g_strcmp0(value, "true") == 0) session->sync_extra_temp_file = TRUE; else session->sync_extra_temp_file = FALSE; } if (g_strcmp0(key, KEY_DISABLE_VERIFY_CERTIFICATE) == 0) { if (g_strcmp0(value, "true") == 0) session->disable_verify_certificate = TRUE; else session->disable_verify_certificate = FALSE; } if (g_strcmp0(key, KEY_USE_PROXY) == 0) { if (g_strcmp0(value, "true") == 0) session->use_http_proxy = TRUE; else session->use_http_proxy = FALSE; } if (g_strcmp0(key, KEY_PROXY_TYPE) == 0) { session->http_proxy_type = g_strcmp0(value, "none") == 0 ? NULL : g_strdup(value); } if (g_strcmp0(key, KEY_PROXY_ADDR) == 0) { session->http_proxy_addr = g_strdup(value); } if (g_strcmp0(key, KEY_PROXY_USERNAME) == 0) { session->http_proxy_username = g_strdup(value); } if (g_strcmp0(key, KEY_PROXY_PASSWORD) == 0) { session->http_proxy_password = g_strdup(value); } return 0; } int seafile_session_config_set_int (SeafileSession *session, const char *key, int value) { char sql[256]; sqlite3_snprintf (sizeof(sql), sql, "REPLACE INTO Config VALUES ('%q', %d);", key, value); if (sqlite_query_exec (session->config_db, sql) < 0) return -1; if (g_strcmp0(key, KEY_PROXY_PORT) == 0) { session->http_proxy_port = value; } return 0; } sqlite3 * seafile_session_config_open_db (const char *db_path) { sqlite3 *db; if (sqlite_open_db (db_path, &db) < 0) return NULL; /* * Values are stored in text. You should convert it * back to integer if needed when you read it from * db. */ char *sql = "CREATE TABLE IF NOT EXISTS Config (" "key TEXT PRIMARY KEY, " "value TEXT);"; sqlite_query_exec (db, sql); return db; } int seafile_session_config_set_allow_invalid_worktree(SeafileSession *session, gboolean val) { return seafile_session_config_set_string(session, KEY_ALLOW_INVALID_WORKTREE, val ? "true" : "false"); } gboolean seafile_session_config_get_allow_invalid_worktree(SeafileSession *session) { return seafile_session_config_get_bool (session, KEY_ALLOW_INVALID_WORKTREE); } gboolean seafile_session_config_get_allow_repo_not_found_on_server(SeafileSession *session) { return seafile_session_config_get_bool (session, KEY_ALLOW_REPO_NOT_FOUND_ON_SERVER); } seafile-6.1.5/daemon/seafile-config.h000066400000000000000000000051361323477647300174470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_CONFIG_H #define SEAFILE_CONFIG_H #include "seafile-session.h" #include "db.h" #define KEY_CLIENT_NAME "client_name" #define KEY_MONITOR_ID "monitor_id" #define KEY_CHECK_REPO_PERIOD "check_repo_period" #define KEY_DB_HOST "db_host" #define KEY_DB_USER "db_user" #define KEY_DB_PASSWD "db_passwd" #define KEY_DB_NAME "db_name" #define KEY_UPLOAD_LIMIT "upload_limit" #define KEY_DOWNLOAD_LIMIT "download_limit" #define KEY_ALLOW_INVALID_WORKTREE "allow_invalid_worktree" #define KEY_ALLOW_REPO_NOT_FOUND_ON_SERVER "allow_repo_not_found_on_server" #define KEY_SYNC_EXTRA_TEMP_FILE "sync_extra_temp_file" /* Http sync settings. */ #define KEY_ENABLE_HTTP_SYNC "enable_http_sync" #define KEY_DISABLE_VERIFY_CERTIFICATE "disable_verify_certificate" /* Http sync proxy settings. */ #define KEY_USE_PROXY "use_proxy" #define KEY_PROXY_TYPE "proxy_type" #define KEY_PROXY_ADDR "proxy_addr" #define KEY_PROXY_PORT "proxy_port" #define KEY_PROXY_USERNAME "proxy_username" #define KEY_PROXY_PASSWORD "proxy_password" #define PROXY_TYPE_HTTP "http" #define PROXY_TYPE_SOCKS "socks" gboolean seafile_session_config_exists (SeafileSession *session, const char *key); /* * Returns: config value in string. The string should be freed by caller. */ char * seafile_session_config_get_string (SeafileSession *session, const char *key); /* * Returns: * If key exists, @exists will be set to TRUE and returns the value; * otherwise, @exists will be set to FALSE and returns -1. */ int seafile_session_config_get_int (SeafileSession *session, const char *key, gboolean *exists); /* * Returns: config value in boolean. Return FALSE if the value is not configured. */ gboolean seafile_session_config_get_bool (SeafileSession *session, const char *key); int seafile_session_config_set_string (SeafileSession *session, const char *key, const char *value); int seafile_session_config_set_int (SeafileSession *session, const char *key, int value); int seafile_session_config_set_allow_invalid_worktree(SeafileSession *session, gboolean val); gboolean seafile_session_config_get_allow_invalid_worktree(SeafileSession *session); gboolean seafile_session_config_get_allow_repo_not_found_on_server(SeafileSession *session); sqlite3 * seafile_session_config_open_db (const char *db_path); #endif seafile-6.1.5/daemon/seafile-session.c000066400000000000000000000404151323477647300176570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "seafile-session.h" #include "seafile-config.h" #include "vc-utils.h" #include "seaf-utils.h" #include "log.h" #define MAX_THREADS 50 enum { REPO_COMMITTED, REPO_FETCHED, REPO_UPLOADED, REPO_HTTP_FETCHED, REPO_HTTP_UPLOADED, REPO_WORKTREE_CHECKED, LAST_SIGNAL }; int signals[LAST_SIGNAL]; G_DEFINE_TYPE (SeafileSession, seafile_session, G_TYPE_OBJECT); static void seafile_session_class_init (SeafileSessionClass *klass) { signals[REPO_COMMITTED] = g_signal_new ("repo-committed", SEAFILE_TYPE_SESSION, G_SIGNAL_RUN_LAST, 0, /* no class singal handler */ NULL, NULL, /* no accumulator */ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[REPO_FETCHED] = g_signal_new ("repo-fetched", SEAFILE_TYPE_SESSION, G_SIGNAL_RUN_LAST, 0, /* no class singal handler */ NULL, NULL, /* no accumulator */ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[REPO_UPLOADED] = g_signal_new ("repo-uploaded", SEAFILE_TYPE_SESSION, G_SIGNAL_RUN_LAST, 0, /* no class singal handler */ NULL, NULL, /* no accumulator */ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[REPO_HTTP_FETCHED] = g_signal_new ("repo-http-fetched", SEAFILE_TYPE_SESSION, G_SIGNAL_RUN_LAST, 0, /* no class singal handler */ NULL, NULL, /* no accumulator */ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); signals[REPO_HTTP_UPLOADED] = g_signal_new ("repo-http-uploaded", SEAFILE_TYPE_SESSION, G_SIGNAL_RUN_LAST, 0, /* no class singal handler */ NULL, NULL, /* no accumulator */ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); } static int create_deleted_store_dirs (const char *deleted_store) { char *commits = NULL, *fs = NULL, *blocks = NULL; int ret = 0; if (checkdir_with_mkdir (deleted_store) < 0) { seaf_warning ("Directory %s does not exist and is unable to create\n", deleted_store); return -1; } commits = g_build_filename (deleted_store, "commits", NULL); if (checkdir_with_mkdir (commits) < 0) { seaf_warning ("Directory %s does not exist and is unable to create\n", commits); ret = -1; goto out; } fs = g_build_filename (deleted_store, "fs", NULL); if (checkdir_with_mkdir (fs) < 0) { seaf_warning ("Directory %s does not exist and is unable to create\n", fs); ret = -1; goto out; } blocks = g_build_filename (deleted_store, "blocks", NULL); if (checkdir_with_mkdir (blocks) < 0) { seaf_warning ("Directory %s does not exist and is unable to create\n", blocks); ret = -1; goto out; } out: g_free (commits); g_free (fs); g_free (blocks); return ret; } SeafileSession * seafile_session_new(const char *seafile_dir, const char *worktree_dir, struct _CcnetClient *ccnet_session) { char *abs_seafile_dir; char *abs_worktree_dir; char *tmp_file_dir; char *db_path; char *deleted_store; sqlite3 *config_db; SeafileSession *session = NULL; #ifndef SEAF_TOOL if (!ccnet_session) return NULL; #endif abs_worktree_dir = ccnet_expand_path (worktree_dir); abs_seafile_dir = ccnet_expand_path (seafile_dir); tmp_file_dir = g_build_filename (abs_seafile_dir, "tmpfiles", NULL); db_path = g_build_filename (abs_seafile_dir, "config.db", NULL); deleted_store = g_build_filename (abs_seafile_dir, "deleted_store", NULL); if (checkdir_with_mkdir (abs_seafile_dir) < 0) { seaf_warning ("Config dir %s does not exist and is unable to create\n", abs_seafile_dir); goto onerror; } if (checkdir_with_mkdir (abs_worktree_dir) < 0) { seaf_warning ("Worktree %s does not exist and is unable to create\n", abs_worktree_dir); goto onerror; } if (checkdir_with_mkdir (tmp_file_dir) < 0) { seaf_warning ("Temp file dir %s does not exist and is unable to create\n", tmp_file_dir); goto onerror; } if (create_deleted_store_dirs (deleted_store) < 0) goto onerror; config_db = seafile_session_config_open_db (db_path); if (!config_db) { seaf_warning ("Failed to open config db.\n"); goto onerror; } session = g_object_new (SEAFILE_TYPE_SESSION, NULL); session->seaf_dir = abs_seafile_dir; session->tmp_file_dir = tmp_file_dir; session->worktree_dir = abs_worktree_dir; session->session = ccnet_session; session->config_db = config_db; session->deleted_store = deleted_store; session->fs_mgr = seaf_fs_manager_new (session, abs_seafile_dir); if (!session->fs_mgr) goto onerror; session->block_mgr = seaf_block_manager_new (session, abs_seafile_dir); if (!session->block_mgr) goto onerror; session->commit_mgr = seaf_commit_manager_new (session); if (!session->commit_mgr) goto onerror; session->repo_mgr = seaf_repo_manager_new (session); if (!session->repo_mgr) goto onerror; session->branch_mgr = seaf_branch_manager_new (session); if (!session->branch_mgr) goto onerror; session->transfer_mgr = seaf_transfer_manager_new (session); if (!session->transfer_mgr) goto onerror; session->clone_mgr = seaf_clone_manager_new (session); if (!session->clone_mgr) goto onerror; session->sync_mgr = seaf_sync_manager_new (session); if (!session->sync_mgr) goto onerror; session->wt_monitor = seaf_wt_monitor_new (session); if (!session->wt_monitor) goto onerror; session->http_tx_mgr = http_tx_manager_new (session); if (!session->http_tx_mgr) goto onerror; session->filelock_mgr = seaf_filelock_manager_new (session); if (!session->filelock_mgr) goto onerror; session->job_mgr = ccnet_job_manager_new (MAX_THREADS); ccnet_session->job_mgr = ccnet_job_manager_new (MAX_THREADS); session->ev_mgr = cevent_manager_new (); if (!session->ev_mgr) goto onerror; session->mq_mgr = seaf_mq_manager_new (session); if (!session->mq_mgr) goto onerror; return session; onerror: free (abs_seafile_dir); free (abs_worktree_dir); g_free (tmp_file_dir); g_free (db_path); g_free (deleted_store); g_free (session); return NULL; } static void seafile_session_init (SeafileSession *session) { } static void load_system_proxy (SeafileSession *session) { char *system_proxy_txt = g_build_filename (seaf->seaf_dir, "system-proxy.txt", NULL); json_t *json = NULL; if (!g_file_test (system_proxy_txt, G_FILE_TEST_EXISTS)) { seaf_warning ("Can't load system proxy: file %s doesn't exist\n", system_proxy_txt); goto out; } json_error_t jerror; json = json_load_file(system_proxy_txt, 0, &jerror); if (!json) { if (strlen(jerror.text) > 0) seaf_warning ("Failed to load system proxy information: %s.\n", jerror.text); else seaf_warning ("Failed to load system proxy information\n"); goto out; } const char *type; type = json_object_get_string_member (json, "type"); if (!type) { seaf_warning ("Failed to load system proxy information: proxy type missing\n"); goto out; } if (strcmp(type, "none") != 0 && strcmp(type, "socks") != 0 && strcmp(type, "http") != 0) { seaf_warning ("Failed to load system proxy information: invalid proxy type %s\n", type); goto out; } if (g_strcmp0(type, "none") == 0) { goto out; } session->http_proxy_type = g_strdup(type); session->http_proxy_addr = g_strdup(json_object_get_string_member (json, "addr")); session->http_proxy_port = json_object_get_int_member (json, "port"); session->http_proxy_username = g_strdup(json_object_get_string_member (json, "username")); session->http_proxy_password = g_strdup(json_object_get_string_member (json, "password")); out: g_free (system_proxy_txt); if (json) json_decref(json); } void seafile_session_prepare (SeafileSession *session) { session->client_name = seafile_session_config_get_string (session, KEY_CLIENT_NAME); if (!session->client_name) { session->client_name = g_strdup(session->session->base.name); } /* load config */ session->sync_extra_temp_file = seafile_session_config_get_bool (session, KEY_SYNC_EXTRA_TEMP_FILE); /* Enable http sync by default. */ session->enable_http_sync = TRUE; session->disable_verify_certificate = seafile_session_config_get_bool (session, KEY_DISABLE_VERIFY_CERTIFICATE); session->use_http_proxy = seafile_session_config_get_bool(session, KEY_USE_PROXY); gboolean use_system_proxy = seafile_session_config_get_bool(session, "use_system_proxy"); if (use_system_proxy) { load_system_proxy(session); } else { session->http_proxy_type = seafile_session_config_get_string(session, KEY_PROXY_TYPE); session->http_proxy_addr = seafile_session_config_get_string(session, KEY_PROXY_ADDR); session->http_proxy_port = seafile_session_config_get_int(session, KEY_PROXY_PORT, NULL); session->http_proxy_username = seafile_session_config_get_string(session, KEY_PROXY_USERNAME); session->http_proxy_password = seafile_session_config_get_string(session, KEY_PROXY_PASSWORD); } /* Start mq manager earlier, so that we can send notifications * when start repo manager. */ seaf_mq_manager_init (session->mq_mgr); seaf_commit_manager_init (session->commit_mgr); seaf_fs_manager_init (session->fs_mgr); seaf_branch_manager_init (session->branch_mgr); seaf_filelock_manager_init (session->filelock_mgr); seaf_repo_manager_init (session->repo_mgr); seaf_clone_manager_init (session->clone_mgr); #ifndef SEAF_TOOL seaf_sync_manager_init (session->sync_mgr); #endif seaf_mq_manager_set_heartbeat_name (session->mq_mgr, "seafile.heartbeat"); } /* static void */ /* recover_interrupted_merges () */ /* { */ /* GList *repos, *ptr; */ /* SeafRepo *repo; */ /* SeafRepoMergeInfo info; */ /* char *err_msg = NULL; */ /* gboolean unused; */ /* repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, -1, -1); */ /* for (ptr = repos; ptr; ptr = ptr->next) { */ /* repo = ptr->data; */ /* if (seaf_repo_manager_get_merge_info (seaf->repo_mgr, repo->id, &info) < 0) { */ /* seaf_warning ("Failed to get merge info for repo %s.\n", repo->id); */ /* continue; */ /* } */ /* if (info.in_merge) { */ /* seaf_message ("Recovering merge for repo %.8s.\n", repo->id); */ /* /\* No one else is holding the lock. *\/ */ /* pthread_mutex_lock (&repo->lock); */ /* if (seaf_repo_merge (repo, "master", &err_msg, &unused) < 0) { */ /* g_free (err_msg); */ /* } */ /* pthread_mutex_unlock (&repo->lock); */ /* } */ /* } */ /* g_list_free (repos); */ /* } */ static gboolean is_repo_store_in_use (const char *repo_id) { if (seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) return TRUE; char sql[256]; snprintf (sql, sizeof(sql), "SELECT 1 FROM CloneTasks WHERE repo_id='%s'", repo_id); if (sqlite_check_for_existence (seaf->clone_mgr->db, sql)) return TRUE; return FALSE; } static void cleanup_unused_repo_stores (const char *type) { char *top_store_dir; const char *repo_id; top_store_dir = g_build_filename (seaf->seaf_dir, "storage", type, NULL); GError *error = NULL; GDir *dir = g_dir_open (top_store_dir, 0, &error); if (!dir) { seaf_warning ("Failed to open store dir %s: %s.\n", top_store_dir, error->message); g_free (top_store_dir); return; } while ((repo_id = g_dir_read_name(dir)) != NULL) { if (!is_repo_store_in_use (repo_id)) { seaf_message ("Moving %s for deleted repo %s.\n", type, repo_id); seaf_repo_manager_move_repo_store (seaf->repo_mgr, type, repo_id); } } g_free (top_store_dir); g_dir_close (dir); } static void * on_start_cleanup_job (void *vdata) { /* recover_interrupted_merges (); */ /* Ignore migration errors. If any blocks is not migrated successfully, * there will be some sync error in run time. The user has to recover the * error by resyncing. */ /* migrate_client_v0_repos (); */ cleanup_unused_repo_stores ("commits"); cleanup_unused_repo_stores ("fs"); cleanup_unused_repo_stores ("blocks"); return vdata; } static void cleanup_job_done (void *vdata) { SeafileSession *session = vdata; if (cevent_manager_start (session->ev_mgr) < 0) { g_error ("Failed to start event manager.\n"); return; } if (seaf_transfer_manager_start (session->transfer_mgr) < 0) { g_error ("Failed to start transfer manager.\n"); return; } if (http_tx_manager_start (session->http_tx_mgr) < 0) { g_error ("Failed to start http transfer manager.\n"); return; } if (seaf_sync_manager_start (session->sync_mgr) < 0) { g_error ("Failed to start sync manager.\n"); return; } if (seaf_wt_monitor_start (session->wt_monitor) < 0) { g_error ("Failed to start worktree monitor.\n"); return; } /* Must be after wt monitor, since we may add watch to repo worktree. */ if (seaf_repo_manager_start (session->repo_mgr) < 0) { g_error ("Failed to start repo manager.\n"); return; } if (seaf_clone_manager_start (session->clone_mgr) < 0) { g_error ("Failed to start clone manager.\n"); return; } if (seaf_filelock_manager_start (session->filelock_mgr) < 0) { g_error ("Failed to start filelock manager.\n"); return; } /* The system is up and running. */ session->started = TRUE; } static void on_start_cleanup (SeafileSession *session) { ccnet_job_manager_schedule_job (seaf->job_mgr, on_start_cleanup_job, cleanup_job_done, session); } void seafile_session_start (SeafileSession *session) { /* MQ must be started to send heartbeat message to applet. */ if (seaf_mq_manager_start (session->mq_mgr) < 0) { g_error ("Failed to start mq manager.\n"); return; } /* Finish cleanup task before anything is run. */ on_start_cleanup (session); } #if 0 void seafile_session_add_event (SeafileSession *session, const char *type, const char *first, ...) { gchar *body; va_list args; va_start (args, first); body = key_value_list_to_json_v (first, args); va_end (args); CcnetEvent *event = g_object_new (CCNET_TYPE_EVENT, "etype", type, "body", body, NULL); ccnet_client_send_event(session->session, (GObject *)event); g_object_unref (event); g_free (body); } #endif seafile-6.1.5/daemon/seafile-session.h000066400000000000000000000070261323477647300176650ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_SESSION_H #define SEAFILE_SESSION_H #include #include #include #include #include "block-mgr.h" #include "fs-mgr.h" #include "commit-mgr.h" #include "branch-mgr.h" #include "repo-mgr.h" #include "clone-mgr.h" #include "db.h" #include "transfer-mgr.h" #include "sync-mgr.h" #include "wt-monitor.h" #include "mq-mgr.h" #include "http-tx-mgr.h" #include "filelock-mgr.h" #include struct _CcnetClient; #define SEAFILE_TYPE_SESSION (seafile_session_get_type ()) #define SEAFILE_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAFILE_TYPE_SESSION, SeafileSession)) #define SEAFILE_IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAFILE_TYPE_SESSION)) #define SEAFILE_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAFILE_TYPE_SESSION, SeafileSessionClass)) #define SEAFILE_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAFILE_TYPE_SESSION)) #define SEAFILE_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAFILE_TYPE_SESSION, SeafileSessionClass)) typedef struct _SeafileSession SeafileSession; typedef struct _SeafileSessionClass SeafileSessionClass; struct _SeafileSession { GObject parent_instance; struct _CcnetClient *session; char *client_name; SearpcClient *ccnetrpc_client; SearpcClient *appletrpc_client; char *seaf_dir; char *tmp_file_dir; char *worktree_dir; /* the default directory for * storing worktrees */ sqlite3 *config_db; char *deleted_store; SeafBlockManager *block_mgr; SeafFSManager *fs_mgr; SeafCommitManager *commit_mgr; SeafBranchManager *branch_mgr; SeafRepoManager *repo_mgr; SeafTransferManager *transfer_mgr; SeafCloneManager *clone_mgr; SeafSyncManager *sync_mgr; SeafWTMonitor *wt_monitor; SeafMqManager *mq_mgr; CEventManager *ev_mgr; CcnetJobManager *job_mgr; HttpTxManager *http_tx_mgr; SeafFilelockManager *filelock_mgr; /* Set after all components are up and running. */ gboolean started; gboolean sync_extra_temp_file; gboolean enable_http_sync; gboolean disable_verify_certificate; gboolean use_http_proxy; char *http_proxy_type; char *http_proxy_addr; int http_proxy_port; char *http_proxy_username; char *http_proxy_password; }; struct _SeafileSessionClass { GObjectClass parent_class; }; extern SeafileSession *seaf; SeafileSession * seafile_session_new(const char *seafile_dir, const char *worktree_dir, struct _CcnetClient *ccnet_session); void seafile_session_prepare (SeafileSession *session); void seafile_session_start (SeafileSession *session); char * seafile_session_get_tmp_file_path (SeafileSession *session, const char *basename, char path[]); #if 0 void seafile_session_add_event (SeafileSession *session, const char *type, const char *first, ...); #endif #endif /* SEAFILE_H */ seafile-6.1.5/daemon/set-perm.c000066400000000000000000000216141323477647300163220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "utils.h" #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" #include "set-perm.h" #ifdef WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x501 #endif #include #include #include #define WIN32_WRITE_ACCESS_MASK (FILE_WRITE_DATA | FILE_APPEND_DATA | \ FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | DELETE) // Remove explicit ACEs set by us. static int unset_permissions (PACL dacl) { ACL_SIZE_INFORMATION size_info; if (!dacl) return 0; if (!GetAclInformation (dacl, &size_info, sizeof(size_info), AclSizeInformation)) { seaf_warning ("GetAclInformation Error: %lu\n", GetLastError()); return -1; } DWORD i; ACE_HEADER *ace; ACCESS_DENIED_ACE *deny_ace; ACCESS_ALLOWED_ACE *allowed_ace; for (i = 0; i < size_info.AceCount; ++i) { if (!GetAce(dacl, i, (void**)&ace)) { seaf_warning ("GetAce Error: %lu\n", GetLastError()); return -1; } // Skip inherited ACEs. if (ace->AceFlags & INHERITED_ACE) continue; if (ace->AceType == ACCESS_DENIED_ACE_TYPE) { deny_ace = (ACCESS_DENIED_ACE *)ace; if (deny_ace->Mask == WIN32_WRITE_ACCESS_MASK) { DeleteAce(dacl, i); break; } } else if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE) { allowed_ace = (ACCESS_ALLOWED_ACE *)ace; if (allowed_ace->Mask == WIN32_WRITE_ACCESS_MASK) { DeleteAce(dacl, i); break; } } } return 0; } int seaf_set_path_permission (const char *path, SeafPathPerm perm, gboolean recursive) { wchar_t *wpath = NULL; int ret = 0; DWORD res = 0; PACL old_dacl = NULL, new_dacl = NULL; PSECURITY_DESCRIPTOR sd = NULL; EXPLICIT_ACCESS ea; g_return_val_if_fail (perm == SEAF_PATH_PERM_RO || perm == SEAF_PATH_PERM_RW, -1); seaf_debug ("set permission for %s, perm: %d, recursive: %d\n", path, perm, recursive); wpath = win32_long_path (path); if (!wpath) return -1; res = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL, &sd); if (ERROR_SUCCESS != res) { seaf_warning( "GetNamedSecurityInfo Error for path %s: %lu\n", path, res ); ret = -1; goto cleanup; } unset_permissions (old_dacl); // Initialize an EXPLICIT_ACCESS structure for the new ACE. memset (&ea, 0, sizeof(EXPLICIT_ACCESS)); ea.grfAccessPermissions = WIN32_WRITE_ACCESS_MASK; ea.grfAccessMode = ((perm == SEAF_PATH_PERM_RO)?DENY_ACCESS:GRANT_ACCESS); ea.grfInheritance = (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE); ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME; ea.Trustee.TrusteeType = TRUSTEE_IS_USER; ea.Trustee.ptstrName = "CURRENT_USER"; // Create a new ACL that merges the new ACE // into the existing DACL. res = SetEntriesInAcl(1, &ea, old_dacl, &new_dacl); if (ERROR_SUCCESS != res) { seaf_warning( "SetEntriesInAcl Error %lu\n", res ); ret = -1; goto cleanup; } // Attach the new ACL as the object's DACL. if (recursive) { res = SetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, new_dacl, NULL); if (ERROR_SUCCESS != res) { seaf_warning( "SetNamedSecurityInfo Error %lu\n", res ); ret = -1; goto cleanup; } } else { SECURITY_DESCRIPTOR new_sd; InitializeSecurityDescriptor (&new_sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl (&new_sd, TRUE, new_dacl, FALSE); if (!SetFileSecurityW (wpath, DACL_SECURITY_INFORMATION, &new_sd)) { seaf_warning ("SetFileSecurity Error %lu\n", GetLastError()); ret = -1; goto cleanup; } } cleanup: g_free (wpath); if(sd != NULL) LocalFree((HLOCAL) sd); if(new_dacl != NULL) LocalFree((HLOCAL) new_dacl); return ret; } int seaf_unset_path_permission (const char *path, gboolean recursive) { wchar_t *wpath = NULL; int ret = 0; DWORD res = 0; PACL old_dacl = NULL, new_dacl = NULL; PSECURITY_DESCRIPTOR sd = NULL; seaf_debug ("unset permission for %s, recursive: %d\n", path, recursive); wpath = win32_long_path (path); if (!wpath) return -1; res = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL, &sd); if (ERROR_SUCCESS != res) { seaf_warning( "GetNamedSecurityInfo Error %lu\n", res ); ret = -1; goto cleanup; } // Create a new copy of the old ACL res = SetEntriesInAcl(0, NULL, old_dacl, &new_dacl); if (ERROR_SUCCESS != res) { seaf_warning( "SetEntriesInAcl Error %lu\n", res ); ret = -1; goto cleanup; } if (!new_dacl) { goto cleanup; } unset_permissions (new_dacl); // Update path's ACL if (recursive) { res = SetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, new_dacl, NULL); if (ERROR_SUCCESS != res) { seaf_warning( "SetNamedSecurityInfo Error %lu\n", res ); ret = -1; goto cleanup; } } else { SECURITY_DESCRIPTOR new_sd; InitializeSecurityDescriptor (&new_sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl (&new_sd, TRUE, new_dacl, FALSE); if (!SetFileSecurityW (wpath, DACL_SECURITY_INFORMATION, &new_sd)) { seaf_warning ("SetFileSecurity Error %lu\n", GetLastError()); ret = -1; goto cleanup; } } cleanup: g_free (wpath); if(sd != NULL) LocalFree((HLOCAL) sd); if(new_dacl != NULL) LocalFree((HLOCAL) new_dacl); return ret; } SeafPathPerm seaf_get_path_permission (const char *path) { wchar_t *wpath = NULL; SeafPathPerm ret = SEAF_PATH_PERM_UNKNOWN; DWORD res = 0; PACL dacl = NULL; PSECURITY_DESCRIPTOR sd = NULL; wpath = win32_long_path (path); if (!wpath) return ret; res = GetNamedSecurityInfoW(wpath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &sd); if (ERROR_SUCCESS != res) { seaf_warning( "GetNamedSecurityInfo Error %lu\n", res ); goto cleanup; } ACL_SIZE_INFORMATION size_info; if (!GetAclInformation (dacl, &size_info, sizeof(size_info), AclSizeInformation)) { seaf_warning ("GetAclInformation Error: %lu\n", GetLastError()); goto cleanup; } DWORD i; ACE_HEADER *ace; ACCESS_DENIED_ACE *deny_ace; ACCESS_ALLOWED_ACE *allowed_ace; for (i = 0; i < size_info.AceCount; ++i) { if (!GetAce(dacl, i, (void**)&ace)) { seaf_warning ("GetAce Error: %lu\n", GetLastError()); goto cleanup; } // Skip inherited ACEs. if (ace->AceFlags & INHERITED_ACE) continue; if (ace->AceType == ACCESS_DENIED_ACE_TYPE) { deny_ace = (ACCESS_DENIED_ACE *)ace; if (deny_ace->Mask == WIN32_WRITE_ACCESS_MASK) { ret = SEAF_PATH_PERM_RO; break; } } else if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE) { allowed_ace = (ACCESS_ALLOWED_ACE *)ace; if (allowed_ace->Mask == WIN32_WRITE_ACCESS_MASK) { ret = SEAF_PATH_PERM_RW; break; } } } cleanup: g_free (wpath); if(sd != NULL) LocalFree((HLOCAL) sd); return ret; } #else #include int seaf_set_path_permission (const char *path, SeafPathPerm perm, gboolean recursive) { struct stat st; mode_t new_mode; if (stat (path, &st) < 0) { seaf_warning ("Failed to stat %s: %s\n", path, strerror(errno)); return -1; } new_mode = st.st_mode; if (perm == SEAF_PATH_PERM_RO) new_mode &= ~(S_IWUSR); else if (perm == SEAF_PATH_PERM_RW) new_mode |= S_IWUSR; if (chmod (path, new_mode) < 0) { seaf_warning ("Failed to chmod %s to %d: %s\n", path, new_mode, strerror(errno)); return -1; } return 0; } int seaf_unset_path_permission (const char *path, gboolean recursive) { return 0; } SeafPathPerm seaf_get_path_permission (const char *path) { return SEAF_PATH_PERM_UNKNOWN; } #endif /* WIN32 */ seafile-6.1.5/daemon/set-perm.h000066400000000000000000000006421323477647300163250ustar00rootroot00000000000000#ifndef SEAF_SET_PERM_H #define SEAF_SET_PERM_H enum SeafPathPerm { SEAF_PATH_PERM_UNKNOWN = 0, SEAF_PATH_PERM_RO, SEAF_PATH_PERM_RW, }; typedef enum SeafPathPerm SeafPathPerm; int seaf_set_path_permission (const char *path, SeafPathPerm perm, gboolean recursive); int seaf_unset_path_permission (const char *path, gboolean recursive); SeafPathPerm seaf_get_path_permission (const char *path); #endif seafile-6.1.5/daemon/status.c000066400000000000000000000245211323477647300161110ustar00rootroot00000000000000#include "common.h" #include #include #include #include #include "seafile-session.h" #include "status.h" #include "fs-mgr.h" #include "index/index.h" #include "diff-simple.h" #include "vc-utils.h" #include "utils.h" #include "cdc/cdc.h" #include "log.h" struct dir_entry { unsigned int len; char name[0]; /* more */ }; struct dir_struct { int nr, alloc; int ignored_nr, ignored_alloc; enum { DIR_SHOW_IGNORED = 1<<0, DIR_SHOW_OTHER_DIRECTORIES = 1<<1, DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, DIR_NO_GITLINKS = 1<<3, DIR_COLLECT_IGNORED = 1<<4 } flags; struct dir_entry **entries; struct dir_entry **ignored; }; static struct dir_entry * dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; ent = malloc(sizeof(*ent) + len + 1); ent->len = len; memcpy(ent->name, pathname, len); ent->name[len] = 0; return ent; } static struct dir_entry * dir_add_name(struct dir_struct *dir, const char *pathname, int len, struct index_state *index) { if (index_name_exists(index, pathname, len, 0)) return NULL; ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc); return dir->entries[dir->nr++] = dir_entry_new(pathname, len); } static inline int is_dot_or_dotdot(const char *name) { return (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))); } static int get_dtype(const char *dname, const char *path) { SeafStat st; int dtype = DT_UNKNOWN; char *realpath = g_build_path (PATH_SEPERATOR, path, dname, NULL); if (!seaf_stat(realpath, &st)) { if (S_ISREG(st.st_mode)) dtype = DT_REG; if (S_ISDIR(st.st_mode)) dtype = DT_DIR; } g_free(realpath); return dtype; } static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, struct index_state *index, const char *worktree, IgnoreFunc ignore_func, void *data) { char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL); GDir *fdir = g_dir_open (realpath, 0, NULL); const char *dname; char *nfc_dname; int contents = 0; int dtype; if (fdir) { char path[SEAF_PATH_MAX + 1]; memcpy(path, base, baselen); while ((dname = g_dir_read_name(fdir)) != NULL) { int len = 0; #ifdef __APPLE__ nfc_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC); #else nfc_dname = g_strdup(dname); #endif if (is_dot_or_dotdot(nfc_dname)) { g_free (nfc_dname); continue; } if (ignore_func (realpath, nfc_dname, data)) { g_free (nfc_dname); continue; } dtype = get_dtype(nfc_dname, realpath); switch (dtype) { case DT_REG: len = strlen(nfc_dname); memcpy(path + baselen, nfc_dname, len + 1); len = strlen(path); break; case DT_DIR: len = strlen(nfc_dname); memcpy(path + baselen, nfc_dname, len + 1); memcpy(path + baselen + len, "/", 2); len = strlen(path); read_directory_recursive(dir, path, len, 0, index, worktree, ignore_func, data); g_free (nfc_dname); continue; default: /* DT_UNKNOWN */ len = 0; break; } if(len > 0) dir_add_name(dir, path, len, index); g_free (nfc_dname); } g_dir_close(fdir); } g_free(realpath); return contents; } static int cmp_name(const void *p1, const void *p2) { const struct dir_entry *e1 = *(const struct dir_entry **)p1; const struct dir_entry *e2 = *(const struct dir_entry **)p2; return cache_name_compare(e1->name, e1->len, e2->name, e2->len); } static int read_directory(struct dir_struct *dir, const char *worktree, struct index_state *index, IgnoreFunc ignore_func) { GList *ignore_list = NULL; ignore_list = seaf_repo_load_ignore_files(worktree); read_directory_recursive(dir, "", 0, 0, index, worktree, ignore_func, ignore_list); seaf_repo_free_ignore_files(ignore_list); qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name); return dir->nr; } void wt_status_collect_untracked(struct index_state *index, GList **results, const char *worktree, IgnoreFunc ignore_func) { int i; struct dir_struct dir; DiffEntry *de; memset(&dir, 0, sizeof(dir)); read_directory(&dir, worktree, index, ignore_func); for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; unsigned char sha1[20] = { 0 }; de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_ADDED, sha1, ent->name); *results = g_list_prepend (*results, de); free(ent); } free(dir.entries); } void wt_status_collect_changes_worktree(struct index_state *index, GList **results, const char *worktree) { DiffEntry *de; int entries, i; GList *ignore_list = seaf_repo_load_ignore_files (worktree); entries = index->cache_nr; for (i = 0; i < entries; i++) { char *realpath; SeafStat st; struct cache_entry *ce = index->cache[i]; int changed = 0; if (ce_stage(ce)) { int mask = 0; mask |= 1 << ce_stage(ce); while (i < entries) { struct cache_entry *nce = index->cache[i]; if (strcmp(ce->name, nce->name)) break; mask |= 1 << ce_stage(nce); i++; } /* * Compensate for loop update */ i--; de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_UNMERGED, ce->sha1, ce->name); de->unmerge_state = diff_unmerged_state (mask); *results = g_list_prepend (*results, de); continue; } if (ce_uptodate(ce) || ce_skip_worktree(ce)) continue; realpath = g_build_path (PATH_SEPERATOR, worktree, ce->name, NULL); if (seaf_stat(realpath, &st) < 0) { if (errno != ENOENT && errno != ENOTDIR) changed = -1; else changed = 1; } if (changed) { if (changed < 0) { seaf_warning ("Faile to stat %s: %s\n", ce->name, strerror(errno)); g_free (realpath); continue; } if (ce->ce_ctime.sec == 0) { g_free (realpath); continue; } de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_DELETED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); g_free (realpath); continue; } if (S_ISDIR (ce->ce_mode)) { g_free (realpath); continue; } /* Don't check changes to ignored files. * This can happen when a file is committed and then added to * ignore.txt. After that changes to this file will not committed, * and it should be ignored here. */ if (seaf_repo_check_ignore_file (ignore_list, realpath)) { g_free (realpath); continue; } g_free (realpath); changed = ie_match_stat (ce, &st, 0); if (!changed) { ce_mark_uptodate (ce); continue; } de = diff_entry_new (DIFF_TYPE_WORKTREE, DIFF_STATUS_MODIFIED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); } seaf_repo_free_ignore_files (ignore_list); } static struct cache_entry * next_cache_entry(struct index_state *index, int *pos) { while (*pos < index->cache_nr) { struct cache_entry *ce = index->cache[*pos]; (*pos)++; if (!(ce->ce_flags & CE_UNPACKED)) return ce; } return NULL; } void wt_status_collect_changes_index (struct index_state *index, GList **results, SeafRepo *repo) { SeafFSManager *fs_mgr; SeafCommit *head; int pos = 0; DiffEntry *de; fs_mgr = repo->manager->seaf->fs_mgr; head = seaf_commit_manager_get_commit (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id); if (!head) { seaf_warning ("Failed to get commit %s:%s.\n", repo->id, repo->head->commit_id); return; } mark_all_ce_unused (index); /* if repo is initial, we don't need to check index changes */ if (strncmp(EMPTY_SHA1, head->root_id, 40) != 0) { SeafDir *root; /* call diff_index to get status */ root = seaf_fs_manager_get_seafdir (fs_mgr, repo->id, repo->version, head->root_id); if (!root) { seaf_warning ("Failed to get root %s:%s.\n", repo->id, head->root_id); seaf_commit_unref (head); return; } if (diff_index(repo->id, repo->version, index, root, results) < 0) seaf_warning("diff index failed\n"); seaf_dir_free (root); seaf_commit_unref (head); return; } seaf_commit_unref (head); while (1) { struct cache_entry *ce = next_cache_entry(index, &pos); if (!ce || ce_stage(ce)) break; ce->ce_flags |= CE_UNPACKED; de = diff_entry_new (DIFF_TYPE_INDEX, DIFF_STATUS_ADDED, ce->sha1, ce->name); *results = g_list_prepend (*results, de); } } seafile-6.1.5/daemon/status.h000066400000000000000000000014321323477647300161120ustar00rootroot00000000000000#ifndef STATUS_H #define STATUS_H #include #include "repo-mgr.h" #include "index/index.h" #include "diff-simple.h" typedef gboolean (*IgnoreFunc) (const char *basepath, const char *filename, void *data); void wt_status_collect_changes_worktree(struct index_state *index, GList **results, const char *worktree); void wt_status_collect_untracked(struct index_state *index, GList **results, const char *worktree, IgnoreFunc ignore_func); void wt_status_collect_changes_index (struct index_state *index, GList **results, SeafRepo *repo); #endif /* STATUS_H */ seafile-6.1.5/daemon/sync-mgr.c000066400000000000000000003511151323477647300163270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include "db.h" #include "seafile-session.h" #include "seafile-config.h" #include "sync-mgr.h" #include "transfer-mgr.h" #include "processors/sync-repo-proc.h" #include "processors/getca-proc.h" #include "processors/check-protocol-proc.h" #include "vc-common.h" #include "seafile-error.h" #include "status.h" #include "mq-mgr.h" #include "utils.h" #include "vc-utils.h" #include "sync-status-tree.h" #ifdef WIN32 #include #endif #define DEBUG_FLAG SEAFILE_DEBUG_SYNC #include "log.h" #define DEFAULT_SYNC_INTERVAL 30 /* 30s */ #define CHECK_SYNC_INTERVAL 1000 /* 1s */ #define UPDATE_TX_STATE_INTERVAL 1000 /* 1s */ #define MAX_RUNNING_SYNC_TASKS 5 #define CHECK_LOCKED_FILES_INTERVAL 10 /* 10s */ #define CHECK_FOLDER_PERMS_INTERVAL 30 /* 30s */ enum { SERVER_SIDE_MERGE_UNKNOWN = 0, SERVER_SIDE_MERGE_SUPPORTED, SERVER_SIDE_MERGE_UNSUPPORTED, }; struct _ServerState { int server_side_merge; gboolean checking; }; typedef struct _ServerState ServerState; struct _HttpServerState { int http_version; gboolean checking; gint64 last_http_check_time; char *testing_host; /* Can be server_url or server_url:8082, depends on which one works. */ char *effective_host; gboolean use_fileserver_port; gboolean folder_perms_not_supported; gint64 last_check_perms_time; gboolean checking_folder_perms; gboolean locked_files_not_supported; gint64 last_check_locked_files_time; gboolean checking_locked_files; /* * repo_id -> head commit id mapping. * Caches the head commit ids of synced repos. */ GHashTable *head_commit_map; pthread_mutex_t head_commit_map_lock; gboolean head_commit_map_init; gint64 last_update_head_commit_map_time; }; typedef struct _HttpServerState HttpServerState; struct _SeafSyncManagerPriv { struct CcnetTimer *check_sync_timer; struct CcnetTimer *update_tx_state_timer; int pulse_count; /* When FALSE, auto sync is globally disabled */ gboolean auto_sync_enabled; GHashTable *active_paths; pthread_mutex_t paths_lock; #ifdef WIN32 GAsyncQueue *refresh_paths; struct CcnetTimer *refresh_windows_timer; #endif }; struct _ActivePathsInfo { GHashTable *paths; struct SyncStatusTree *syncing_tree; struct SyncStatusTree *synced_tree; }; typedef struct _ActivePathsInfo ActivePathsInfo; static void start_sync (SeafSyncManager *manager, SeafRepo *repo, gboolean need_commit, gboolean is_manual_sync, gboolean is_initial_commit); static int auto_sync_pulse (void *vmanager); static void on_repo_fetched (SeafileSession *seaf, TransferTask *tx_task, SeafSyncManager *manager); static void on_repo_uploaded (SeafileSession *seaf, TransferTask *tx_task, SeafSyncManager *manager); static void on_repo_http_fetched (SeafileSession *seaf, HttpTxTask *tx_task, SeafSyncManager *manager); static void on_repo_http_uploaded (SeafileSession *seaf, HttpTxTask *tx_task, SeafSyncManager *manager); static inline void transition_sync_state (SyncTask *task, int new_state); static void sync_task_free (SyncTask *task); static gboolean check_relay_status (SeafSyncManager *mgr, SeafRepo *repo); static int sync_repo_v2 (SeafSyncManager *manager, SeafRepo *repo, gboolean is_manual_sync); static gboolean check_http_protocol (SeafSyncManager *mgr, SeafRepo *repo); static void active_paths_info_free (ActivePathsInfo *info); static HttpServerState * http_server_state_new () { HttpServerState *state = g_new0 (HttpServerState, 1); state->head_commit_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); pthread_mutex_init (&state->head_commit_map_lock, NULL); return state; } static void http_server_state_free (HttpServerState *state) { if (!state) return; g_hash_table_destroy (state->head_commit_map); pthread_mutex_destroy (&state->head_commit_map_lock); g_free (state); } SeafSyncManager* seaf_sync_manager_new (SeafileSession *seaf) { SeafSyncManager *mgr = g_new0 (SeafSyncManager, 1); mgr->priv = g_new0 (SeafSyncManagerPriv, 1); mgr->priv->auto_sync_enabled = TRUE; mgr->seaf = seaf; mgr->sync_interval = DEFAULT_SYNC_INTERVAL; mgr->sync_infos = g_hash_table_new (g_str_hash, g_str_equal); mgr->server_states = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); mgr->http_server_states = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)http_server_state_free); gboolean exists; int download_limit = seafile_session_config_get_int (seaf, KEY_DOWNLOAD_LIMIT, &exists); if (exists) mgr->download_limit = download_limit; int upload_limit = seafile_session_config_get_int (seaf, KEY_UPLOAD_LIMIT, &exists); if (exists) mgr->upload_limit = upload_limit; mgr->priv->active_paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)active_paths_info_free); pthread_mutex_init (&mgr->priv->paths_lock, NULL); #ifdef WIN32 mgr->priv->refresh_paths = g_async_queue_new (); #endif return mgr; } static SyncInfo* get_sync_info (SeafSyncManager *manager, const char *repo_id) { SyncInfo *info = g_hash_table_lookup (manager->sync_infos, repo_id); if (info) return info; info = g_new0 (SyncInfo, 1); memcpy (info->repo_id, repo_id, 36); g_hash_table_insert (manager->sync_infos, info->repo_id, info); return info; } SyncInfo * seaf_sync_manager_get_sync_info (SeafSyncManager *mgr, const char *repo_id) { return g_hash_table_lookup (mgr->sync_infos, repo_id); } int seaf_sync_manager_init (SeafSyncManager *mgr) { return 0; } /* In case ccnet relay info is lost(e.g. ~/ccnet is removed), we need to * re-add the relay by supplying addr:port */ static void add_relay_if_needed (SeafRepo *repo) { CcnetPeer *relay = NULL; char *relay_port = NULL, *relay_addr = NULL; GString *buf = NULL; seaf_repo_manager_get_repo_relay_info (seaf->repo_mgr, repo->id, &relay_addr, &relay_port); relay = ccnet_get_peer (seaf->ccnetrpc_client, repo->relay_id); if (relay) { /* no relay addr/port info in seafile db. This means we are * updating from an old version. */ if (!relay_addr || !relay_port) { if (relay->public_addr && relay->public_port) { char port[16]; snprintf (port, sizeof(port), "%d", relay->public_port); seaf_repo_manager_set_repo_relay_info (seaf->repo_mgr, repo->id, relay->public_addr, port); } } goto out; } /* relay info is lost in ccnet, but we have its addr:port in seafile.db */ if (relay_addr && relay_port) { buf = g_string_new(NULL); g_string_append_printf (buf, "add-relay --id %s --addr %s:%s", repo->relay_id, relay_addr, relay_port); } else { seaf_warning ("[sync mgr] relay addr/port info" " of repo %.10s is unknown\n", repo->id); } if (buf) { ccnet_send_command (seaf->session, buf->str, NULL, NULL); } out: g_free (relay_addr); g_free (relay_port); if (relay) g_object_unref (relay); if (buf) g_string_free (buf, TRUE); } static void add_repo_relays () { GList *ptr, *repo_list; repo_list = seaf_repo_manager_get_repo_list (seaf->repo_mgr, 0, -1); for (ptr = repo_list; ptr; ptr = ptr->next) { SeafRepo *repo = ptr->data; /* Only use non-http sync protocol for old repos. * If no old repos exist, we don't need to connect to 10001 port. */ if (repo->version == 0 && repo->relay_id) { add_relay_if_needed (repo); } } g_list_free (repo_list); } static void format_transfer_task_detail (TransferTask *task, GString *buf) { if (task->state != TASK_STATE_NORMAL || task->runtime_state == TASK_RT_STATE_INIT || task->runtime_state == TASK_RT_STATE_FINISHED || task->runtime_state == TASK_RT_STATE_NETDOWN) return; SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); char *repo_name; char *type; if (repo) { repo_name = repo->name; type = (task->type == TASK_TYPE_UPLOAD) ? "upload" : "download"; } else if (task->is_clone) { CloneTask *ctask; ctask = seaf_clone_manager_get_task (seaf->clone_mgr, task->repo_id); repo_name = ctask->repo_name; type = "download"; } else { return; } int rate = transfer_task_get_rate(task); g_string_append_printf (buf, "%s\t%d %s\n", type, rate, repo_name); } static void format_http_task_detail (HttpTxTask *task, GString *buf) { if (task->state != HTTP_TASK_STATE_NORMAL || task->runtime_state == HTTP_TASK_RT_STATE_INIT || task->runtime_state == HTTP_TASK_RT_STATE_FINISHED) return; SeafRepo *repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); char *repo_name; char *type; if (repo) { repo_name = repo->name; type = (task->type == HTTP_TASK_TYPE_UPLOAD) ? "upload" : "download"; } else if (task->is_clone) { CloneTask *ctask; ctask = seaf_clone_manager_get_task (seaf->clone_mgr, task->repo_id); repo_name = ctask->repo_name; type = "download"; } else { return; } int rate = http_tx_task_get_rate(task); g_string_append_printf (buf, "%s\t%d %s\n", type, rate, repo_name); } /* * Publish a notification message to report : * * [uploading/downloading]\t[transfer-rate] [repo-name]\n */ static int update_tx_state (void *vmanager) { SeafSyncManager *mgr = vmanager; GString *buf = g_string_new (NULL); GList *tasks, *ptr; TransferTask *task; HttpTxTask *http_task; mgr->last_sent_bytes = g_atomic_int_get (&mgr->sent_bytes); g_atomic_int_set (&mgr->sent_bytes, 0); mgr->last_recv_bytes = g_atomic_int_get (&mgr->recv_bytes); g_atomic_int_set (&mgr->recv_bytes, 0); tasks = seaf_transfer_manager_get_upload_tasks (seaf->transfer_mgr); for (ptr = tasks; ptr; ptr = ptr->next) { task = ptr->data; format_transfer_task_detail (task, buf); } g_list_free (tasks); tasks = seaf_transfer_manager_get_download_tasks (seaf->transfer_mgr); for (ptr = tasks; ptr; ptr = ptr->next) { task = ptr->data; format_transfer_task_detail (task, buf); } g_list_free (tasks); tasks = http_tx_manager_get_upload_tasks (seaf->http_tx_mgr); for (ptr = tasks; ptr; ptr = ptr->next) { http_task = ptr->data; format_http_task_detail (http_task, buf); } g_list_free (tasks); tasks = http_tx_manager_get_download_tasks (seaf->http_tx_mgr); for (ptr = tasks; ptr; ptr = ptr->next) { http_task = ptr->data; format_http_task_detail (http_task, buf); } g_list_free (tasks); if (buf->len != 0) seaf_mq_manager_publish_notification (seaf->mq_mgr, "transfer", buf->str); g_string_free (buf, TRUE); return TRUE; } #ifdef WIN32 static void * refresh_windows_explorer_thread (void *vdata); #define STARTUP_REFRESH_WINDOWS_DELAY 10000 static int refresh_all_windows_on_startup (void *vdata) { /* This is a hack to tell Windows Explorer to refresh all open windows. * On startup, if there is one big library, its events may dominate the * explorer refresh queue. Other libraries don't get refreshed until * the big library's events are consumed. So we refresh the open windows * to reduce the delay. */ SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); /* One time */ return 0; } #endif static void *update_cached_head_commit_ids (void *arg); int seaf_sync_manager_start (SeafSyncManager *mgr) { add_repo_relays (); mgr->priv->check_sync_timer = ccnet_timer_new ( auto_sync_pulse, mgr, CHECK_SYNC_INTERVAL); mgr->priv->update_tx_state_timer = ccnet_timer_new ( update_tx_state, mgr, UPDATE_TX_STATE_INTERVAL); ccnet_proc_factory_register_processor (mgr->seaf->session->proc_factory, "seafile-sync-repo", SEAFILE_TYPE_SYNC_REPO_PROC); ccnet_proc_factory_register_processor (mgr->seaf->session->proc_factory, "seafile-getca", SEAFILE_TYPE_GETCA_PROC); ccnet_proc_factory_register_processor (mgr->seaf->session->proc_factory, "seafile-check-protocol", SEAFILE_TYPE_CHECK_PROTOCOL_PROC); g_signal_connect (seaf, "repo-fetched", (GCallback)on_repo_fetched, mgr); g_signal_connect (seaf, "repo-uploaded", (GCallback)on_repo_uploaded, mgr); g_signal_connect (seaf, "repo-http-fetched", (GCallback)on_repo_http_fetched, mgr); g_signal_connect (seaf, "repo-http-uploaded", (GCallback)on_repo_http_uploaded, mgr); #ifdef WIN32 ccnet_job_manager_schedule_job (seaf->job_mgr, refresh_windows_explorer_thread, NULL, mgr->priv->refresh_paths); mgr->priv->refresh_windows_timer = ccnet_timer_new ( refresh_all_windows_on_startup, mgr, STARTUP_REFRESH_WINDOWS_DELAY); #endif pthread_t tid; if (pthread_create (&tid, NULL, update_cached_head_commit_ids, mgr) < 0) { seaf_warning ("Failed to create update cached head commit id thread.\n"); return -1; } return 0; } int seaf_sync_manager_add_sync_task (SeafSyncManager *mgr, const char *repo_id, GError **error) { if (!seaf->started) { seaf_message ("sync manager is not started, skip sync request.\n"); return -1; } SeafRepo *repo; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { seaf_warning ("[sync mgr] cannot find repo %s.\n", repo_id); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_REPO, "Invalid repo"); return -1; } if (seaf_repo_check_worktree (repo) < 0) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_NO_WORKTREE, "Worktree doesn't exist"); return -1; } #ifdef USE_GPL_CRYPTO if (repo->version == 0 || (repo->encrypted && repo->enc_version < 2)) { seaf_warning ("Don't support syncing old version libraries.\n"); g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Don't support syncing old version libraries"); return -1; } #endif SyncInfo *info = get_sync_info (mgr, repo->id); if (info->in_sync) return 0; if (repo->version > 0) { if (check_http_protocol (mgr, repo)) { sync_repo_v2 (mgr, repo, TRUE); return 0; } } else { /* If relay is not ready or protocol version is not determined, * need to wait. */ if (!check_relay_status (mgr, repo)) { seaf_warning ("Relay for repo %s(%.8s) is not ready or protocol version" "is not detected.\n", repo->name, repo->id); return 0; } start_sync (mgr, repo, TRUE, TRUE, FALSE); } return 0; } void seaf_sync_manager_cancel_sync_task (SeafSyncManager *mgr, const char *repo_id) { SyncInfo *info; SyncTask *task; if (!seaf->started) { seaf_message ("sync manager is not started, skip cancel request.\n"); return; } /* Cancel running task. */ info = g_hash_table_lookup (mgr->sync_infos, repo_id); if (!info || !info->in_sync) return; g_return_if_fail (info->current_task != NULL); task = info->current_task; switch (task->state) { case SYNC_STATE_FETCH: if (!task->http_sync) seaf_transfer_manager_cancel_task (seaf->transfer_mgr, task->tx_id, TASK_TYPE_DOWNLOAD); else http_tx_manager_cancel_task (seaf->http_tx_mgr, repo_id, HTTP_TASK_TYPE_DOWNLOAD); transition_sync_state (task, SYNC_STATE_CANCEL_PENDING); break; case SYNC_STATE_UPLOAD: if (!task->http_sync) seaf_transfer_manager_cancel_task (seaf->transfer_mgr, task->tx_id, TASK_TYPE_UPLOAD); else http_tx_manager_cancel_task (seaf->http_tx_mgr, repo_id, HTTP_TASK_TYPE_UPLOAD); transition_sync_state (task, SYNC_STATE_CANCEL_PENDING); break; case SYNC_STATE_COMMIT: case SYNC_STATE_INIT: case SYNC_STATE_MERGE: transition_sync_state (task, SYNC_STATE_CANCEL_PENDING); break; case SYNC_STATE_CANCEL_PENDING: break; default: g_return_if_reached (); } } /* Check the notify setting by user. */ static gboolean need_notify_sync (SeafRepo *repo) { char *notify_setting = seafile_session_config_get_string(seaf, "notify_sync"); if (notify_setting == NULL) { seafile_session_config_set_string(seaf, "notify_sync", "on"); return TRUE; } gboolean result = (g_strcmp0(notify_setting, "on") == 0); g_free (notify_setting); return result; } static const char *sync_state_str[] = { "synchronized", "committing", "initializing", "downloading", "merging", "uploading", "error", "canceled", "cancel pending" }; static gboolean find_meaningful_commit (SeafCommit *commit, void *data, gboolean *stop) { SeafCommit **p_head = data; if (commit->second_parent_id && commit->new_merge && !commit->conflict) return TRUE; *stop = TRUE; seaf_commit_ref (commit); *p_head = commit; return TRUE; } static void notify_sync (SeafRepo *repo, gboolean is_multipart_upload) { SeafCommit *head = NULL; if (!seaf_commit_manager_traverse_commit_tree_truncated (seaf->commit_mgr, repo->id, repo->version, repo->head->commit_id, find_meaningful_commit, &head, FALSE)) { seaf_warning ("Failed to traverse commit tree of %.8s.\n", repo->id); return; } if (!head) return; GString *buf = g_string_new (NULL); g_string_append_printf (buf, "%s\t%s\t%s\t%s\t%s", repo->name, repo->id, head->commit_id, head->parent_id, head->desc); if (!is_multipart_upload) seaf_mq_manager_publish_notification (seaf->mq_mgr, "sync.done", buf->str); else seaf_mq_manager_publish_notification (seaf->mq_mgr, "sync.multipart_upload", buf->str); g_string_free (buf, TRUE); seaf_commit_unref (head); } #define IN_ERROR_THRESHOLD 3 static void update_sync_info_error_state (SyncTask *task, int new_state) { SyncInfo *info = task->info; if (new_state == SYNC_STATE_ERROR) { info->err_cnt++; if (info->err_cnt == IN_ERROR_THRESHOLD) info->in_error = TRUE; } else if (info->err_cnt > 0) { info->err_cnt = 0; info->in_error = FALSE; } } static void commit_repo (SyncTask *task); static inline void transition_sync_state (SyncTask *task, int new_state) { g_return_if_fail (new_state >= 0 && new_state < SYNC_STATE_NUM); SyncInfo *info = task->info; if (task->state != new_state) { if (!task->server_side_merge) { if ((task->state == SYNC_STATE_MERGE || task->state == SYNC_STATE_UPLOAD) && new_state == SYNC_STATE_DONE && need_notify_sync(task->repo)) notify_sync (task->repo, FALSE); } else { if (((task->state == SYNC_STATE_INIT && task->uploaded) || task->state == SYNC_STATE_FETCH) && new_state == SYNC_STATE_DONE && need_notify_sync(task->repo)) notify_sync (task->repo, (info->multipart_upload && !info->end_multipart_upload)); } /* If we're in the process of uploading large set of files, they'll be splitted * into multiple batches for upload. We want to immediately start the next batch * after previous one is done. */ if (new_state == SYNC_STATE_DONE && info->multipart_upload && !info->end_multipart_upload) { commit_repo (task); return; } if (!(task->state == SYNC_STATE_DONE && new_state == SYNC_STATE_INIT) && !(task->state == SYNC_STATE_INIT && new_state == SYNC_STATE_DONE)) { seaf_message ("Repo '%s' sync state transition from '%s' to '%s'.\n", task->repo->name, sync_state_str[task->state], sync_state_str[new_state]); } task->state = new_state; if (new_state == SYNC_STATE_DONE || new_state == SYNC_STATE_CANCELED || new_state == SYNC_STATE_ERROR) { info->in_sync = FALSE; --(task->mgr->n_running_tasks); update_sync_info_error_state (task, new_state); /* Keep previous upload progress if sync task is canceled or failed. */ if (new_state == SYNC_STATE_DONE) { info->multipart_upload = FALSE; info->end_multipart_upload = FALSE; info->total_bytes = 0; info->uploaded_bytes = 0; } } #ifdef WIN32 seaf_sync_manager_add_refresh_path (seaf->sync_mgr, task->repo->worktree); #endif } } static const char *sync_error_str[] = { "Success", "relay not connected", "failed to upgrade old repo", "Server has been removed", "You have not login to the server", "Remote service is not available", "You do not have permission to access this library", "The storage space of the repo owner has been used up", "Access denied to service. Please check your registration on relay.", "Internal data corrupted.", "Failed to start upload.", "Error occured in upload.", "Failed to start download.", "Error occured in download.", "No such repo on relay.", "Repo is damaged on relay.", "Failed to index files.", "Conflict in merge.", "Files changed in local folder, skip merge.", "Server version is too old.", "Failed to get sync info from server.", "Files are locked by other application", "Unknown error.", }; void seaf_sync_manager_set_task_error (SyncTask *task, int error) { g_return_if_fail (error >= 0 && error < SYNC_ERROR_NUM); if (task->state != SYNC_STATE_ERROR) { seaf_message ("Repo '%s' sync state transition from %s to '%s': '%s'.\n", task->repo->name, sync_state_str[task->state], sync_state_str[SYNC_STATE_ERROR], sync_error_str[error]); task->state = SYNC_STATE_ERROR; task->error = error; task->info->in_sync = FALSE; --(task->mgr->n_running_tasks); update_sync_info_error_state (task, SYNC_STATE_ERROR); #ifdef WIN32 seaf_sync_manager_add_refresh_path (seaf->sync_mgr, task->repo->worktree); #endif #if 0 if (task->repo && error != SYNC_ERROR_RELAY_OFFLINE && error != SYNC_ERROR_NOREPO) { GString *buf = g_string_new (NULL); g_string_append_printf (buf, "%s\t%s", task->repo->name, task->repo->id); seaf_mq_manager_publish_notification (seaf->mq_mgr, "sync.error", buf->str); g_string_free (buf, TRUE); } #endif } } static void sync_task_free (SyncTask *task) { g_free (task->tx_id); g_free (task->dest_id); g_free (task->token); g_free (task->err_detail); g_free (task); } static void start_upload_if_necessary (SyncTask *task) { GError *error = NULL; SeafRepo *repo = task->repo; const char *repo_id = task->repo->id; if (!task->http_sync) { char *tx_id = seaf_transfer_manager_add_upload (seaf->transfer_mgr, repo_id, task->repo->version, task->dest_id, "local", "master", task->token, task->server_side_merge, &error); if (error != NULL) { seaf_warning ("Failed to start upload: %s\n", error->message); seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_UPLOAD); return; } task->tx_id = tx_id; } else { if (http_tx_manager_add_upload (seaf->http_tx_mgr, repo->id, repo->version, repo->effective_host, repo->token, task->http_version, repo->use_fileserver_port, &error) < 0) { seaf_warning ("Failed to start http upload: %s\n", error->message); seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_UPLOAD); return; } task->tx_id = g_strdup(repo->id); } transition_sync_state (task, SYNC_STATE_UPLOAD); } static void start_fetch_if_necessary (SyncTask *task, const char *remote_head) { GError *error = NULL; char *tx_id; SeafRepo *repo = task->repo; const char *repo_id = task->repo->id; if (!task->http_sync) { tx_id = seaf_transfer_manager_add_download (seaf->transfer_mgr, repo_id, task->repo->version, task->dest_id, "fetch_head", "master", task->token, task->server_side_merge, NULL, NULL, repo->email, &error); if (error != NULL) { seaf_warning ("[sync-mgr] Failed to start download: %s\n", error->message); seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_FETCH); return; } task->tx_id = tx_id; } else { if (http_tx_manager_add_download (seaf->http_tx_mgr, repo->id, repo->version, repo->effective_host, repo->token, remote_head, FALSE, NULL, NULL, task->http_version, repo->email, repo->use_fileserver_port, repo->name, &error) < 0) { seaf_warning ("Failed to start http download: %s.\n", error->message); seaf_sync_manager_set_task_error (task, SYNC_ERROR_START_FETCH); return; } task->tx_id = g_strdup(repo->id); } transition_sync_state (task, SYNC_STATE_FETCH); } struct MergeResult { SyncTask *task; gboolean success; int merge_status; gboolean worktree_dirty; }; static void * merge_job (void *vtask) { SyncTask *task = vtask; SeafRepo *repo = task->repo; char *err_msg = NULL; struct MergeResult *res = g_new0 (struct MergeResult, 1); res->task = task; if (repo->delete_pending) { seaf_message ("Repo %s was deleted, don't need to merge.\n", repo->id); return res; } /* * 4 types of errors may occur: * 1. merge conflicts; * 2. fail to checkout a file because the worktree file has been changed; * 3. Files are locked on Windows; * 4. other I/O errors. * * For 1, the next commit operation will make worktree clean. * For 2 and 4, the errors are ignored by the merge routine (return 0). * For 3, just wait another merge retry. * */ if (seaf_repo_merge (repo, "master", &err_msg, &res->merge_status) < 0) { seaf_message ("[Sync mgr] Merge of repo %s(%.8s) is not clean.\n", repo->name, repo->id); res->success = FALSE; g_free (err_msg); return res; } res->success = TRUE; g_free (err_msg); seaf_message ("[Sync mgr] Merged repo %s(%.8s).\n", repo->name, repo->id); return res; } static void merge_job_done (void *vresult) { struct MergeResult *res = vresult; SeafRepo *repo = res->task->repo; if (repo->delete_pending) { transition_sync_state (res->task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); g_free (res); return; } if (res->task->state == SYNC_STATE_CANCEL_PENDING) { transition_sync_state (res->task, SYNC_STATE_CANCELED); g_free (res); return; } if (res->success) { SeafBranch *local; SeafBranch *master = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "master"); if (!master) { seaf_warning ("[sync mgr] master branch doesn't exist.\n"); seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_DATA_CORRUPT); goto out; } /* Save head commit id of master branch for GC, since we've * checked out the blocks on the master branch. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD, master->commit_id); seaf_branch_unref (master); /* If it's a ff merge, also update REPO_LOCAL_HEAD. */ switch (res->merge_status) { case MERGE_STATUS_FAST_FORWARD: local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("[sync mgr] local branch doesn't exist.\n"); seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_DATA_CORRUPT); goto out; } seaf_repo_manager_set_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD, local->commit_id); seaf_branch_unref (local); transition_sync_state (res->task, SYNC_STATE_DONE); break; case MERGE_STATUS_REAL_MERGE: start_upload_if_necessary (res->task); break; case MERGE_STATUS_UPTODATE: transition_sync_state (res->task, SYNC_STATE_DONE); break; } } else if (res->worktree_dirty) seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_WORKTREE_DIRTY); else seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_MERGE); out: g_free (res); } static void merge_branches_if_necessary (SyncTask *task) { SeafRepo *repo = task->repo; /* Repo is not checked out yet. */ if (!repo->head) { transition_sync_state (task, SYNC_STATE_DONE); return; } transition_sync_state (task, SYNC_STATE_MERGE); ccnet_job_manager_schedule_job (seaf->job_mgr, merge_job, merge_job_done, task); } typedef struct { char remote_id[41]; char last_uploaded[41]; char last_checkout[41]; gboolean result; } CheckFFData; static gboolean check_fast_forward (SeafCommit *commit, void *vdata, gboolean *stop) { CheckFFData *data = vdata; if (strcmp (commit->commit_id, data->remote_id) == 0) { *stop = TRUE; data->result = TRUE; return TRUE; } if (strcmp (commit->commit_id, data->last_uploaded) == 0 || strcmp (commit->commit_id, data->last_checkout) == 0) { *stop = TRUE; return TRUE; } return TRUE; } static gboolean check_fast_forward_with_limit (SeafRepo *repo, const char *local_id, const char *remote_id, const char *last_uploaded, const char *last_checkout, gboolean *error) { CheckFFData data; memset (&data, 0, sizeof(data)); memcpy (data.remote_id, remote_id, 40); memcpy (data.last_uploaded, last_uploaded, 40); memcpy (data.last_checkout, last_checkout, 40); *error = FALSE; if (!seaf_commit_manager_traverse_commit_tree_truncated (seaf->commit_mgr, repo->id, repo->version, local_id, check_fast_forward, &data, FALSE)) { seaf_warning ("Failed to traverse commit tree from %s.\n", local_id); *error = TRUE; return FALSE; } return data.result; } static void getca_done_cb (CcnetProcessor *processor, gboolean success, void *data) { SyncTask *task = data; SyncInfo *info = task->info; SeafRepo *repo = task->repo; SeafileGetcaProc *proc = (SeafileGetcaProc *)processor; SeafBranch *master; if (repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); return; } if (task->state == SYNC_STATE_CANCEL_PENDING) { transition_sync_state (task, SYNC_STATE_CANCELED); return; } if (!success) { switch (processor->failure) { case PROC_NO_SERVICE: seaf_warning ("Server doesn't support putca-proc.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DEPRECATED_SERVER); break; case GETCA_PROC_ACCESS_DENIED: seaf_warning ("No permission to access repo %.8s.\n", repo->id); seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED); break; case GETCA_PROC_NO_CA: seaf_warning ("Compute common ancestor failed for %.8s.\n", repo->id); seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); break; case PROC_REMOTE_DEAD: seaf_sync_manager_set_task_error (task, SYNC_ERROR_SERVICE_DOWN); break; case PROC_PERM_ERR: seaf_sync_manager_set_task_error (task, SYNC_ERROR_PROC_PERM_ERR); break; case PROC_DONE: /* It can never happen */ g_return_if_reached (); case PROC_BAD_RESP: case PROC_NOTSET: default: seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); } return; } seaf_repo_manager_set_common_ancestor (seaf->repo_mgr, repo->id, proc->ca_id, repo->head->commit_id); master = seaf_branch_manager_get_branch (seaf->branch_mgr, info->repo_id, "master"); if (!master || strcmp (info->head_commit, master->commit_id) != 0) { start_fetch_if_necessary (task, NULL); } else if (strcmp (repo->head->commit_id, master->commit_id) != 0) { /* Try to merge even if we don't need to fetch. */ merge_branches_if_necessary (task); } seaf_branch_unref (master); } static int start_get_ca_proc (SyncTask *task, const char *repo_id) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getca", task->dest_id); if (!processor) { seaf_warning ("[sync-mgr] failed to create getca proc.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); return -1; } if (ccnet_processor_startl (processor, repo_id, task->token, NULL) < 0) { seaf_warning ("[sync-mgr] failed to start getca proc.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); return -1; } g_signal_connect (processor, "done", (GCallback)getca_done_cb, task); return 0; } /* Return TURE if we started a processor, otherwise return FALSE. */ static gboolean update_common_ancestor (SyncTask *task, const char *last_uploaded, const char *last_checkout) { SeafRepo *repo = task->repo; char *local_head = repo->head->commit_id; char ca_id[41], cached_head_id[41]; /* If common ancestor result is not cached, we need to compute it. */ if (seaf_repo_manager_get_common_ancestor (seaf->repo_mgr, repo->id, ca_id, cached_head_id) < 0) goto update_common_ancestor; /* If the head id is unchanged, use the cached common ancestor id directly. * Common ancestor won't change if the local head is not updated. */ if (strcmp (cached_head_id, local_head) == 0) { seaf_debug ("Use cached common ancestor.\n"); return FALSE; } update_common_ancestor: if (strcmp (last_uploaded, local_head) == 0 || strcmp (last_checkout, local_head) == 0) { seaf_debug ("Use local head as common ancestor.\n"); seaf_repo_manager_set_common_ancestor (seaf->repo_mgr, repo->id, local_head, local_head); return FALSE; } start_get_ca_proc (task, repo->id); return TRUE; } static gboolean repo_block_store_exists (SeafRepo *repo) { gboolean ret; char *store_path = g_build_filename (seaf->seaf_dir, "storage", "blocks", repo->id, NULL); if (g_file_test (store_path, G_FILE_TEST_IS_DIR)) ret = TRUE; else ret = FALSE; g_free (store_path); return ret; } #ifdef WIN32 static GHashTable * load_locked_files_blocks (const char *repo_id) { LockedFileSet *fset; GHashTable *block_id_hash; GHashTableIter iter; gpointer key, value; LockedFile *locked; Seafile *file; int i; char *blk_id; fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo_id); block_id_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_iter_init (&iter, fset->locked_files); while (g_hash_table_iter_next (&iter, &key, &value)) { locked = value; if (strcmp (locked->operation, LOCKED_OP_UPDATE) == 0) { file = seaf_fs_manager_get_seafile (seaf->fs_mgr, fset->repo_id, 1, locked->file_id); if (!file) { seaf_warning ("Failed to find file %s in repo %.8s.\n", locked->file_id, fset->repo_id); continue; } for (i = 0; i < file->n_blocks; ++i) { blk_id = g_strdup (file->blk_sha1s[i]); g_hash_table_replace (block_id_hash, blk_id, blk_id); } seafile_unref (file); } } locked_file_set_free (fset); return block_id_hash; } static gboolean remove_block_cb (const char *store_id, int version, const char *block_id, void *user_data) { GHashTable *block_hash = user_data; if (!g_hash_table_lookup (block_hash, block_id)) seaf_block_manager_remove_block (seaf->block_mgr, store_id, version, block_id); return TRUE; } #endif static void * remove_repo_blocks (void *vtask) { SyncTask *task = vtask; #ifndef WIN32 seaf_block_manager_remove_store (seaf->block_mgr, task->repo->id); #else GHashTable *block_hash; block_hash = load_locked_files_blocks (task->repo->id); if (g_hash_table_size (block_hash) == 0) { g_hash_table_destroy (block_hash); seaf_block_manager_remove_store (seaf->block_mgr, task->repo->id); return vtask; } seaf_block_manager_foreach_block (seaf->block_mgr, task->repo->id, task->repo->version, remove_block_cb, block_hash); g_hash_table_destroy (block_hash); #endif return vtask; } static void remove_blocks_done (void *vtask) { SyncTask *task = vtask; transition_sync_state (task, SYNC_STATE_DONE); } static void on_repo_deleted_on_server (SyncTask *task, SeafRepo *repo) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_NOREPO); seaf_warning ("repo %s(%.8s) not found on server\n", repo->name, repo->id); if (!seafile_session_config_get_allow_repo_not_found_on_server(seaf)) { seaf_message ("remove repo %s(%.8s) since it's deleted on relay\n", repo->name, repo->id); seaf_mq_manager_publish_notification (seaf->mq_mgr, "repo.deleted_on_relay", repo->name); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); } } static void update_sync_status (SyncTask *task) { SyncInfo *info = task->info; SeafRepo *repo = task->repo; SeafBranch *master, *local; char *last_uploaded = NULL, *last_checkout = NULL; local = seaf_branch_manager_get_branch ( seaf->branch_mgr, info->repo_id, "local"); if (!local) { seaf_warning ("[sync-mgr] Branch local not found for repo %s(%.8s).\n", repo->name, repo->id); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); return; } master = seaf_branch_manager_get_branch ( seaf->branch_mgr, info->repo_id, "master"); last_uploaded = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, REPO_LOCAL_HEAD); if (!last_uploaded) { seaf_warning ("Last uploaded commit id is not found in db.\n"); seaf_branch_unref (local); seaf_branch_unref (master); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); return; } last_checkout = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, REPO_REMOTE_HEAD); if (!last_checkout) { seaf_warning ("Last checked out commit id is not found in db.\n"); seaf_branch_unref (local); seaf_branch_unref (master); g_free (last_uploaded); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); return; } if (info->repo_corrupted) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_REPO_CORRUPT); } else if (info->deleted_on_relay) { /* First upload. */ if (!master) start_upload_if_necessary (task); /* If repo doesn't exist on relay and we have "master", * it was deleted on relay. In this case we remove this repo. */ else on_repo_deleted_on_server (task, repo); } else { /* branch deleted on relay */ if (info->branch_deleted_on_relay) { start_upload_if_necessary (task); goto out; } /* If local head is the same as remote head, already in sync. */ if (strcmp (local->commit_id, info->head_commit) == 0) { /* As long as the repo is synced with the server. All the local * blocks are not useful any more. */ if (repo_block_store_exists (repo)) { /* seaf_message ("Removing blocks for repo %s(%.8s).\n", */ /* repo->name, repo->id); */ ccnet_job_manager_schedule_job (seaf->job_mgr, remove_repo_blocks, remove_blocks_done, task); } else transition_sync_state (task, SYNC_STATE_DONE); goto out; } /* This checking is done in the main thread. But it usually doesn't take * much time, because the traversing is limited by last_uploaded and * last_checkout commits. */ gboolean error = FALSE; gboolean is_ff = check_fast_forward_with_limit (repo, local->commit_id, info->head_commit, last_uploaded, last_checkout, &error); if (error) { seaf_warning ("Failed to check fast forward.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); goto out; } /* fast-forward upload */ if (is_ff) { start_upload_if_necessary (task); goto out; } /* * We have to compute the common ancestor before doing merge. * The last result of computation is cached in local db. * Check if we need to re-compute the common ancestor. * If so we'll start a processor to do that on the server. * For repo version == 0, we download all commits so there is no * need to check. */ if (repo->version > 0 && update_common_ancestor (task, last_uploaded, last_checkout)) goto out; if (!master || strcmp (info->head_commit, master->commit_id) != 0) { start_fetch_if_necessary (task, NULL); } else if (strcmp (local->commit_id, master->commit_id) != 0) { /* Try to merge even if we don't need to fetch. */ merge_branches_if_necessary (task); } } out: seaf_branch_unref (local); if (master) seaf_branch_unref (master); g_free (last_uploaded); g_free (last_checkout); } static void update_sync_status_v2 (SyncTask *task) { SyncInfo *info = task->info; SeafRepo *repo = task->repo; SeafBranch *master = NULL, *local = NULL; local = seaf_branch_manager_get_branch ( seaf->branch_mgr, info->repo_id, "local"); if (!local) { seaf_warning ("[sync-mgr] Branch local not found for repo %s(%.8s).\n", repo->name, repo->id); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); return; } master = seaf_branch_manager_get_branch ( seaf->branch_mgr, info->repo_id, "master"); if (!master) { seaf_warning ("[sync-mgr] Branch master not found for repo %s(%.8s).\n", repo->name, repo->id); seaf_sync_manager_set_task_error (task, SYNC_ERROR_DATA_CORRUPT); return; } if (info->repo_corrupted) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_REPO_CORRUPT); } else if (info->deleted_on_relay) { on_repo_deleted_on_server (task, repo); } else { /* If local head is the same as remote head, already in sync. */ if (strcmp (local->commit_id, info->head_commit) == 0) { /* As long as the repo is synced with the server. All the local * blocks are not useful any more. */ if (repo_block_store_exists (repo)) { seaf_message ("Removing blocks for repo %s(%.8s).\n", repo->name, repo->id); ccnet_job_manager_schedule_job (seaf->job_mgr, remove_repo_blocks, remove_blocks_done, task); } else transition_sync_state (task, SYNC_STATE_DONE); } else start_fetch_if_necessary (task, task->info->head_commit); } seaf_branch_unref (local); seaf_branch_unref (master); } static void sync_done_cb (CcnetProcessor *processor, gboolean success, void *data) { SyncTask *task = data; SeafRepo *repo = task->repo; if (repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); return; } if (task->state == SYNC_STATE_CANCEL_PENDING) { transition_sync_state (task, SYNC_STATE_CANCELED); return; } if (!success) { switch (processor->failure) { case PROC_DONE: /* It can never happen */ g_return_if_reached (); case PROC_REMOTE_DEAD: case PROC_NO_SERVICE: seaf_sync_manager_set_task_error (task, SYNC_ERROR_SERVICE_DOWN); break; case PROC_PERM_ERR: seaf_sync_manager_set_task_error (task, SYNC_ERROR_PROC_PERM_ERR); break; case PROC_BAD_RESP: case PROC_NOTSET: default: seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); } return; } if (!task->server_side_merge) update_sync_status (task); else update_sync_status_v2 (task); } /* The sync-repo processor is used to check the head commit at the server side. */ static int start_sync_repo_proc (SeafSyncManager *manager, SyncTask *task) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sync-repo", task->dest_id); if (!processor) { seaf_warning ("[sync-mgr] failed to create get seafile-sync-repo proc.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); return -1; } ((SeafileSyncRepoProc *)processor)->task = task; if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("[sync-mgr] failed to start get seafile-sync-repo proc.\n"); seaf_sync_manager_set_task_error (task, SYNC_ERROR_UNKNOWN); return -1; } g_signal_connect (processor, "done", (GCallback)sync_done_cb, task); transition_sync_state (task, SYNC_STATE_INIT); return 0; } static void check_head_commit_done (HttpHeadCommit *result, void *user_data) { SyncTask *task = user_data; SyncInfo *info = task->info; if (!result->check_success) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_GET_SYNC_INFO); task->err_detail = g_strdup(http_task_error_str(result->error_code)); return; } info->deleted_on_relay = result->is_deleted; info->repo_corrupted = result->is_corrupt; memcpy (info->head_commit, result->head_commit, 40); update_sync_status_v2 (task); } static int check_head_commit_http (SyncTask *task) { SeafRepo *repo = task->repo; int ret = http_tx_manager_check_head_commit (seaf->http_tx_mgr, repo->id, repo->version, repo->effective_host, repo->token, repo->use_fileserver_port, check_head_commit_done, task); if (ret == 0) transition_sync_state (task, SYNC_STATE_INIT); else if (ret < 0) seaf_sync_manager_set_task_error (task, SYNC_ERROR_GET_SYNC_INFO); return ret; } struct CommitResult { SyncTask *task; gboolean changed; gboolean success; }; static void * commit_job (void *vtask) { SyncTask *task = vtask; SeafRepo *repo = task->repo; struct CommitResult *res = g_new0 (struct CommitResult, 1); GError *error = NULL; res->task = task; if (repo->delete_pending) return res; res->changed = TRUE; res->success = TRUE; char *commit_id = seaf_repo_index_commit (repo, "", task->is_manual_sync, task->is_initial_commit, &error); if (commit_id == NULL && error != NULL) { seaf_warning ("[Sync mgr] Failed to commit to repo %s(%.8s).\n", repo->name, repo->id); res->success = FALSE; } else if (commit_id == NULL) { res->changed = FALSE; } g_free (commit_id); return res; } static void commit_job_done (void *vres) { struct CommitResult *res = vres; SeafRepo *repo = res->task->repo; SyncTask *task = res->task; res->task->mgr->commit_job_running = FALSE; if (repo->delete_pending) { transition_sync_state (res->task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, repo); g_free (res); return; } if (res->task->state == SYNC_STATE_CANCEL_PENDING) { transition_sync_state (res->task, SYNC_STATE_CANCELED); g_free (res); return; } if (!res->success) { seaf_sync_manager_set_task_error (res->task, SYNC_ERROR_COMMIT); g_free (res); return; } if (!res->task->server_side_merge) { /* If nothing committed and is not manual sync, no need to sync. */ if (!res->changed && !res->task->is_manual_sync && !res->task->is_initial_commit) { transition_sync_state (res->task, SYNC_STATE_DONE); g_free (res); return; } start_sync_repo_proc (res->task->mgr, res->task); } else { if (res->changed) start_upload_if_necessary (res->task); else if (task->is_manual_sync || task->is_initial_commit) { if (task->http_sync) check_head_commit_http (task); else start_sync_repo_proc (task->mgr, task); } else transition_sync_state (task, SYNC_STATE_DONE); } g_free (res); } static int check_commit_state (void *data); static void commit_repo (SyncTask *task) { /* In order not to eat too much CPU power, only one commit job can be run * at the same time. Other sync tasks have to check every 1 second. */ if (task->mgr->commit_job_running) { task->commit_timer = ccnet_timer_new (check_commit_state, task, 1000); return; } task->mgr->commit_job_running = TRUE; transition_sync_state (task, SYNC_STATE_COMMIT); if (ccnet_job_manager_schedule_job (seaf->job_mgr, commit_job, commit_job_done, task) < 0) seaf_sync_manager_set_task_error (task, SYNC_ERROR_COMMIT); } static int check_commit_state (void *data) { SyncTask *task = data; if (!task->mgr->commit_job_running) { ccnet_timer_free (&task->commit_timer); commit_repo (task); return 0; } return 1; } static void start_sync (SeafSyncManager *manager, SeafRepo *repo, gboolean need_commit, gboolean is_manual_sync, gboolean is_initial_commit) { SyncTask *task = g_new0 (SyncTask, 1); SyncInfo *info; info = get_sync_info (manager, repo->id); task->info = info; task->mgr = manager; task->dest_id = g_strdup(repo->relay_id); task->token = g_strdup(repo->token); task->is_manual_sync = is_manual_sync; task->is_initial_commit = is_initial_commit; repo->last_sync_time = time(NULL); ++(manager->n_running_tasks); /* Free the last task when a new task is started. * This way we can always get the state of the last task even * after it's done. */ if (task->info->current_task) sync_task_free (task->info->current_task); task->info->current_task = task; task->info->in_sync = TRUE; task->repo = repo; if (need_commit) { repo->create_partial_commit = FALSE; commit_repo (task); } else start_sync_repo_proc (manager, task); } static int sync_repo (SeafSyncManager *manager, SeafRepo *repo) { WTStatus *status; gint now = (gint)time(NULL); gint last_changed; status = seaf_wt_monitor_get_worktree_status (manager->seaf->wt_monitor, repo->id); if (status) { last_changed = g_atomic_int_get (&status->last_changed); if (status->last_check == 0) { /* Force commit and sync after a new repo is added. */ start_sync (manager, repo, TRUE, FALSE, TRUE); status->last_check = now; wt_status_unref (status); return 0; } else if (last_changed != 0 && status->last_check <= last_changed) { /* Commit and sync if the repo has been updated after the * last check and is not updated for the last 2 seconds. */ if (now - last_changed >= 2) { start_sync (manager, repo, TRUE, FALSE, FALSE); status->last_check = now; wt_status_unref (status); return 0; } } wt_status_unref (status); } if (manager->n_running_tasks >= MAX_RUNNING_SYNC_TASKS) return -1; if (repo->last_sync_time > now - manager->sync_interval) return -1; start_sync (manager, repo, FALSE, FALSE, FALSE); return 0; } static SyncTask * create_sync_task_v2 (SeafSyncManager *manager, SeafRepo *repo, gboolean is_manual_sync, gboolean is_initial_commit) { SyncTask *task = g_new0 (SyncTask, 1); SyncInfo *info; info = get_sync_info (manager, repo->id); task->info = info; task->mgr = manager; task->dest_id = g_strdup (repo->relay_id); task->token = g_strdup(repo->token); task->is_manual_sync = is_manual_sync; task->is_initial_commit = is_initial_commit; task->server_side_merge = TRUE; repo->last_sync_time = time(NULL); ++(manager->n_running_tasks); /* Free the last task when a new task is started. * This way we can always get the state of the last task even * after it's done. */ if (task->info->current_task) sync_task_free (task->info->current_task); task->info->current_task = task; task->info->in_sync = TRUE; task->repo = repo; if (repo->server_url) { HttpServerState *state = g_hash_table_lookup (manager->http_server_states, repo->server_url); if (state) { task->http_sync = TRUE; task->http_version = state->http_version; } } return task; } static gboolean create_commit_from_event_queue (SeafSyncManager *manager, SeafRepo *repo, gboolean is_manual_sync) { WTStatus *status; SyncTask *task; gboolean ret = FALSE; gint now = (gint)time(NULL); gint last_changed; status = seaf_wt_monitor_get_worktree_status (manager->seaf->wt_monitor, repo->id); if (status) { last_changed = g_atomic_int_get (&status->last_changed); if (status->last_check == 0) { /* Force commit and sync after a new repo is added. */ task = create_sync_task_v2 (manager, repo, is_manual_sync, TRUE); repo->create_partial_commit = TRUE; commit_repo (task); status->last_check = now; ret = TRUE; } else if (status->partial_commit) { task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); repo->create_partial_commit = TRUE; commit_repo (task); ret = TRUE; } else if (last_changed != 0 && status->last_check <= last_changed) { /* Commit and sync if the repo has been updated after the * last check and is not updated for the last 2 seconds. */ if (now - last_changed >= 2) { task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); repo->create_partial_commit = TRUE; commit_repo (task); status->last_check = now; ret = TRUE; } } wt_status_unref (status); } return ret; } static gboolean can_schedule_repo (SeafSyncManager *manager, SeafRepo *repo) { int now = (int)time(NULL); return ((repo->last_sync_time == 0 || repo->last_sync_time < now - manager->sync_interval) && manager->n_running_tasks < MAX_RUNNING_SYNC_TASKS); } static gboolean need_check_on_server (SeafSyncManager *manager, SeafRepo *repo, const char *master_head_id) { #define HEAD_COMMIT_MAP_TTL 90 HttpServerState *state; gboolean ret = FALSE; SyncInfo *info; /* If sync state is in error, always retry. */ info = get_sync_info (manager, repo->id); if (info && info->current_task && info->current_task->state == SYNC_STATE_ERROR) return TRUE; state = g_hash_table_lookup (manager->http_server_states, repo->server_url); if (!state) return TRUE; pthread_mutex_lock (&state->head_commit_map_lock); if (!state->head_commit_map_init) { ret = TRUE; goto out; } gint64 now = (gint64)time(NULL); if (now - state->last_update_head_commit_map_time >= HEAD_COMMIT_MAP_TTL) { ret = TRUE; goto out; } char *server_head = g_hash_table_lookup (state->head_commit_map, repo->id); if (!server_head) { /* Repo was removed on server. Just return "changed on server". */ ret = TRUE; goto out; } if (g_strcmp0 (server_head, master_head_id) != 0) ret = TRUE; out: pthread_mutex_unlock (&state->head_commit_map_lock); return ret; } static int sync_repo_v2 (SeafSyncManager *manager, SeafRepo *repo, gboolean is_manual_sync) { SeafBranch *master, *local; SyncTask *task; int ret = 0; char *last_download = NULL; master = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "master"); if (!master) { seaf_warning ("No master branch found for repo %s(%.8s).\n", repo->name, repo->id); return -1; } local = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "local"); if (!local) { seaf_warning ("No local branch found for repo %s(%.8s).\n", repo->name, repo->id); return -1; } /* If last download was interrupted in the fetch and download stage, * need to resume it at exactly the same remote commit. */ last_download = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_DOWNLOAD_HEAD); if (last_download && strcmp (last_download, EMPTY_SHA1) != 0) { if (is_manual_sync || can_schedule_repo (manager, repo)) { task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); start_fetch_if_necessary (task, last_download); } goto out; } if (strcmp (master->commit_id, local->commit_id) != 0) { if (is_manual_sync || can_schedule_repo (manager, repo)) { task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); start_upload_if_necessary (task); } /* Do nothing if the client still has something to upload * but it's before 30-second schedule. */ goto out; } else if (is_manual_sync) { task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); commit_repo (task); goto out; } else if (create_commit_from_event_queue (manager, repo, is_manual_sync)) goto out; if (is_manual_sync || can_schedule_repo (manager, repo)) { /* If file syncing protocol version is higher than 2, we check for all head commit ids * for synced repos regularly. */ if (!is_manual_sync && !need_check_on_server (manager, repo, master->commit_id)) { seaf_debug ("Repo %s is not changed on server %s.\n", repo->name, repo->server_url); repo->last_sync_time = time(NULL); goto out; } task = create_sync_task_v2 (manager, repo, is_manual_sync, FALSE); if (task->http_sync) check_head_commit_http (task); else start_sync_repo_proc (manager, task); } out: g_free (last_download); seaf_branch_unref (master); seaf_branch_unref (local); return ret; } static void auto_delete_repo (SeafSyncManager *manager, SeafRepo *repo) { SyncInfo *info = seaf_sync_manager_get_sync_info (manager, repo->id); char *name = g_strdup (repo->name); seaf_message ("Auto deleted repo '%s'.\n", repo->name); seaf_sync_manager_cancel_sync_task (seaf->sync_mgr, repo->id); if (info != NULL && info->in_sync) { seaf_repo_manager_mark_repo_deleted (seaf->repo_mgr, repo); } else { seaf_repo_manager_del_repo (seaf->repo_mgr, repo); } /* Publish a message, for applet to notify in the system tray */ seaf_mq_manager_publish_notification (seaf->mq_mgr, "repo.removed", name); g_free (name); } static void check_protocol_done_cb (CcnetProcessor *processor, gboolean success, void *data) { ServerState *state = data; state->checking = FALSE; if (success) state->server_side_merge = SERVER_SIDE_MERGE_SUPPORTED; else if (processor->failure == PROC_NO_SERVICE) /* Talking to an old server. */ state->server_side_merge = SERVER_SIDE_MERGE_UNSUPPORTED; } static int start_check_protocol_proc (SeafSyncManager *manager, const char *peer_id, ServerState *state) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-check-protocol", peer_id); if (!processor) { seaf_warning ("[sync-mgr] failed to create get seafile-check-protocol proc.\n"); return -1; } if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("[sync-mgr] failed to start seafile-check-protocol proc.\n"); return -1; } g_signal_connect (processor, "done", (GCallback)check_protocol_done_cb, state); return 0; } static gboolean check_relay_status (SeafSyncManager *mgr, SeafRepo *repo) { gboolean is_ready = ccnet_peer_is_ready (seaf->ccnetrpc_client, repo->relay_id); ServerState *state = g_hash_table_lookup (mgr->server_states, repo->relay_id); if (!state) { state = g_new0 (ServerState, 1); g_hash_table_insert (mgr->server_states, g_strdup(repo->relay_id), state); } if (is_ready) { if (state->server_side_merge == SERVER_SIDE_MERGE_UNKNOWN) { if (!state->checking) { start_check_protocol_proc (mgr, repo->relay_id, state); state->checking = TRUE; } return FALSE; } else return TRUE; } else { if (state->server_side_merge == SERVER_SIDE_MERGE_UNKNOWN) return FALSE; else { /* Reset protocol_version to unknown so that we'll check it * after the server is up again. */ state->server_side_merge = SERVER_SIDE_MERGE_UNKNOWN; return FALSE; } } } static char * http_fileserver_url (const char *url) { const char *host; char *colon; char *url_no_port; char *ret = NULL; /* Just return the url itself if it's invalid. */ if (strlen(url) <= strlen("http://")) return g_strdup(url); /* Skip protocol schem. */ host = url + strlen("http://"); colon = strrchr (host, ':'); if (colon) { url_no_port = g_strndup(url, colon - url); ret = g_strconcat(url_no_port, ":8082", NULL); g_free (url_no_port); } else { ret = g_strconcat(url, ":8082", NULL); } return ret; } static void check_http_fileserver_protocol_done (HttpProtocolVersion *result, void *user_data) { HttpServerState *state = user_data; state->checking = FALSE; if (result->check_success && !result->not_supported) { state->http_version = MIN(result->version, CURRENT_SYNC_PROTO_VERSION); state->effective_host = http_fileserver_url(state->testing_host); state->use_fileserver_port = TRUE; seaf_message ("File syncing protocol version on server %s is %d. " "Client file syncing protocol version is %d. Use version %d.\n", state->effective_host, result->version, CURRENT_SYNC_PROTO_VERSION, state->http_version); } } static void check_http_protocol_done (HttpProtocolVersion *result, void *user_data) { HttpServerState *state = user_data; if (result->check_success && !result->not_supported) { state->http_version = MIN(result->version, CURRENT_SYNC_PROTO_VERSION); state->effective_host = g_strdup(state->testing_host); state->checking = FALSE; seaf_message ("File syncing protocol version on server %s is %d. " "Client file syncing protocol version is %d. Use version %d.\n", state->effective_host, result->version, CURRENT_SYNC_PROTO_VERSION, state->http_version); } else if (strncmp(state->testing_host, "https", 5) != 0) { char *host_fileserver = http_fileserver_url(state->testing_host); if (http_tx_manager_check_protocol_version (seaf->http_tx_mgr, host_fileserver, TRUE, check_http_fileserver_protocol_done, state) < 0) state->checking = FALSE; g_free (host_fileserver); } else { state->checking = FALSE; } } #define CHECK_HTTP_INTERVAL 10 /* * Returns TRUE if we're ready to use http-sync; otherwise FALSE. */ static gboolean check_http_protocol (SeafSyncManager *mgr, SeafRepo *repo) { /* If a repo was cloned before 4.0, server-url is not set. */ if (!repo->server_url) return FALSE; HttpServerState *state = g_hash_table_lookup (mgr->http_server_states, repo->server_url); if (!state) { state = http_server_state_new (); g_hash_table_insert (mgr->http_server_states, g_strdup(repo->server_url), state); } if (state->checking) { return FALSE; } if (state->http_version > 0) { if (!repo->effective_host) { repo->effective_host = g_strdup(state->effective_host); repo->use_fileserver_port = state->use_fileserver_port; } return TRUE; } /* If we haven't detected the server url successfully, retry every 10 seconds. */ gint64 now = time(NULL); if (now - state->last_http_check_time < CHECK_HTTP_INTERVAL) return FALSE; /* First try repo->server_url. * If it fails and https is not used, try server_url:8082 instead. */ g_free (state->testing_host); state->testing_host = g_strdup(repo->server_url); state->last_http_check_time = (gint64)time(NULL); if (http_tx_manager_check_protocol_version (seaf->http_tx_mgr, repo->server_url, FALSE, check_http_protocol_done, state) < 0) return FALSE; state->checking = TRUE; return FALSE; } gint cmp_repos_by_sync_time (gconstpointer a, gconstpointer b, gpointer user_data) { const SeafRepo *repo_a = a; const SeafRepo *repo_b = b; return (repo_a->last_sync_time - repo_b->last_sync_time); } #ifdef WIN32 static void cleanup_file_blocks (const char *repo_id, int version, const char *file_id) { Seafile *file; int i; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo_id, version, file_id); for (i = 0; i < file->n_blocks; ++i) seaf_block_manager_remove_block (seaf->block_mgr, repo_id, version, file->blk_sha1s[i]); seafile_unref (file); } static gboolean handle_locked_file_update (SeafRepo *repo, struct index_state *istate, LockedFileSet *fset, const char *path, LockedFile *locked) { gboolean locked_on_server = FALSE; struct cache_entry *ce; char file_id[41]; char *fullpath = NULL; SeafStat st; gboolean file_exists = TRUE; SeafileCrypt *crypt = NULL; SeafBranch *master = NULL; gboolean ret = TRUE; locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo->id, path); /* File is still locked, do nothing. */ if (do_check_file_locked (path, repo->worktree, locked_on_server)) return FALSE; seaf_debug ("Update previously locked file %s in repo %.8s.\n", path, repo->id); /* If the file was locked on the last checkout, the worktree file was not * updated, but the index has been updated. So the ce in the index should * contain the information for the file to be updated. */ ce = index_name_exists (istate, path, strlen(path), 0); if (!ce) { seaf_warning ("Cache entry for %s in repo %s(%.8s) is not found " "when update locked file.", path, repo->name, repo->id); goto remove_from_db; } rawdata_to_hex (ce->sha1, file_id, 20); fullpath = g_build_filename (repo->worktree, path, NULL); file_exists = seaf_util_exists (fullpath); if (file_exists && seaf_stat (fullpath, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", fullpath, strerror(errno)); goto out; } if (repo->encrypted) crypt = seafile_crypt_new (repo->enc_version, repo->enc_key, repo->enc_iv); master = seaf_branch_manager_get_branch (seaf->branch_mgr, repo->id, "master"); if (!master) { seaf_warning ("No master branch found for repo %s(%.8s).\n", repo->name, repo->id); goto out; } gboolean conflicted; gboolean force_conflict = (file_exists && st.st_mtime != locked->old_mtime); if (seaf_fs_manager_checkout_file (seaf->fs_mgr, repo->id, repo->version, file_id, fullpath, ce->ce_mode, ce->ce_mtime.sec, crypt, path, master->commit_id, force_conflict, &conflicted, repo->email) < 0) { seaf_warning ("Failed to checkout previously locked file %s in repo " "%s(%.8s).\n", path, repo->name, repo->id); } seaf_sync_manager_update_active_path (seaf->sync_mgr, repo->id, path, S_IFREG, SYNC_STATUS_SYNCED); /* In checkout, the file was overwritten by rename, so the file attributes are gone. We have to set read-only state again. */ if (locked_on_server) seaf_filelock_manager_lock_wt_file (seaf->filelock_mgr, repo->id, path); out: cleanup_file_blocks (repo->id, repo->version, file_id); remove_from_db: /* Remove the locked file record from db. */ locked_file_set_remove (fset, path, TRUE); g_free (fullpath); g_free (crypt); seaf_branch_unref (master); return ret; } static gboolean handle_locked_file_delete (SeafRepo *repo, struct index_state *istate, LockedFileSet *fset, const char *path, LockedFile *locked) { gboolean locked_on_server = FALSE; char *fullpath = NULL; SeafStat st; gboolean file_exists = TRUE; gboolean ret = TRUE; locked_on_server = seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo->id, path); /* File is still locked, do nothing. */ if (do_check_file_locked (path, repo->worktree, locked_on_server)) return FALSE; seaf_debug ("Delete previously locked file %s in repo %.8s.\n", path, repo->id); fullpath = g_build_filename (repo->worktree, path, NULL); file_exists = seaf_util_exists (fullpath); if (file_exists && seaf_stat (fullpath, &st) < 0) { seaf_warning ("Failed to stat %s: %s.\n", fullpath, strerror(errno)); goto out; } if (file_exists && st.st_mtime == locked->old_mtime) seaf_util_unlink (fullpath); out: /* Remove the locked file record from db. */ locked_file_set_remove (fset, path, TRUE); g_free (fullpath); return ret; } static void * check_locked_files (void *vdata) { SeafRepo *repo = vdata; LockedFileSet *fset; GHashTableIter iter; gpointer key, value; char *path; LockedFile *locked; char index_path[SEAF_PATH_MAX]; struct index_state istate; fset = seaf_repo_manager_get_locked_file_set (seaf->repo_mgr, repo->id); if (g_hash_table_size (fset->locked_files) == 0) { locked_file_set_free (fset); return vdata; } memset (&istate, 0, sizeof(istate)); snprintf (index_path, SEAF_PATH_MAX, "%s/%s", repo->manager->index_dir, repo->id); if (read_index_from (&istate, index_path, repo->version) < 0) { seaf_warning ("Failed to load index.\n"); return vdata; } gboolean success; g_hash_table_iter_init (&iter, fset->locked_files); while (g_hash_table_iter_next (&iter, &key, &value)) { path = key; locked = value; success = FALSE; if (strcmp (locked->operation, LOCKED_OP_UPDATE) == 0) success = handle_locked_file_update (repo, &istate, fset, path, locked); else if (strcmp (locked->operation, LOCKED_OP_DELETE) == 0) success = handle_locked_file_delete (repo, &istate, fset, path, locked); if (success) g_hash_table_iter_remove (&iter); } discard_index (&istate); locked_file_set_free (fset); return vdata; } static void check_locked_files_done (void *vdata) { SeafRepo *repo = vdata; repo->checking_locked_files = FALSE; } #endif static void check_folder_perms_done (HttpFolderPerms *result, void *user_data) { HttpServerState *server_state = user_data; GList *ptr; HttpFolderPermRes *res; gint64 now = (gint64)time(NULL); server_state->checking_folder_perms = FALSE; if (!result->success) { /* If on star-up we find that checking folder perms fails, * we assume the server doesn't support it. */ if (server_state->last_check_perms_time == 0) server_state->folder_perms_not_supported = TRUE; server_state->last_check_perms_time = now; return; } SyncInfo *info; for (ptr = result->results; ptr; ptr = ptr->next) { res = ptr->data; info = get_sync_info (seaf->sync_mgr, res->repo_id); if (info->in_sync) continue; seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_USER, res->user_perms); seaf_repo_manager_update_folder_perms (seaf->repo_mgr, res->repo_id, FOLDER_PERM_TYPE_GROUP, res->group_perms); seaf_repo_manager_update_folder_perm_timestamp (seaf->repo_mgr, res->repo_id, res->timestamp); } server_state->last_check_perms_time = now; } static void check_folder_permissions_one_server (SeafSyncManager *mgr, const char *host, HttpServerState *server_state, GList *repos) { GList *ptr; SeafRepo *repo; char *token; gint64 timestamp; HttpFolderPermReq *req; GList *requests = NULL; if (!seaf_repo_manager_server_is_pro (seaf->repo_mgr, host)) return; gint64 now = (gint64)time(NULL); if (server_state->http_version == 0 || server_state->folder_perms_not_supported || server_state->checking_folder_perms) return; if (server_state->last_check_perms_time > 0 && now - server_state->last_check_perms_time < CHECK_FOLDER_PERMS_INTERVAL) return; for (ptr = repos; ptr; ptr = ptr->next) { repo = ptr->data; if (!repo->head) continue; if (g_strcmp0 (host, repo->server_url) != 0) continue; token = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_TOKEN); if (!token) continue; timestamp = seaf_repo_manager_get_folder_perm_timestamp (seaf->repo_mgr, repo->id); if (timestamp < 0) timestamp = 0; req = g_new0 (HttpFolderPermReq, 1); memcpy (req->repo_id, repo->id, 36); req->token = g_strdup(token); req->timestamp = timestamp; requests = g_list_append (requests, req); g_free (token); } if (!requests) return; server_state->checking_folder_perms = TRUE; /* The requests list will be freed in http tx manager. */ if (http_tx_manager_get_folder_perms (seaf->http_tx_mgr, server_state->effective_host, server_state->use_fileserver_port, requests, check_folder_perms_done, server_state) < 0) { seaf_warning ("Failed to schedule check folder permissions\n"); server_state->checking_folder_perms = FALSE; } } static void check_folder_permissions (SeafSyncManager *mgr, GList *repos) { GHashTableIter iter; gpointer key, value; char *host; HttpServerState *state; g_hash_table_iter_init (&iter, mgr->http_server_states); while (g_hash_table_iter_next (&iter, &key, &value)) { host = key; state = value; check_folder_permissions_one_server (mgr, host, state, repos); } } static void check_server_locked_files_done (HttpLockedFiles *result, void *user_data) { HttpServerState *server_state = user_data; GList *ptr; HttpLockedFilesRes *locked_res; gint64 now = (gint64)time(NULL); server_state->checking_locked_files = FALSE; if (!result->success) { /* If on star-up we find that checking locked files fails, * we assume the server doesn't support it. */ if (server_state->last_check_locked_files_time == 0) server_state->locked_files_not_supported = TRUE; server_state->last_check_locked_files_time = now; return; } SyncInfo *info; for (ptr = result->results; ptr; ptr = ptr->next) { locked_res = ptr->data; info = get_sync_info (seaf->sync_mgr, locked_res->repo_id); if (info->in_sync) continue; seaf_filelock_manager_update (seaf->filelock_mgr, locked_res->repo_id, locked_res->locked_files); seaf_filelock_manager_update_timestamp (seaf->filelock_mgr, locked_res->repo_id, locked_res->timestamp); } server_state->last_check_locked_files_time = now; } static void check_locked_files_one_server (SeafSyncManager *mgr, const char *host, HttpServerState *server_state, GList *repos) { GList *ptr; SeafRepo *repo; char *token; gint64 timestamp; HttpLockedFilesReq *req; GList *requests = NULL; if (!seaf_repo_manager_server_is_pro (seaf->repo_mgr, host)) return; gint64 now = (gint64)time(NULL); if (server_state->http_version == 0 || server_state->locked_files_not_supported || server_state->checking_locked_files) return; if (server_state->last_check_locked_files_time > 0 && now - server_state->last_check_locked_files_time < CHECK_FOLDER_PERMS_INTERVAL) return; for (ptr = repos; ptr; ptr = ptr->next) { repo = ptr->data; if (!repo->head) continue; if (g_strcmp0 (host, repo->server_url) != 0) continue; token = seaf_repo_manager_get_repo_property (seaf->repo_mgr, repo->id, REPO_PROP_TOKEN); if (!token) continue; timestamp = seaf_filelock_manager_get_timestamp (seaf->filelock_mgr, repo->id); if (timestamp < 0) timestamp = 0; req = g_new0 (HttpLockedFilesReq, 1); memcpy (req->repo_id, repo->id, 36); req->token = g_strdup(token); req->timestamp = timestamp; requests = g_list_append (requests, req); g_free (token); } if (!requests) return; server_state->checking_locked_files = TRUE; /* The requests list will be freed in http tx manager. */ if (http_tx_manager_get_locked_files (seaf->http_tx_mgr, server_state->effective_host, server_state->use_fileserver_port, requests, check_server_locked_files_done, server_state) < 0) { seaf_warning ("Failed to schedule check server locked files\n"); server_state->checking_locked_files = FALSE; } } static void check_server_locked_files (SeafSyncManager *mgr, GList *repos) { GHashTableIter iter; gpointer key, value; char *host; HttpServerState *state; g_hash_table_iter_init (&iter, mgr->http_server_states); while (g_hash_table_iter_next (&iter, &key, &value)) { host = key; state = value; check_locked_files_one_server (mgr, host, state, repos); } } #if 0 static void print_active_paths (SeafSyncManager *mgr) { int n = seaf_sync_manager_active_paths_number(mgr); seaf_message ("%d active paths\n\n", n); if (n < 10) { char *paths_json = seaf_sync_manager_list_active_paths_json (mgr); seaf_message ("%s\n", paths_json); g_free (paths_json); } } #endif inline static gboolean periodic_sync_due (SeafRepo *repo) { int now = (int)time(NULL); return (now > (repo->last_sync_time + repo->sync_interval)); } static int auto_sync_pulse (void *vmanager) { SeafSyncManager *manager = vmanager; GList *repos, *ptr; SeafRepo *repo; repos = seaf_repo_manager_get_repo_list (manager->seaf->repo_mgr, -1, -1); check_folder_permissions (manager, repos); check_server_locked_files (manager, repos); /* Sort repos by last_sync_time, so that we don't "starve" any repo. */ repos = g_list_sort_with_data (repos, cmp_repos_by_sync_time, NULL); for (ptr = repos; ptr != NULL; ptr = ptr->next) { repo = ptr->data; /* Every second, we'll check the worktree to see if it still exists. * We'll invalidate worktree if it gets moved or deleted. * But there is a hole here: If the user delete the worktree dir and * recreate a dir with the same name within a second, we'll falsely * see the worktree as valid. What's worse, the new worktree dir won't * be monitored. * This problem can only be solved by restart. */ /* If repo has been checked out and the worktree doesn't exist, * we'll delete the repo automatically. */ if (repo->head != NULL) { if (seaf_repo_check_worktree (repo) < 0) { if (!repo->worktree_invalid) { // The repo worktree was valid, but now it's invalid seaf_repo_manager_invalidate_repo_worktree (seaf->repo_mgr, repo); if (!seafile_session_config_get_allow_invalid_worktree(seaf)) { auto_delete_repo (manager, repo); } } continue; } else { if (repo->worktree_invalid) { // The repo worktree was invalid, but now it's valid again, // so we start watch it seaf_repo_manager_validate_repo_worktree (seaf->repo_mgr, repo); continue; } } } repo->worktree_invalid = FALSE; #ifdef USE_GPL_CRYPTO if (repo->version == 0 || (repo->encrypted && repo->enc_version < 2)) { continue; } #endif if (!repo->token) { /* If the user has logged out of the account, the repo token would * be null */ seaf_debug ("repo token of %s (%.8s) is null, would not sync it\n", repo->name, repo->id); continue; } /* Don't sync repos not checked out yet. */ if (!repo->head) continue; if (!manager->priv->auto_sync_enabled || !repo->auto_sync) continue; #ifdef WIN32 if (repo->version > 0) { if (repo->checking_locked_files) continue; gint64 now = (gint64)time(NULL); if (repo->last_check_locked_time == 0 || now - repo->last_check_locked_time >= CHECK_LOCKED_FILES_INTERVAL) { repo->checking_locked_files = TRUE; if (ccnet_job_manager_schedule_job (seaf->job_mgr, check_locked_files, check_locked_files_done, repo) < 0) { seaf_warning ("Failed to schedule check local locked files\n"); repo->checking_locked_files = FALSE; } else { repo->last_check_locked_time = now; } } } #endif SyncInfo *info = get_sync_info (manager, repo->id); if (info->in_sync) continue; if (repo->version > 0) { /* For repo version > 0, only use http sync. */ if (check_http_protocol (manager, repo)) { if (repo->sync_interval == 0) sync_repo_v2 (manager, repo, FALSE); else if (periodic_sync_due (repo)) sync_repo_v2 (manager, repo, TRUE); } } else { /* If relay is not ready or protocol version is not determined, * need to wait. */ if (check_relay_status (manager, repo)) sync_repo (manager, repo); } } g_list_free (repos); return TRUE; } inline static void send_sync_error_notification (SeafRepo *repo, const char *type) { GString *buf = g_string_new (NULL); g_string_append_printf (buf, "%s\t%s", repo->name, repo->id); seaf_mq_manager_publish_notification (seaf->mq_mgr, type, buf->str); g_string_free (buf, TRUE); } static void on_repo_fetched (SeafileSession *seaf, TransferTask *tx_task, SeafSyncManager *manager) { SyncInfo *info = get_sync_info (manager, tx_task->repo_id); SyncTask *task = info->current_task; /* Clone tasks are handled by clone manager. */ if (tx_task->is_clone) return; if (task->repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, task->repo); return; } if (tx_task->state == TASK_STATE_FINISHED) { memcpy (info->head_commit, tx_task->head, 41); if (!task->server_side_merge) merge_branches_if_necessary (task); else transition_sync_state (task, SYNC_STATE_DONE); } else if (tx_task->state == TASK_STATE_CANCELED) { transition_sync_state (task, SYNC_STATE_CANCELED); } else if (tx_task->state == TASK_STATE_ERROR) { if (tx_task->error == TASK_ERR_ACCESS_DENIED) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED); if (!task->repo->access_denied_notified) { send_sync_error_notification (task->repo, "sync.access_denied"); task->repo->access_denied_notified = 1; } } else if (tx_task->error == TASK_ERR_FILES_LOCKED) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_FILES_LOCKED); } else seaf_sync_manager_set_task_error (task, SYNC_ERROR_FETCH); } } static void on_repo_uploaded (SeafileSession *seaf, TransferTask *tx_task, SeafSyncManager *manager) { SyncInfo *info = get_sync_info (manager, tx_task->repo_id); SyncTask *task = info->current_task; g_return_if_fail (task != NULL && info->in_sync); if (task->repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, task->repo); return; } if (tx_task->state == TASK_STATE_FINISHED) { memcpy (info->head_commit, tx_task->head, 41); /* Save current head commit id for GC. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo->id, REPO_LOCAL_HEAD, task->repo->head->commit_id); if (!task->server_side_merge) transition_sync_state (task, SYNC_STATE_DONE); else { task->uploaded = TRUE; if (!task->http_sync) start_sync_repo_proc (manager, task); else check_head_commit_http (task); } } else if (tx_task->state == TASK_STATE_CANCELED) { transition_sync_state (task, SYNC_STATE_CANCELED); } else if (tx_task->state == TASK_STATE_ERROR) { if (tx_task->error == TASK_ERR_ACCESS_DENIED) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED); if (!task->repo->access_denied_notified) { send_sync_error_notification (task->repo, "sync.access_denied"); task->repo->access_denied_notified = 1; } } else if (tx_task->error == TASK_ERR_QUOTA_FULL) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_QUOTA_FULL); /* Only notify "quota full" once. */ if (!task->repo->quota_full_notified) { send_sync_error_notification (task->repo, "sync.quota_full"); task->repo->quota_full_notified = 1; } } else seaf_sync_manager_set_task_error (task, SYNC_ERROR_UPLOAD); } } static void on_repo_http_fetched (SeafileSession *seaf, HttpTxTask *tx_task, SeafSyncManager *manager) { SyncInfo *info = get_sync_info (manager, tx_task->repo_id); SyncTask *task = info->current_task; /* Clone tasks are handled by clone manager. */ if (tx_task->is_clone) return; if (task->repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, task->repo); return; } if (tx_task->state == HTTP_TASK_STATE_FINISHED) { memcpy (info->head_commit, tx_task->head, 41); transition_sync_state (task, SYNC_STATE_DONE); } else if (tx_task->state == HTTP_TASK_STATE_CANCELED) { transition_sync_state (task, SYNC_STATE_CANCELED); } else if (tx_task->state == HTTP_TASK_STATE_ERROR) { if (tx_task->error == HTTP_TASK_ERR_FORBIDDEN) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED); if (!task->repo->access_denied_notified) { send_sync_error_notification (task->repo, "sync.access_denied"); task->repo->access_denied_notified = 1; } } else if (tx_task->error == HTTP_TASK_ERR_FILES_LOCKED) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_FILES_LOCKED); } else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) { on_repo_deleted_on_server (task, task->repo); } else seaf_sync_manager_set_task_error (task, SYNC_ERROR_FETCH); task->err_detail = g_strdup(http_task_error_str(tx_task->error)); } } static void on_repo_http_uploaded (SeafileSession *seaf, HttpTxTask *tx_task, SeafSyncManager *manager) { SyncInfo *info = get_sync_info (manager, tx_task->repo_id); SyncTask *task = info->current_task; g_return_if_fail (task != NULL && info->in_sync); if (task->repo->delete_pending) { transition_sync_state (task, SYNC_STATE_CANCELED); seaf_repo_manager_del_repo (seaf->repo_mgr, task->repo); return; } if (tx_task->state == HTTP_TASK_STATE_FINISHED) { memcpy (info->head_commit, tx_task->head, 41); /* Save current head commit id for GC. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo->id, REPO_LOCAL_HEAD, task->repo->head->commit_id); task->uploaded = TRUE; check_head_commit_http (task); } else if (tx_task->state == HTTP_TASK_STATE_CANCELED) { transition_sync_state (task, SYNC_STATE_CANCELED); } else if (tx_task->state == HTTP_TASK_STATE_ERROR) { if (tx_task->error == HTTP_TASK_ERR_FORBIDDEN) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_ACCESS_DENIED); if (!task->repo->access_denied_notified) { send_sync_error_notification (task->repo, "sync.access_denied"); task->repo->access_denied_notified = 1; } } else if (tx_task->error == HTTP_TASK_ERR_NO_QUOTA) { seaf_sync_manager_set_task_error (task, SYNC_ERROR_QUOTA_FULL); /* Only notify "quota full" once. */ if (!task->repo->quota_full_notified) { send_sync_error_notification (task->repo, "sync.quota_full"); task->repo->quota_full_notified = 1; } } else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) { on_repo_deleted_on_server (task, task->repo); } else seaf_sync_manager_set_task_error (task, SYNC_ERROR_UPLOAD); task->err_detail = g_strdup(http_task_error_str(tx_task->error)); } } const char * sync_error_to_str (int error) { if (error < 0 || error >= SYNC_ERROR_NUM) { seaf_warning ("illegal sync error: %d\n", error); return NULL; } return sync_error_str[error]; } const char * sync_state_to_str (int state) { if (state < 0 || state >= SYNC_STATE_NUM) { seaf_warning ("illegal sync state: %d\n", state); return NULL; } return sync_state_str[state]; } static void disable_auto_sync_for_repos (SeafSyncManager *mgr) { GList *repos; GList *ptr; SeafRepo *repo; repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, -1, -1); for (ptr = repos; ptr; ptr = ptr->next) { repo = ptr->data; if (repo->sync_interval == 0) seaf_wt_monitor_unwatch_repo (seaf->wt_monitor, repo->id); seaf_sync_manager_cancel_sync_task (mgr, repo->id); seaf_sync_manager_remove_active_path_info (mgr, repo->id); } g_list_free (repos); } int seaf_sync_manager_disable_auto_sync (SeafSyncManager *mgr) { if (!seaf->started) { seaf_message ("sync manager is not started, skip disable auto sync.\n"); return -1; } disable_auto_sync_for_repos (mgr); mgr->priv->auto_sync_enabled = FALSE; g_debug ("[sync mgr] auto sync is disabled\n"); return 0; } static void enable_auto_sync_for_repos (SeafSyncManager *mgr) { GList *repos; GList *ptr; SeafRepo *repo; repos = seaf_repo_manager_get_repo_list (seaf->repo_mgr, -1, -1); for (ptr = repos; ptr; ptr = ptr->next) { repo = ptr->data; if (repo->sync_interval == 0) seaf_wt_monitor_watch_repo (seaf->wt_monitor, repo->id, repo->worktree); } g_list_free (repos); } int seaf_sync_manager_enable_auto_sync (SeafSyncManager *mgr) { if (!seaf->started) { seaf_message ("sync manager is not started, skip enable auto sync.\n"); return -1; } enable_auto_sync_for_repos (mgr); mgr->priv->auto_sync_enabled = TRUE; g_debug ("[sync mgr] auto sync is enabled\n"); return 0; } int seaf_sync_manager_is_auto_sync_enabled (SeafSyncManager *mgr) { if (mgr->priv->auto_sync_enabled) return 1; else return 0; } static ActivePathsInfo * active_paths_info_new (SeafRepo *repo) { ActivePathsInfo *info = g_new0 (ActivePathsInfo, 1); info->paths = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); info->syncing_tree = sync_status_tree_new (repo->worktree); info->synced_tree = sync_status_tree_new (repo->worktree); return info; } static void active_paths_info_free (ActivePathsInfo *info) { if (!info) return; g_hash_table_destroy (info->paths); sync_status_tree_free (info->syncing_tree); sync_status_tree_free (info->synced_tree); g_free (info); } void seaf_sync_manager_update_active_path (SeafSyncManager *mgr, const char *repo_id, const char *path, int mode, SyncStatus status) { ActivePathsInfo *info; SeafRepo *repo; if (!repo_id || !path) { seaf_warning ("BUG: empty repo_id or path.\n"); return; } if (status <= SYNC_STATUS_NONE || status >= N_SYNC_STATUS) { seaf_warning ("BUG: invalid sync status %d.\n", status); return; } pthread_mutex_lock (&mgr->priv->paths_lock); info = g_hash_table_lookup (mgr->priv->active_paths, repo_id); if (!info) { repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { pthread_mutex_unlock (&mgr->priv->paths_lock); return; } info = active_paths_info_new (repo); g_hash_table_insert (mgr->priv->active_paths, g_strdup(repo_id), info); } SyncStatus existing = (SyncStatus) g_hash_table_lookup (info->paths, path); if (!existing) { g_hash_table_insert (info->paths, g_strdup(path), (void*)status); if (status == SYNC_STATUS_SYNCING) sync_status_tree_add (info->syncing_tree, path, mode); else if (status == SYNC_STATUS_SYNCED) sync_status_tree_add (info->synced_tree, path, mode); else { #ifdef WIN32 seaf_sync_manager_add_refresh_path (mgr, path); #endif } } else if (existing != status) { g_hash_table_replace (info->paths, g_strdup(path), (void*)status); if (existing == SYNC_STATUS_SYNCING) sync_status_tree_del (info->syncing_tree, path); else if (existing == SYNC_STATUS_SYNCED) sync_status_tree_del (info->synced_tree, path); if (status == SYNC_STATUS_SYNCING) sync_status_tree_add (info->syncing_tree, path, mode); else if (status == SYNC_STATUS_SYNCED) sync_status_tree_add (info->synced_tree, path, mode); #ifdef WIN32 seaf_sync_manager_add_refresh_path (mgr, path); #endif } pthread_mutex_unlock (&mgr->priv->paths_lock); } void seaf_sync_manager_delete_active_path (SeafSyncManager *mgr, const char *repo_id, const char *path) { ActivePathsInfo *info; if (!repo_id || !path) { seaf_warning ("BUG: empty repo_id or path.\n"); return; } pthread_mutex_lock (&mgr->priv->paths_lock); info = g_hash_table_lookup (mgr->priv->active_paths, repo_id); if (!info) { pthread_mutex_unlock (&mgr->priv->paths_lock); return; } g_hash_table_remove (info->paths, path); sync_status_tree_del (info->syncing_tree, path); sync_status_tree_del (info->synced_tree, path); pthread_mutex_unlock (&mgr->priv->paths_lock); } static char *path_status_tbl[] = { "none", "syncing", "error", "ignored", "synced", "paused", "readonly", "locked", "locked_by_me", NULL, }; static char * get_repo_sync_status (SeafSyncManager *mgr, const char *repo_id) { SyncInfo *info = get_sync_info (mgr, repo_id); SeafRepo *repo; if (info->in_error) return g_strdup(path_status_tbl[SYNC_STATUS_ERROR]); repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) return g_strdup(path_status_tbl[SYNC_STATUS_NONE]); if (!repo->auto_sync || !mgr->priv->auto_sync_enabled) return g_strdup(path_status_tbl[SYNC_STATUS_PAUSED]); char allzeros[41] = {0}; if (!info->in_sync && memcmp(allzeros, info->head_commit, 41) == 0) return g_strdup(path_status_tbl[SYNC_STATUS_NONE]); if (info->in_sync && (info->current_task->state == SYNC_STATE_COMMIT || info->current_task->state == SYNC_STATE_FETCH || info->current_task->state == SYNC_STATE_UPLOAD || info->current_task->state == SYNC_STATE_MERGE)) return g_strdup(path_status_tbl[SYNC_STATUS_SYNCING]); else if (!repo->is_readonly) return g_strdup(path_status_tbl[SYNC_STATUS_SYNCED]); else return g_strdup(path_status_tbl[SYNC_STATUS_READONLY]); } char * seaf_sync_manager_get_path_sync_status (SeafSyncManager *mgr, const char *repo_id, const char *path, gboolean is_dir) { ActivePathsInfo *info; SyncInfo *sync_info; SyncStatus ret = SYNC_STATUS_NONE; if (!repo_id || !path) { seaf_warning ("BUG: empty repo_id or path.\n"); return NULL; } if (path[0] == 0) { return get_repo_sync_status (mgr, repo_id); } /* If the repo is in error, all files in it should show no sync status. */ sync_info = get_sync_info (mgr, repo_id); if (sync_info && sync_info->in_error) { ret = SYNC_STATUS_NONE; goto out; } pthread_mutex_lock (&mgr->priv->paths_lock); info = g_hash_table_lookup (mgr->priv->active_paths, repo_id); if (!info) { pthread_mutex_unlock (&mgr->priv->paths_lock); ret = SYNC_STATUS_NONE; goto out; } ret = (SyncStatus) g_hash_table_lookup (info->paths, path); if (is_dir && (ret == SYNC_STATUS_NONE)) { /* If a dir is not in the syncing tree but in the synced tree, * it's synced. Otherwise if it's in the syncing tree, some files * under it must be syncing, so it should be in syncing status too. */ if (sync_status_tree_exists (info->syncing_tree, path)) ret = SYNC_STATUS_SYNCING; else if (sync_status_tree_exists (info->synced_tree, path)) ret = SYNC_STATUS_SYNCED; } pthread_mutex_unlock (&mgr->priv->paths_lock); if (ret == SYNC_STATUS_SYNCED) { if (!seaf_repo_manager_is_path_writable(seaf->repo_mgr, repo_id, path)) ret = SYNC_STATUS_READONLY; else if (seaf_filelock_manager_is_file_locked_by_me (seaf->filelock_mgr, repo_id, path)) ret = SYNC_STATUS_LOCKED_BY_ME; else if (seaf_filelock_manager_is_file_locked (seaf->filelock_mgr, repo_id, path)) ret = SYNC_STATUS_LOCKED; } out: return g_strdup(path_status_tbl[ret]); } static json_t * active_paths_to_json (GHashTable *paths) { json_t *array = NULL, *obj = NULL; GHashTableIter iter; gpointer key, value; char *path; SyncStatus status; array = json_array (); g_hash_table_iter_init (&iter, paths); while (g_hash_table_iter_next (&iter, &key, &value)) { path = key; status = (SyncStatus)value; obj = json_object (); json_object_set (obj, "path", json_string(path)); json_object_set (obj, "status", json_string(path_status_tbl[status])); json_array_append (array, obj); } return array; } char * seaf_sync_manager_list_active_paths_json (SeafSyncManager *mgr) { json_t *array = NULL, *obj = NULL, *path_array = NULL; GHashTableIter iter; gpointer key, value; char *repo_id; ActivePathsInfo *info; char *ret = NULL; pthread_mutex_lock (&mgr->priv->paths_lock); array = json_array (); g_hash_table_iter_init (&iter, mgr->priv->active_paths); while (g_hash_table_iter_next (&iter, &key, &value)) { repo_id = key; info = value; obj = json_object(); path_array = active_paths_to_json (info->paths); json_object_set (obj, "repo_id", json_string(repo_id)); json_object_set (obj, "paths", path_array); json_array_append (array, obj); } pthread_mutex_unlock (&mgr->priv->paths_lock); ret = json_dumps (array, JSON_INDENT(4)); if (!ret) { seaf_warning ("Failed to convert active paths to json\n"); } json_decref (array); return ret; } int seaf_sync_manager_active_paths_number (SeafSyncManager *mgr) { GHashTableIter iter; gpointer key, value; ActivePathsInfo *info; int ret = 0; g_hash_table_iter_init (&iter, mgr->priv->active_paths); while (g_hash_table_iter_next (&iter, &key, &value)) { info = value; ret += g_hash_table_size(info->paths); } return ret; } void seaf_sync_manager_remove_active_path_info (SeafSyncManager *mgr, const char *repo_id) { pthread_mutex_lock (&mgr->priv->paths_lock); g_hash_table_remove (mgr->priv->active_paths, repo_id); pthread_mutex_unlock (&mgr->priv->paths_lock); #ifdef WIN32 /* This is a hack to tell Windows Explorer to refresh all open windows. */ SHChangeNotify (SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); #endif } #ifdef WIN32 static wchar_t * win_path (const char *path) { char *ret = g_strdup(path); wchar_t *ret_w; char *p; for (p = ret; *p != 0; ++p) if (*p == '/') *p = '\\'; ret_w = g_utf8_to_utf16 (ret, -1, NULL, NULL, NULL); g_free (ret); return ret_w; } static void * refresh_windows_explorer_thread (void *vdata) { GAsyncQueue *q = vdata; char *path; wchar_t *wpath; int count = 0; while (1) { path = g_async_queue_pop (q); wpath = win_path (path); SHChangeNotify (SHCNE_ATTRIBUTES, SHCNF_PATHW, wpath, NULL); g_free (path); g_free (wpath); if (++count >= 100) { g_usleep (G_USEC_PER_SEC); count = 0; } } return NULL; } void seaf_sync_manager_add_refresh_path (SeafSyncManager *mgr, const char *path) { g_async_queue_push (mgr->priv->refresh_paths, g_strdup(path)); } void seaf_sync_manager_refresh_path (SeafSyncManager *mgr, const char *path) { wchar_t *wpath; wpath = win_path (path); SHChangeNotify (SHCNE_ATTRIBUTES, SHCNF_PATHW, wpath, NULL); g_free (wpath); } #endif static void update_head_commit_ids_for_server (gpointer key, gpointer value, gpointer user_data) { char *server_url = key; HttpServerState *state = value; /* Only get head commit ids from server if: * 1. syncing protocol version has been checked, and * 2. protocol version is at least 2. */ if (state->http_version >= 2) { seaf_debug ("Updating repo head commit ids for server %s.\n", server_url); GList *repo_id_list = seaf_repo_manager_get_repo_id_list_by_server (seaf->repo_mgr, server_url); if (!repo_id_list) { return; } GHashTable *new_map = http_tx_manager_get_head_commit_ids (seaf->http_tx_mgr, state->effective_host, state->use_fileserver_port, repo_id_list); if (new_map) { pthread_mutex_lock (&state->head_commit_map_lock); g_hash_table_destroy (state->head_commit_map); state->head_commit_map = new_map; if (!state->head_commit_map_init) state->head_commit_map_init = TRUE; state->last_update_head_commit_map_time = (gint64)time(NULL); pthread_mutex_unlock (&state->head_commit_map_lock); } g_list_free_full (repo_id_list, g_free); } } static void * update_cached_head_commit_ids (void *arg) { SeafSyncManager *mgr = (SeafSyncManager *)arg; while (1) { g_usleep (30 * G_USEC_PER_SEC); g_hash_table_foreach (mgr->http_server_states, update_head_commit_ids_for_server, mgr); } } seafile-6.1.5/daemon/sync-mgr.h000066400000000000000000000130111323477647300163220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SYNC_MGR_H #define SYNC_MGR_H typedef struct _SyncInfo SyncInfo; typedef struct _SyncTask SyncTask; typedef struct _SeafSyncManager SeafSyncManager; typedef struct _SeafSyncManagerPriv SeafSyncManagerPriv; struct CcnetTimer; struct _SyncInfo { char repo_id[41]; /* the repo */ char head_commit[41]; /* head commit on relay */ SyncTask *current_task; gboolean in_sync; /* set to FALSE when sync state is DONE or ERROR */ gint err_cnt; gboolean in_error; /* set to TRUE if err_cnt >= 3 */ gboolean deleted_on_relay; gboolean branch_deleted_on_relay; gboolean repo_corrupted; gboolean need_fetch; gboolean need_upload; gboolean need_merge; /* Used by multipart upload. */ gboolean multipart_upload; gint64 total_bytes; gint64 uploaded_bytes; gboolean end_multipart_upload; }; enum { SYNC_STATE_DONE, SYNC_STATE_COMMIT, SYNC_STATE_INIT, SYNC_STATE_FETCH, SYNC_STATE_MERGE, SYNC_STATE_UPLOAD, SYNC_STATE_ERROR, SYNC_STATE_CANCELED, SYNC_STATE_CANCEL_PENDING, SYNC_STATE_NUM, }; enum { SYNC_ERROR_NONE, SYNC_ERROR_RELAY_OFFLINE, SYNC_ERROR_UPGRADE_REPO, SYNC_ERROR_RELAY_REMOVED, SYNC_ERROR_NOT_LOGIN, SYNC_ERROR_SERVICE_DOWN, SYNC_ERROR_ACCESS_DENIED, SYNC_ERROR_QUOTA_FULL, SYNC_ERROR_PROC_PERM_ERR, SYNC_ERROR_DATA_CORRUPT, SYNC_ERROR_START_UPLOAD, SYNC_ERROR_UPLOAD, SYNC_ERROR_START_FETCH, SYNC_ERROR_FETCH, SYNC_ERROR_NOREPO, SYNC_ERROR_REPO_CORRUPT, SYNC_ERROR_COMMIT, SYNC_ERROR_MERGE, SYNC_ERROR_WORKTREE_DIRTY, SYNC_ERROR_DEPRECATED_SERVER, SYNC_ERROR_GET_SYNC_INFO, /* for http sync */ SYNC_ERROR_FILES_LOCKED, SYNC_ERROR_UNKNOWN, SYNC_ERROR_NUM, }; struct _SyncTask { SeafSyncManager *mgr; SyncInfo *info; char *dest_id; gboolean is_manual_sync; gboolean is_initial_commit; int state; int error; char *err_detail; char *tx_id; char *token; struct CcnetTimer *commit_timer; gboolean server_side_merge; gboolean uploaded; gboolean http_sync; int http_version; SeafRepo *repo; /* for convenience, only valid when in_sync. */ }; enum _SyncStatus { SYNC_STATUS_NONE = 0, SYNC_STATUS_SYNCING, SYNC_STATUS_ERROR, SYNC_STATUS_IGNORED, SYNC_STATUS_SYNCED, SYNC_STATUS_PAUSED, SYNC_STATUS_READONLY, SYNC_STATUS_LOCKED, SYNC_STATUS_LOCKED_BY_ME, N_SYNC_STATUS, }; typedef enum _SyncStatus SyncStatus; struct _SeafileSession; struct _SeafSyncManager { struct _SeafileSession *seaf; GHashTable *sync_infos; int n_running_tasks; gboolean commit_job_running; int sync_interval; GHashTable *server_states; GHashTable *http_server_states; /* Sent/recv bytes from all transfer tasks in this second. * Since we have http and non-http tasks, sync manager is * the only reasonable place to put these variables. */ gint sent_bytes; gint recv_bytes; gint last_sent_bytes; gint last_recv_bytes; /* Upload/download rate limits. */ gint upload_limit; gint download_limit; SeafSyncManagerPriv *priv; }; SeafSyncManager* seaf_sync_manager_new (struct _SeafileSession *seaf); int seaf_sync_manager_init (SeafSyncManager *mgr); int seaf_sync_manager_start (SeafSyncManager *mgr); int seaf_sync_manager_add_sync_task (SeafSyncManager *mgr, const char *repo_id, GError **error); void seaf_sync_manager_cancel_sync_task (SeafSyncManager *mgr, const char *repo_id); SyncInfo * seaf_sync_manager_get_sync_info (SeafSyncManager *mgr, const char *repo_id); int seaf_sync_manager_disable_auto_sync (SeafSyncManager *mgr); int seaf_sync_manager_enable_auto_sync (SeafSyncManager *mgr); int seaf_sync_manager_is_auto_sync_enabled (SeafSyncManager *mgr); const char * sync_error_to_str (int error); const char * sync_state_to_str (int state); void seaf_sync_manager_update_active_path (SeafSyncManager *mgr, const char *repo_id, const char *path, int mode, SyncStatus status); void seaf_sync_manager_delete_active_path (SeafSyncManager *mgr, const char *repo_id, const char *path); char * seaf_sync_manager_get_path_sync_status (SeafSyncManager *mgr, const char *repo_id, const char *path, gboolean is_dir); char * seaf_sync_manager_list_active_paths_json (SeafSyncManager *mgr); int seaf_sync_manager_active_paths_number (SeafSyncManager *mgr); void seaf_sync_manager_remove_active_path_info (SeafSyncManager *mgr, const char *repo_id); #ifdef WIN32 /* Add to refresh queue */ void seaf_sync_manager_add_refresh_path (SeafSyncManager *mgr, const char *path); /* Refresh immediately. */ void seaf_sync_manager_refresh_path (SeafSyncManager *mgr, const char *path); #endif #endif seafile-6.1.5/daemon/sync-status-tree.c000066400000000000000000000153471323477647300200260ustar00rootroot00000000000000#include "common.h" #include "seafile-session.h" #include "sync-status-tree.h" #include "log.h" struct _SyncStatusDir { GHashTable *dirents; /* name -> dirent. */ }; typedef struct _SyncStatusDir SyncStatusDir; struct _SyncStatusDirent { char *name; int mode; /* Only used for directories. */ SyncStatusDir *subdir; }; typedef struct _SyncStatusDirent SyncStatusDirent; struct SyncStatusTree { SyncStatusDir *root; char *worktree; }; typedef struct SyncStatusTree SyncStatusTree; static void sync_status_dirent_free (SyncStatusDirent *dirent); static SyncStatusDir * sync_status_dir_new () { SyncStatusDir *dir = g_new0 (SyncStatusDir, 1); dir->dirents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)sync_status_dirent_free); return dir; } static void sync_status_dir_free (SyncStatusDir *dir) { if (!dir) return; g_hash_table_destroy (dir->dirents); g_free (dir); } static SyncStatusDirent * sync_status_dirent_new (const char *name, int mode) { SyncStatusDirent *dirent = g_new0(SyncStatusDirent, 1); dirent->name = g_strdup(name); dirent->mode = mode; if (S_ISDIR(mode)) dirent->subdir = sync_status_dir_new (); return dirent; } static void sync_status_dirent_free (SyncStatusDirent *dirent) { if (!dirent) return; g_free (dirent->name); sync_status_dir_free (dirent->subdir); g_free (dirent); } SyncStatusTree * sync_status_tree_new (const char *worktree) { SyncStatusTree *tree = g_new0(SyncStatusTree, 1); tree->root = sync_status_dir_new (); tree->worktree = g_strdup(worktree); return tree; } #if 0 #ifdef WIN32 static void refresh_recursive (const char *basedir, SyncStatusDir *dir) { GHashTableIter iter; gpointer key, value; char *dname, *path; SyncStatusDirent *dirent; g_hash_table_iter_init (&iter, dir->dirents); while (g_hash_table_iter_next (&iter, &key, &value)) { dname = key; dirent = value; path = g_strconcat(basedir, "/", dname, NULL); seaf_sync_manager_add_refresh_path (seaf->sync_mgr, path); if (S_ISDIR(dirent->mode)) refresh_recursive (path, dirent->subdir); g_free (path); } } #endif #endif /* 0 */ void sync_status_tree_free (struct SyncStatusTree *tree) { if (!tree) return; #ifdef WIN32 /* refresh_recursive (tree->worktree, tree->root); */ #endif /* Free the tree recursively. */ sync_status_dir_free (tree->root); g_free (tree->worktree); g_free (tree); } void sync_status_tree_add (SyncStatusTree *tree, const char *path, int mode) { char **dnames = NULL; guint n, i; char *dname; SyncStatusDir *dir = tree->root; SyncStatusDirent *dirent; GString *buf; dnames = g_strsplit (path, "/", 0); if (!dnames) return; n = g_strv_length (dnames); buf = g_string_new (""); g_string_append (buf, tree->worktree); for (i = 0; i < n; i++) { dname = dnames[i]; dirent = g_hash_table_lookup (dir->dirents, dname); g_string_append (buf, "/"); g_string_append (buf, dname); if (dirent) { if (S_ISDIR(dirent->mode)) { if (i == (n-1)) { goto out; } else { dir = dirent->subdir; } } else { goto out; } } else { if (i == (n-1)) { dirent = sync_status_dirent_new (dname, mode); g_hash_table_insert (dir->dirents, g_strdup(dname), dirent); } else { dirent = sync_status_dirent_new (dname, S_IFDIR); g_hash_table_insert (dir->dirents, g_strdup(dname), dirent); dir = dirent->subdir; } #ifdef WIN32 seaf_sync_manager_add_refresh_path (seaf->sync_mgr, buf->str); #endif } } out: g_string_free (buf, TRUE); g_strfreev (dnames); } inline static gboolean is_empty_dir (SyncStatusDirent *dirent) { return (g_hash_table_size(dirent->subdir->dirents) == 0); } static void remove_item (SyncStatusDir *dir, const char *dname, const char *fullpath) { g_hash_table_remove (dir->dirents, dname); #ifdef WIN32 seaf_sync_manager_add_refresh_path (seaf->sync_mgr, fullpath); #endif } static void delete_recursive (SyncStatusDir *dir, char **dnames, guint n, guint i, const char *base) { char *dname; SyncStatusDirent *dirent; char *fullpath = NULL; dname = dnames[i]; fullpath = g_strconcat (base, "/", dname, NULL); dirent = g_hash_table_lookup (dir->dirents, dname); if (dirent) { if (S_ISDIR(dirent->mode)) { if (i == (n-1)) { if (is_empty_dir(dirent)) remove_item (dir, dname, fullpath); } else { delete_recursive (dirent->subdir, dnames, n, ++i, fullpath); /* If this dir becomes empty after deleting the entry below, * remove the dir itself too. */ if (is_empty_dir(dirent)) remove_item (dir, dname, fullpath); } } else if (i == (n-1)) { remove_item (dir, dname, fullpath); } } g_free (fullpath); } void sync_status_tree_del (SyncStatusTree *tree, const char *path) { char **dnames = NULL; guint n; SyncStatusDir *dir = tree->root; dnames = g_strsplit (path, "/", 0); if (!dnames) return; n = g_strv_length (dnames); delete_recursive (dir, dnames, n, 0, tree->worktree); g_strfreev (dnames); } int sync_status_tree_exists (SyncStatusTree *tree, const char *path) { char **dnames = NULL; guint n, i; char *dname; SyncStatusDir *dir = tree->root; SyncStatusDirent *dirent; int ret = 0; dnames = g_strsplit (path, "/", 0); if (!dnames) return ret; n = g_strv_length (dnames); for (i = 0; i < n; i++) { dname = dnames[i]; dirent = g_hash_table_lookup (dir->dirents, dname); if (dirent) { if (S_ISDIR(dirent->mode)) { if (i == (n-1)) { ret = 1; goto out; } else { dir = dirent->subdir; } } else { if (i == (n-1)) { ret = 1; goto out; } else { goto out; } } } else { goto out; } } out: g_strfreev (dnames); return ret; } seafile-6.1.5/daemon/sync-status-tree.h000066400000000000000000000015471323477647300200300ustar00rootroot00000000000000#ifndef SYNC_STATUS_TREE_H #define SYNC_STATUS_TREE_H struct SyncStatusTree; struct SyncStatusTree * sync_status_tree_new (const char *worktree); void sync_status_tree_free (struct SyncStatusTree *tree); /* * Add a @path into the @tree. If any directory along the path is missing, * it will be created. If the path already exists, it won't be overwritten. */ void sync_status_tree_add (struct SyncStatusTree *tree, const char *path, int mode); /* * Delete a path from the tree. If directory becomes empty after the deletion, * it will be deleted too. All empty direcotries along the path will be deleted. */ void sync_status_tree_del (struct SyncStatusTree *tree, const char *path); int sync_status_tree_exists (struct SyncStatusTree *tree, const char *path); #endif seafile-6.1.5/daemon/test-sync-tree.c000066400000000000000000000024551323477647300174560ustar00rootroot00000000000000#include #include #include #include "sync-status-tree.h" int main (int argc, char **argv) { struct SyncStatusTree *tree; int val; tree = sync_status_tree_new (); sync_status_tree_add (tree, "a/b/c.txt", S_IFREG); sync_status_tree_add (tree, "a/b/c/d", S_IFDIR); sync_status_tree_add (tree, "a/xxx.txt", S_IFREG); printf ("test after add\n"); val = sync_status_tree_exists (tree, "a/b/c.txt"); printf ("a/b/c.txt: %d\n", val); val = sync_status_tree_exists (tree, "a/b/c/d"); printf ("a/b/c/d: %d\n", val); val = sync_status_tree_exists (tree, "a/d/f.foo"); printf ("a/d/f.foo: %d\n", val); val = sync_status_tree_exists (tree, "a/b"); printf ("a/b: %d\n", val); sync_status_tree_del (tree, "a/b/c.txt"); sync_status_tree_del (tree, "a/b/c/d"); sync_status_tree_del (tree, "a/xxx.txt"); sync_status_tree_del (tree, "a/c.pdf"); printf ("test after del\n"); val = sync_status_tree_exists (tree, "a/b/c.txt"); printf ("a/b/c.txt: %d\n", val); val = sync_status_tree_exists (tree, "a/b/c/d"); printf ("a/b/c/d: %d\n", val); val = sync_status_tree_exists (tree, "a/b"); printf ("a/b: %d\n", val); val = sync_status_tree_exists (tree, "a"); printf ("a: %d\n", val); } seafile-6.1.5/daemon/transfer-mgr.c000066400000000000000000002202631323477647300171760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_TRANSFER #include "log.h" #include #include #include #include #include "utils.h" #include "db.h" #ifndef USE_GPL_CRYPTO #include #endif #include "seafile-session.h" #include "transfer-mgr.h" #include "commit-mgr.h" #include "fs-mgr.h" #include "block-mgr.h" #include "seafile-error.h" #include "vc-common.h" #include "merge.h" #include "sync-mgr.h" #include "clone-mgr.h" #include "vc-utils.h" #include "mq-mgr.h" #include "seafile-config.h" #ifndef USE_GPL_CRYPTO #include "processors/check-tx-v3-proc.h" #endif #include "processors/sendfs-proc.h" #include "processors/getfs-proc.h" #include "processors/getcs-proc.h" #include "processors/sendbranch-proc.h" #include "processors/getcommit-v2-proc.h" #include "processors/getcommit-v3-proc.h" #include "processors/sendcommit-v3-proc.h" #include "processors/sendcommit-v3-new-proc.h" #include "processors/checkbl-proc.h" #include "processors/getcs-v2-proc.h" #include "processors/sendcommit-v4-proc.h" #include "processors/sendfs-v2-proc.h" #include "processors/getfs-v2-proc.h" #include "block-tx-client.h" #include "diff-simple.h" #define TRANSFER_DB "transfer.db" #define SCHEDULE_INTERVAL 1 /* 1s */ #define MAX_QUEUED_BLOCKS 50 #define DEFAULT_BLOCK_SIZE (1 << 20) static int schedule_task_pulse (void *vmanager); static void state_machine_tick (TransferTask *task); static void transition_state (TransferTask *task, int state, int rt_state); /** * transfer task states: * * INIT COMMIT FS DATA FINISHED NETDOWN * ------------------------------------------------------------------------ * NORMAL 1 2 3 4 x 15 * CANCELED x 9 10 11 12 x * FINISHED x x x x 13 x * ERROR x x x x 14 x * * state transitions: * Event Transition * ------------------------------------------------------- * start commit tx 1 --> 2 * start fs tx 2 --> 3 * start block tx 3 --> 4 * complete block tx 4 --> 13 * * user cancel task 2 --> 9, 3 --> 10, * 4 --> 11, 15 -->12 * * on_commit_uploaded(), * on_commit_downloaded() * checks task canceled 9 --> 12 * if connection lost 9 --> 15 * * on_fs_uploaded(), * on_fs_downloaded() * checks task canceled 10 --> 12 * if connection lost 10 --> 15 * * state_machine_tick() * checks task canceled in DATA state 11 --> 12 * * error in COMMIT or FS state --> 14 * * User can remove a task only when its runtime state is 'FINISHED'. * User can cancel a task only when its state is 'NORMAL'. */ /* * Transfer Task. */ static const char *transfer_task_state_str[] = { "normal", "canceled", "finished", "error", }; static const char *transfer_task_rt_state_str[] = { "init", "check", "commit", "fs", "check-blocks", "get-chunk-server", "data", "update-branch", "finished", "netdown", }; static const char *transfer_task_error_strs[] = { "Successful", "Unknown error", "Service on remote server is not available", "Access denied to service. Please check your registration on server.", "Internal error when preparing upload", "Internal error when preparing download", "No permission to access remote library", "Library doesn't exist on the remote end", "Internal error when starting to send revision information", "Internal error when starting to get revision information", "Failed to upload revision information to remote library", "Failed to get revision information from remote library", "Internal error when starting to send file information", "Internal error when starting to get file information", "Incomplete file information in the local library", "Failed to upload file information to remote library", "Failed to get file information from remote library", "Incomplete file information in the local library", "Internal error when starting to update remote library", "Others have concurrent updates to the remote library. You need to sync again.", "Storage quota full", "Server failed to check storage quota", "Transfer protocol outdated. You need to upgrade seafile.", "Incomplete revision information in the local library", "Failed to compare data to server.", "Failed to get block server list.", "Failed to start block transfer client.", "Failed to upload blocks.", "Failed to download blocks.", "Server version is too old.", "Files are locked by other application.", }; const char * task_state_to_str (int state) { return transfer_task_state_str[state]; } const char * task_rt_state_to_str (int rt_state) { return transfer_task_rt_state_str[rt_state]; } const char * task_error_str (int task_errno) { return transfer_task_error_strs[task_errno]; } static TransferTask * seaf_transfer_task_new (SeafTransferManager *manager, const char *tx_id, const char *repo_id, const char *dest_id, const char *from_branch, const char *to_branch, const char *token, int task_type) { TransferTask *task; char *uuid; g_return_val_if_fail (repo_id != NULL, NULL); g_return_val_if_fail (from_branch != NULL, NULL); g_return_val_if_fail (to_branch != NULL, NULL); g_return_val_if_fail (token != NULL, NULL); task = g_new0 (TransferTask, 1); task->manager = manager; memcpy (task->repo_id, repo_id, 37); task->repo_id[36] = '\0'; task->type = task_type; task->runtime_state = TASK_RT_STATE_INIT; task->from_branch = g_strdup(from_branch); task->to_branch = g_strdup(to_branch); task->token = g_strdup(token); if (!tx_id) { uuid = gen_uuid(); memcpy (task->tx_id, uuid, 37); g_free (uuid); } else { memcpy (task->tx_id, tx_id, 37); } if (dest_id) task->dest_id = g_strdup(dest_id); task->rsize = -1; task->dsize = 0; return task; } static void free_block_id (gpointer data, gpointer user_data) { g_free (data); } static void free_chunk_server (gpointer data, gpointer user_data) { ChunkServer *cs = data; g_free (cs->addr); g_free (cs); } static void seaf_transfer_task_free (TransferTask *task) { g_free (task->session_token); g_free (task->dest_id); g_free (task->from_branch); g_free (task->to_branch); g_free (task->token); g_free (task->email); if (task->fs_roots) object_list_free (task->fs_roots); if (task->commits) object_list_free (task->commits); if (task->protocol_version < 7 && task->block_ids) { g_queue_foreach (task->block_ids, free_block_id, NULL); g_queue_free (task->block_ids); } if (task->protocol_version >= 4) { g_list_foreach (task->chunk_servers, free_chunk_server, NULL); g_list_free (task->chunk_servers); if (task->block_list) block_list_free (task->block_list); } g_free (task); } int transfer_task_get_rate (TransferTask *task) { return task->last_tx_bytes; } int transfer_task_get_done_blocks (TransferTask *task) { if (task->runtime_state != TASK_RT_STATE_DATA) return 0; if (task->protocol_version >= 7 && task->type == TASK_TYPE_DOWNLOAD) return task->n_downloaded; if (task->protocol_version >= 4) { int n_left = g_queue_get_length (task->block_ids); return task->block_list->n_blocks - n_left; } if (task->type == TASK_TYPE_UPLOAD) return task->n_uploaded; else return task->block_list->n_valid_blocks; } static void emit_transfer_done_signal (TransferTask *task) { if (task->type == TASK_TYPE_DOWNLOAD) g_signal_emit_by_name (seaf, "repo-fetched", task); else g_signal_emit_by_name (seaf, "repo-uploaded", task); } static void transition_state (TransferTask *task, int state, int rt_state) { seaf_message ("Transfer repo '%.8s': ('%s', '%s') --> ('%s', '%s')\n", task->repo_id, task_state_to_str(task->state), task_rt_state_to_str(task->runtime_state), task_state_to_str(state), task_rt_state_to_str(rt_state)); task->last_runtime_state = task->runtime_state; if (rt_state == TASK_RT_STATE_FINISHED) { /* Clear download head info. */ if (task->protocol_version >= 7 && task->type == TASK_TYPE_DOWNLOAD && state == TASK_STATE_FINISHED) seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo_id, REPO_PROP_DOWNLOAD_HEAD, EMPTY_SHA1); task->state = state; task->runtime_state = rt_state; emit_transfer_done_signal (task); return; } if (state != task->state) task->state = state; task->runtime_state = rt_state; } void transition_state_to_error (TransferTask *task, int task_errno) { g_return_if_fail (task_errno != 0); seaf_message ("Transfer repo '%.8s': ('%s', '%s') --> ('%s', '%s'): %s\n", task->repo_id, task_state_to_str(task->state), task_rt_state_to_str(task->runtime_state), task_state_to_str(TASK_STATE_ERROR), task_rt_state_to_str(TASK_RT_STATE_FINISHED), task_error_str(task_errno)); task->last_runtime_state = task->runtime_state; task->state = TASK_STATE_ERROR; task->runtime_state = TASK_RT_STATE_FINISHED; task->error = task_errno; emit_transfer_done_signal (task); } void transfer_task_set_error (TransferTask *task, int error) { transition_state_to_error (task, error); } void transfer_task_set_netdown (TransferTask *task) { g_return_if_fail (task->state == TASK_STATE_NORMAL); if (task->runtime_state == TASK_RT_STATE_NETDOWN) return; transition_state (task, TASK_STATE_NORMAL, TASK_RT_STATE_NETDOWN); } static void transfer_task_with_proc_failure (TransferTask *task, CcnetProcessor *proc, int defalut_error) { seaf_debug ("Transfer repo '%.8s': proc %s(%d) failure: %d\n", task->repo_id, GET_PNAME(proc), PRINT_ID(proc->id), proc->failure); switch (proc->failure) { case PROC_DONE: /* It can never happen */ g_return_if_reached (); case PROC_REMOTE_DEAD: seaf_warning ("[tr-mgr] Shutdown processor with failure %d\n", proc->failure); transfer_task_set_netdown (task); break; case PROC_NO_SERVICE: transition_state_to_error (task, TASK_ERR_NO_SERVICE); break; case PROC_PERM_ERR: transition_state_to_error (task, TASK_ERR_PROC_PERM_ERR); break; case PROC_BAD_RESP: case PROC_NOTSET: default: transition_state_to_error (task, defalut_error); } } /* * Transfer Manager. */ SeafTransferManager* seaf_transfer_manager_new (struct _SeafileSession *seaf) { SeafTransferManager *mgr = g_new0 (SeafTransferManager, 1); mgr->seaf = seaf; mgr->download_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) seaf_transfer_task_free); mgr->upload_tasks = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) seaf_transfer_task_free); char *db_path = g_build_path (PATH_SEPERATOR, seaf->seaf_dir, TRANSFER_DB, NULL); if (sqlite_open_db (db_path, &mgr->db) < 0) { g_critical ("[Transfer mgr] Failed to open transfer db\n"); g_free (db_path); g_free (mgr); return NULL; } return mgr; } static void register_processors (CcnetClient *client) { #ifndef USE_GPL_CRYPTO ccnet_proc_factory_register_processor (client->proc_factory, "seafile-check-tx-v3", SEAFILE_TYPE_CHECK_TX_V3_PROC); #endif ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendfs", SEAFILE_TYPE_SENDFS_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getfs", SEAFILE_TYPE_GETFS_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendbranch", SEAFILE_TYPE_SENDBRANCH_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getcs", SEAFILE_TYPE_GETCS_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getcommit-v2", SEAFILE_TYPE_GETCOMMIT_V2_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getcommit-v3", SEAFILE_TYPE_GETCOMMIT_V3_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendcommit-v3", SEAFILE_TYPE_SENDCOMMIT_V3_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendcommit-v3-new", SEAFILE_TYPE_SENDCOMMIT_V3_NEW_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-checkbl", SEAFILE_TYPE_CHECKBL_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getcs-v2", SEAFILE_TYPE_GETCS_V2_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendcommit-v4", SEAFILE_TYPE_SENDCOMMIT_V4_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-sendfs-v2", SEAFILE_TYPE_SENDFS_V2_PROC); ccnet_proc_factory_register_processor (client->proc_factory, "seafile-getfs-v2", SEAFILE_TYPE_GETFS_V2_PROC); } int seaf_transfer_manager_start (SeafTransferManager *manager) { const char *sql; sql = "CREATE TABLE IF NOT EXISTS CloneHeads " "(repo_id TEXT PRIMARY KEY, head TEXT);"; if (sqlite_query_exec (manager->db, sql) < 0) return -1; register_processors (seaf->session); manager->schedule_timer = ccnet_timer_new (schedule_task_pulse, manager, SCHEDULE_INTERVAL * 1000); return 0; } /* * We don't want to have two tasks for the same repo to run * simultaneously. */ static gboolean is_duplicate_task (SeafTransferManager *manager, const char *repo_id) { GHashTableIter iter; gpointer key, value; TransferTask *task; g_hash_table_iter_init (&iter, manager->download_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (strcmp(task->repo_id, repo_id) == 0 && task->runtime_state != TASK_RT_STATE_FINISHED) return TRUE; } g_hash_table_iter_init (&iter, manager->upload_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (strcmp(task->repo_id, repo_id) == 0 && task->runtime_state != TASK_RT_STATE_FINISHED) return TRUE; } return FALSE; } static gboolean remove_task_help (gpointer key, gpointer value, gpointer user_data) { TransferTask *task = value; const char *repo_id = user_data; if (strcmp(task->repo_id, repo_id) != 0) return FALSE; return TRUE; } static void clean_tasks_for_repo (SeafTransferManager *manager, const char *repo_id) { g_hash_table_foreach_remove (manager->download_tasks, remove_task_help, (gpointer)repo_id); g_hash_table_foreach_remove (manager->upload_tasks, remove_task_help, (gpointer)repo_id); } char * seaf_transfer_manager_add_download (SeafTransferManager *manager, const char *repo_id, int repo_version, const char *peer_id, const char *from_branch, const char *to_branch, const char *token, gboolean server_side_merge, const char *passwd, const char *worktree, const char *email, GError **error) { TransferTask *task; if (!repo_id || !from_branch || !to_branch || !token || !email) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty argument(s)"); return NULL; } if (is_duplicate_task (manager, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } clean_tasks_for_repo (manager, repo_id); task = seaf_transfer_task_new (manager, NULL, repo_id, peer_id, from_branch, to_branch, token, TASK_TYPE_DOWNLOAD); task->state = TASK_STATE_NORMAL; task->repo_version = repo_version; task->email = g_strdup(email); task->server_side_merge = server_side_merge; /* Mark task "clone" if it's a new repo. */ if (!seaf_repo_manager_repo_exists (seaf->repo_mgr, repo_id)) task->is_clone = TRUE; if (task->is_clone) { task->passwd = g_strdup(passwd); task->worktree = g_strdup(worktree); } g_hash_table_insert (manager->download_tasks, g_strdup(task->tx_id), task); return g_strdup(task->tx_id); } char * seaf_transfer_manager_add_upload (SeafTransferManager *manager, const char *repo_id, int repo_version, const char *peer_id, const char *from_branch, const char *to_branch, const char *token, gboolean server_side_merge, GError **error) { TransferTask *task; SeafRepo *repo; if (!repo_id || !from_branch || !to_branch || !token) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Empty argument(s)"); return NULL; } repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id); if (!repo) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_BAD_ARGS, "Repo not found"); return NULL; } if (is_duplicate_task (manager, repo_id)) { g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL, "Task is already in progress"); return NULL; } clean_tasks_for_repo (manager, repo_id); task = seaf_transfer_task_new (manager, NULL, repo_id, peer_id, from_branch, to_branch, token, TASK_TYPE_UPLOAD); task->state = TASK_STATE_NORMAL; task->repo_version = repo_version; task->server_side_merge = server_side_merge; g_hash_table_insert (manager->upload_tasks, g_strdup(task->tx_id), task); return g_strdup(task->tx_id); } /* find running tranfer of a repo */ TransferTask* seaf_transfer_manager_find_transfer_by_repo (SeafTransferManager *manager, const char *repo_id) { GHashTableIter iter; gpointer key, value; TransferTask *task; g_hash_table_iter_init (&iter, manager->download_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (strcmp(task->repo_id, repo_id) == 0 && task->state != TASK_STATE_FINISHED) return task; } g_hash_table_iter_init (&iter, manager->upload_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; if (strcmp(task->repo_id, repo_id) == 0 && task->state != TASK_STATE_FINISHED) return task; } return NULL; } static void remove_task(SeafTransferManager *manager, TransferTask *task) { if (task->type == TASK_TYPE_DOWNLOAD) { g_hash_table_remove (manager->download_tasks, task->tx_id); } else { g_hash_table_remove (manager->upload_tasks, task->tx_id); } } void seaf_transfer_manager_remove_task (SeafTransferManager *manager, const char *tx_id, int task_type) { TransferTask *task = NULL; if (task_type == TASK_TYPE_DOWNLOAD) task = g_hash_table_lookup (manager->download_tasks, tx_id); else task = g_hash_table_lookup (manager->upload_tasks, tx_id); if (!task) return; if (task->runtime_state != TASK_RT_STATE_FINISHED) { seaf_warning ("[tr-mgr] Try to remove running task!\n"); return; } remove_task (manager, task); } static void cancel_task (TransferTask *task) { if (task->runtime_state == TASK_RT_STATE_NETDOWN || task->runtime_state == TASK_RT_STATE_INIT) { transition_state (task, TASK_STATE_CANCELED, TASK_RT_STATE_FINISHED); } else { /* * Only transition state, not runtime state. * Runtime state transition is handled asynchronously. */ if (task->protocol_version >= 4 && task->runtime_state == TASK_RT_STATE_DATA) block_tx_client_run_command (task->tx_info, BLOCK_CLIENT_CMD_CANCEL); transition_state (task, TASK_STATE_CANCELED, task->runtime_state); } } void seaf_transfer_manager_cancel_task (SeafTransferManager *manager, const char *tx_id, int task_type) { TransferTask *task = NULL; if (task_type == TASK_TYPE_DOWNLOAD) task = g_hash_table_lookup (manager->download_tasks, tx_id); else task = g_hash_table_lookup (manager->upload_tasks, tx_id); if (!task) return; if (task->state != TASK_STATE_NORMAL) { seaf_warning ("Task cannot be canceled!\n"); return; } cancel_task (task); } GList* seaf_transfer_manager_get_upload_tasks (SeafTransferManager *manager) { return g_hash_table_get_values (manager->upload_tasks); } GList* seaf_transfer_manager_get_download_tasks (SeafTransferManager *manager) { return g_hash_table_get_values (manager->download_tasks); } int seaf_transfer_manager_download_file_blocks (SeafTransferManager *manager, TransferTask *task, const char *file_id) { Seafile *file; file = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file_id); if (!file) { seaf_warning ("Failed to find seafile object %s in repo %.8s.\n", file_id, task->repo_id); return -1; } int i; char *block_id; for (i = 0; i < file->n_blocks; ++i) { block_id = file->blk_sha1s[i]; if (!seaf_block_manager_block_exists (seaf->block_mgr, task->repo_id, task->repo_version, block_id)) g_queue_push_tail (task->block_ids, g_strdup(block_id)); } seafile_unref (file); BlockTxInfo *info = task->tx_info; int rsp; retry: if (g_queue_get_length (task->block_ids) == 0) return BLOCK_CLIENT_SUCCESS; block_tx_client_run_command (info, BLOCK_CLIENT_CMD_TRANSFER); /* Wait until block download is done. */ piperead (info->done_pipe[0], (char*)&rsp, sizeof(rsp)); /* The server closes the socket after 30 seconds without data, * so just retry if we encounter network error. */ if (rsp == BLOCK_CLIENT_NET_ERROR) { block_tx_client_run_command (info, BLOCK_CLIENT_CMD_RESTART); piperead (info->done_pipe[0], (char*)&rsp, sizeof(rsp)); if (rsp == BLOCK_CLIENT_READY) goto retry; } while ((block_id = g_queue_pop_head(task->block_ids)) != NULL) g_free (block_id); return rsp; } /* Utility functions. */ static BlockList * load_blocklist_with_local_history (TransferTask *task) { BlockList *bl1, *bl2, *bl = NULL; int i; ObjectList *commits = task->commits; char *commit_id; SeafCommit *commit; GList *parents = NULL; /* Upload the blocks pointed by new commits, excluding * blocks that have been uploaded before. */ bl1 = block_list_new (); for (i = 0; i < commits->obj_ids->len; ++i) { commit_id = g_ptr_array_index (commits->obj_ids, i); commit = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, commit_id); if (!commit) { seaf_warning ("Failed to get commit %s:%s.\n", task->repo_id, commit_id); block_list_free (bl1); return NULL; } if (seaf_fs_manager_populate_blocklist (seaf->fs_mgr, task->repo_id, task->repo_version, commit->root_id, bl1) < 0) { seaf_commit_unref (commit); block_list_free (bl1); return NULL; } if (commit->parent_id && !object_list_exists (commits, commit->parent_id)) parents = g_list_prepend (parents, g_strdup(commit->parent_id)); if (commit->second_parent_id && !object_list_exists (commits, commit->second_parent_id)) parents = g_list_prepend (parents, g_strdup(commit->second_parent_id)); seaf_commit_unref (commit); } GList *p; char *parent_id; SeafCommit *parent; for (p = parents; p; p = p->next) { parent_id = p->data; parent = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, parent_id); if (!parent) { block_list_free (bl1); return NULL; } bl2 = block_list_new (); if (seaf_fs_manager_populate_blocklist (seaf->fs_mgr, task->repo_id, task->repo_version, parent->root_id, bl2) < 0) { seaf_commit_unref (parent); block_list_free (bl1); block_list_free (bl2); return NULL; } bl = block_list_difference (bl1, bl2); block_list_free (bl1); bl1 = bl; seaf_commit_unref (parent); block_list_free (bl2); } seaf_debug ("Uploading %u blocks.\n", bl1->n_blocks); return bl1; } static int seaf_transfer_task_load_blocklist (TransferTask *task) { SeafRepo *repo; BlockList *bl; repo = seaf_repo_manager_get_repo (seaf->repo_mgr, task->repo_id); if (!repo && !task->is_clone) return -1; if (task->type == TASK_TYPE_UPLOAD) { bl = load_blocklist_with_local_history (task); if (!bl) { seaf_warning ("[tr-mgr]Failed to populate blocklist.\n"); return -1; } } else { SeafCommit *remote; remote = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, task->head); if (!remote) { seaf_warning ("[tr-mgr] Failed to find commit %s.\n", task->head); return -1; } if (!task->is_clone) { /* If we're merging, only get new blocks that need to be checked out. */ if (merge_get_new_block_list (repo, remote, &bl) < 0) { seaf_warning ("[tr-mgr] Failed to get new blocks for merge.\n"); seaf_commit_unref (remote); return -1; } } else { /* If we're cloning, only get blocks pointed by the lastest commit. */ bl = block_list_new (); if (seaf_fs_manager_populate_blocklist (seaf->fs_mgr, task->repo_id, task->repo_version, remote->root_id, bl) < 0) { seaf_warning ("[tr-mgr] Failed to get blocks of commit %s.\n", remote->commit_id); seaf_commit_unref (remote); return -1; } } seaf_commit_unref (remote); g_return_val_if_fail (bl != NULL, -1); } task->block_list = bl; return 0; } typedef struct DiffTreesData { BlockList *bl; TransferTask *task; } DiffTreesData; static int diff_files (int n, const char *basedir, SeafDirent *files[], void *vdata) { SeafDirent *file1 = files[0]; SeafDirent *file2 = files[1]; DiffTreesData *data = vdata; BlockList *bl = data->bl; TransferTask *task = data->task; Seafile *f1 = NULL, *f2 = NULL; int i; if (file1 && strcmp (file1->id, EMPTY_SHA1) != 0) { if (!file2) { f1 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file1->id); if (!f1) { seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file1->id); return -1; } for (i = 0; i < f1->n_blocks; ++i) block_list_insert (bl, f1->blk_sha1s[i]); seafile_unref (f1); } else if (strcmp (file1->id, file2->id) != 0) { f1 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file1->id); if (!f1) { seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file1->id); return -1; } f2 = seaf_fs_manager_get_seafile (seaf->fs_mgr, task->repo_id, task->repo_version, file2->id); if (!f2) { seafile_unref (f1); seaf_warning ("Failed to get seafile object %s:%s.\n", task->repo_id, file2->id); return -1; } GHashTable *h = g_hash_table_new (g_str_hash, g_str_equal); int dummy; for (i = 0; i < f2->n_blocks; ++i) g_hash_table_insert (h, f2->blk_sha1s[i], &dummy); for (i = 0; i < f1->n_blocks; ++i) if (!g_hash_table_lookup (h, f1->blk_sha1s[i])) block_list_insert (bl, f1->blk_sha1s[i]); seafile_unref (f1); seafile_unref (f2); g_hash_table_destroy (h); } } return 0; } static int diff_dirs (int n, const char *basedir, SeafDirent *dirs[], void *data, gboolean *recurse) { /* Do nothing */ return 0; } static int load_blocklist_v2 (TransferTask *task) { int ret = 0; SeafBranch *local = NULL, *master = NULL; SeafCommit *local_head = NULL, *master_head = NULL; local = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "local"); if (!local) { seaf_warning ("Branch local not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!master) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } local_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, local->commit_id); if (!local_head) { seaf_warning ("Local head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } master_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, master->commit_id); if (!master_head) { seaf_warning ("Master head commit not found for repo %.8s.\n", task->repo_id); ret = -1; goto out; } BlockList *bl = block_list_new (); DiffTreesData data; data.bl = bl; data.task = task; DiffOptions opts; memset (&opts, 0, sizeof(opts)); memcpy (opts.store_id, task->repo_id, 36); opts.version = task->repo_version; opts.file_cb = diff_files; opts.dir_cb = diff_dirs; opts.data = &data; const char *trees[2]; trees[0] = local_head->root_id; trees[1] = master_head->root_id; if (diff_trees (2, trees, &opts) < 0) { seaf_warning ("Failed to diff local and master head for repo %.8s.\n", task->repo_id); ret = -1; goto out; } task->block_list = bl; out: seaf_branch_unref (local); seaf_branch_unref (master); seaf_commit_unref (local_head); seaf_commit_unref (master_head); return ret; } /* * Loading block list may take a lot of disk I/O, so do it in a thread. */ typedef void (*LoadBLCB) (TransferTask *); typedef struct LoadBLData { TransferTask *task; gboolean success; LoadBLCB callback; } LoadBLData; static void load_block_list_done (void *vdata) { LoadBLData *data = vdata; TransferTask *task = data->task; if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); g_free (data); return; } if (data->success) data->callback (task); else transition_state_to_error (task, TASK_ERR_LOAD_BLOCK_LIST); g_free (data); } static void * load_block_list_thread (void *vdata) { LoadBLData *data = vdata; int ret = 0; if (data->task->protocol_version >= 7 && data->task->type == TASK_TYPE_UPLOAD) ret = load_blocklist_v2 (data->task); else ret = seaf_transfer_task_load_blocklist (data->task); if (ret < 0) data->success = FALSE; else data->success = TRUE; return data; } static int start_load_block_list_thread (TransferTask *task, LoadBLCB callback) { LoadBLData *data = g_new0 (LoadBLData, 1); data->task = task; data->callback = callback; return ccnet_job_manager_schedule_job (seaf->job_mgr, load_block_list_thread, load_block_list_done, data); } static gboolean fs_root_collector (SeafCommit *commit, void *data, gboolean *stop) { ObjectList *ol = data; if (strcmp(commit->root_id, EMPTY_SHA1) != 0) object_list_insert (ol, commit->root_id); return TRUE; } static int generate_session_key (BlockTxInfo *info, const char *peer_id) { char *sk_base64, *sk_enc_base64; gsize enc_key_len; #ifndef USE_GPL_CRYPTO if (RAND_bytes (info->session_key, sizeof(info->session_key)) != 1) { seaf_warning ("Failed to generate random session key with RAND_bytes(), " "switch to RAND_pseudo_bytes().\n"); RAND_pseudo_bytes (info->session_key, sizeof(info->session_key)); } #endif sk_base64 = g_base64_encode (info->session_key, sizeof(info->session_key)); sk_enc_base64 = ccnet_pubkey_encrypt (seaf->ccnetrpc_client, sk_base64, peer_id); info->enc_session_key = g_base64_decode (sk_enc_base64, &enc_key_len); info->enc_key_len = (int)enc_key_len; g_free (sk_base64); g_free (sk_enc_base64); return 0; } static int update_remote_branch (TransferTask *task); static int update_local_repo (TransferTask *task); static void block_tx_client_once_mode_done_cb (BlockTxInfo *info) { switch (info->result) { case BLOCK_CLIENT_SUCCESS: if (info->task->type == TASK_TYPE_UPLOAD) update_remote_branch (info->task); else { if (update_local_repo (info->task) == 0) transition_state (info->task, TASK_STATE_FINISHED, TASK_RT_STATE_FINISHED); } break; case BLOCK_CLIENT_FAILED: case BLOCK_CLIENT_UNKNOWN: if (info->task->type == TASK_TYPE_UPLOAD) transition_state_to_error (info->task, TASK_ERR_UPLOAD_BLOCKS); else transition_state_to_error (info->task, TASK_ERR_DOWNLOAD_BLOCKS); break; case BLOCK_CLIENT_CANCELED: transition_state (info->task, TASK_STATE_CANCELED, TASK_RT_STATE_FINISHED); break; case BLOCK_CLIENT_NET_ERROR: case BLOCK_CLIENT_SERVER_ERROR: if (info->task->type == TASK_TYPE_UPLOAD) transition_state_to_error (info->task, TASK_ERR_UPLOAD_BLOCKS); else transition_state_to_error (info->task, TASK_ERR_DOWNLOAD_BLOCKS); break; } g_free (info->enc_session_key); pipeclose (info->cmd_pipe[0]); pipeclose (info->cmd_pipe[1]); g_free (info); } static void start_block_tx_client_run_once (TransferTask *task) { BlockTxInfo *info; info = g_new0 (BlockTxInfo, 1); info->task = task; /* Only use the first chunk server. */ info->cs = task->chunk_servers->data; if (generate_session_key (info, task->dest_id) < 0) { transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } if (ccnet_pipe (info->cmd_pipe) < 0) { seaf_warning ("Failed to create command pipe: %s.\n", strerror(errno)); transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } /* For old syncing protocol, set block-tx-client to run-once mode. */ info->transfer_once = TRUE; task->tx_info = info; if (block_tx_client_start (info, block_tx_client_once_mode_done_cb) < 0) { seaf_warning ("Failed to start block tx client.\n"); transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } transition_state (task, task->state, TASK_RT_STATE_DATA); } static void block_tx_client_interactive_done_cb (BlockTxInfo *info) { } static void start_block_tx_client_interactive (TransferTask *task) { BlockTxInfo *info; info = g_new0 (BlockTxInfo, 1); info->task = task; /* Only use the first chunk server. */ info->cs = task->chunk_servers->data; task->block_ids = g_queue_new(); if (generate_session_key (info, task->dest_id) < 0) { transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } if (ccnet_pipe (info->cmd_pipe) < 0) { seaf_warning ("Failed to create command pipe: %s.\n", strerror(errno)); transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } if (ccnet_pipe (info->done_pipe) < 0) { seaf_warning ("Failed to create done pipe: %s.\n", strerror(errno)); transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } task->tx_info = info; if (block_tx_client_start (info, block_tx_client_interactive_done_cb) < 0) { seaf_warning ("Failed to start block tx client.\n"); transition_state_to_error (task, TASK_ERR_START_BLOCK_CLIENT); return; } transition_state (task, task->state, TASK_RT_STATE_DATA); } typedef struct DownloadFilesData { TransferTask *task; int status; } DownloadFilesData; static void * download_and_checkout_files_thread (void *vdata) { DownloadFilesData *data = vdata; TransferTask *task = data->task; int rsp; piperead (task->tx_info->done_pipe[0], (char*)&rsp, sizeof(rsp)); if (rsp == BLOCK_CLIENT_READY) { data->status = seaf_repo_fetch_and_checkout (task, NULL, FALSE, task->head); block_tx_client_run_command (task->tx_info, BLOCK_CLIENT_CMD_END); piperead (task->tx_info->done_pipe[0], (char*)&rsp, sizeof(rsp)); } else /* block-tx-client thread should have exited. */ data->status = FETCH_CHECKOUT_FAILED; return vdata; } static void download_and_checkout_files_done (void *vdata) { DownloadFilesData *data = vdata; TransferTask *task = data->task; BlockTxInfo *info = task->tx_info; g_free (info->enc_session_key); pipeclose (info->cmd_pipe[0]); pipeclose (info->cmd_pipe[1]); pipeclose (info->done_pipe[0]); pipeclose (info->done_pipe[1]); g_queue_free (info->task->block_ids); g_free (info); switch (data->status) { case FETCH_CHECKOUT_SUCCESS: if (update_local_repo (task) == 0) transition_state (task, TASK_STATE_FINISHED, TASK_RT_STATE_FINISHED); break; case FETCH_CHECKOUT_FAILED: case FETCH_CHECKOUT_TRANSFER_ERROR: transition_state_to_error (task, TASK_ERR_DOWNLOAD_BLOCKS); break; case FETCH_CHECKOUT_CANCELED: transition_state (task, TASK_STATE_CANCELED, TASK_RT_STATE_FINISHED); break; case FETCH_CHECKOUT_LOCKED: transition_state_to_error (task, TASK_ERR_FILES_LOCKED); break; } g_free (vdata); } static void on_getcs_v2_done (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #6, #10 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { if (task->type == TASK_TYPE_DOWNLOAD && task->protocol_version >= 7) { /* Record download head commit id, so that we can resume download * if this download is interrupted. */ seaf_repo_manager_set_repo_property (seaf->repo_mgr, task->repo_id, REPO_PROP_DOWNLOAD_HEAD, task->head); start_block_tx_client_interactive (task); DownloadFilesData *data = g_new0 (DownloadFilesData, 1); data->task = task; /* This thread uses block-tx-client thread to download blocks. */ ccnet_job_manager_schedule_job (seaf->job_mgr, download_and_checkout_files_thread, download_and_checkout_files_done, data); } else start_block_tx_client_run_once (task); } else if (task->state != TASK_STATE_ERROR) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_GET_CHUNK_SERVER); } out: g_signal_handlers_disconnect_by_func (processor, on_getcs_v2_done, data); } static void get_chunk_server_address (TransferTask *task) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getcs-v2", task->dest_id); ((SeafileGetcsV2Proc *)processor)->task = task; g_signal_connect (processor, "done", (GCallback)on_getcs_v2_done, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start getcs-v2 proc.\n"); transition_state_to_error (task, TASK_ERR_GET_CHUNK_SERVER); } transition_state (task, task->state, TASK_RT_STATE_CHUNK_SERVER); } /* -------- download -------- */ static int start_getcommit_proc (TransferTask *task, const char *peer_id, GCallback done_cb) { CcnetProcessor *processor; if (task->protocol_version <= 5) processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getcommit-v2", peer_id); else processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getcommit-v3", peer_id); if (!processor) { seaf_warning ("failed to create getcommit proc.\n"); return -1; } if (task->protocol_version <= 5) ((SeafileGetcommitV2Proc *)processor)->tx_task = task; else ((SeafileGetcommitV3Proc *)processor)->tx_task = task; g_signal_connect (processor, "done", done_cb, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start getcommit proc.\n"); return -1; } return 0; } static int start_getfs_proc (TransferTask *task, const char *peer_id, GCallback done_cb) { CcnetProcessor *processor; if (task->protocol_version <= 6) processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getfs", peer_id); else processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-getfs-v2", peer_id); if (!processor) { seaf_warning ("failed to create getfs proc.\n"); return -1; } ((SeafileGetfsProc *)processor)->tx_task = task; g_signal_connect (processor, "done", done_cb, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start getfs proc.\n"); return -1; } return 0; } static void check_block_ids_for_download (TransferTask *task) { int i; BlockList *bl = task->block_list; char *block_id; task->block_ids = g_queue_new (); /* Add all blocks we don't have into task->block_ids. */ for (i = 0; i < bl->n_blocks; ++i) { block_id = g_ptr_array_index (bl->block_ids, i); if (!seaf_block_manager_block_exists (seaf->block_mgr, task->repo_id, task->repo_version, block_id)) g_queue_push_tail (task->block_ids, g_strdup(block_id)); else ++bl->n_valid_blocks; } } static void start_block_download (TransferTask *task) { check_block_ids_for_download (task); if (task->block_list->n_blocks == task->block_list->n_valid_blocks) { seaf_debug ("No block to download.\n"); if (update_local_repo (task) == 0) transition_state (task, TASK_STATE_FINISHED, TASK_RT_STATE_FINISHED); } else { get_chunk_server_address (task); } } static void on_fs_downloaded (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #6, #10 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { if (task->protocol_version <= 6) start_load_block_list_thread (task, start_block_download); else get_chunk_server_address (task); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_FS) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_DOWNLOAD_FS); } out: g_signal_handlers_disconnect_by_func (processor, on_fs_downloaded, data); } static void start_fs_download (TransferTask *task, const char *peer_id) { int ret; ObjectList *ol; if (task->protocol_version == 1) { ol = object_list_new (); ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, task->repo_id, task->repo_version, task->head, fs_root_collector, ol, FALSE); if (ret == FALSE) { object_list_free (ol); transition_state_to_error (task, TASK_ERR_LOAD_FS); return; } task->fs_roots = ol; } if (task->protocol_version <= 6 && object_list_length(task->fs_roots) == 0) { if (update_local_repo (task) == 0) transition_state (task, TASK_STATE_FINISHED, TASK_RT_STATE_FINISHED); return; } if (start_getfs_proc (task, peer_id, (GCallback)on_fs_downloaded) < 0) transition_state_to_error (task, TASK_ERR_DOWNLOAD_FS_START); else transition_state (task, task->state, TASK_RT_STATE_FS); } static int start_download (TransferTask *task); static int start_commit_download (TransferTask *task); static void on_commit_downloaded (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #5, #9 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { start_fs_download (task, processor->peer_id); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_COMMIT) { /* The task state will be transfered to error */ /* if a error occurred in getcommit-proc, otherwise, it means */ /* the processor is shutdown and the reason is recorded in */ /* processor->failure. */ transfer_task_with_proc_failure ( task, processor, TASK_ERR_DOWNLOAD_COMMIT); } out: g_signal_handlers_disconnect_by_func (processor, on_commit_downloaded, data); } static int start_commit_download (TransferTask *task) { const char *dest_id = task->dest_id; task->rsize = -1; task->dsize = 0; /* Also get the head id of the destination branch and store at task->head. */ if (start_getcommit_proc (task, dest_id, (GCallback)on_commit_downloaded) < 0) { transition_state_to_error (task, TASK_ERR_DOWNLOAD_COMMIT_START); return -1; } transition_state (task, task->state, TASK_RT_STATE_COMMIT); return 0; } static void check_download_cb (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #5, #9 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { start_commit_download (task); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_CHECK) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_UNKNOWN); } /* Errors have been processed in the processor. */ out: g_signal_handlers_disconnect_by_func (processor, check_download_cb, data); } static int start_download (TransferTask *task) { const char *dest_id = task->dest_id; CcnetProcessor *processor; if (!dest_id) return -1; if (!ccnet_peer_is_ready (seaf->ccnetrpc_client, dest_id)) return -1; #ifndef USE_GPL_CRYPTO processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-check-tx-v3", dest_id); if (!processor) { seaf_warning ("failed to create check-tx proc for download.\n"); transition_state_to_error (task, TASK_ERR_CHECK_DOWNLOAD_START); return -1; } g_signal_connect (processor, "done", (GCallback)check_download_cb, task); ((SeafileCheckTxV3Proc *)processor)->task = task; if (ccnet_processor_startl (processor, "download", NULL) < 0) { seaf_warning ("failed to start check-tx proc for download.\n"); return -1; } #endif transition_state (task, task->state, TASK_RT_STATE_CHECK); return 0; } static int update_local_repo (TransferTask *task) { SeafRepo *repo; SeafCommit *new_head; SeafBranch *branch; int ret = 0; new_head = seaf_commit_manager_get_commit (seaf->commit_mgr, task->repo_id, task->repo_version, task->head); if (!new_head) { seaf_warning ("Failed to get commit %s.\n", task->head); transition_state_to_error (task, TASK_ERR_UNKNOWN); return -1; } /* If repo doesn't exist, create it. * Note that branch doesn't exist either in this case. */ repo = seaf_repo_manager_get_repo (seaf->repo_mgr, new_head->repo_id); if (task->is_clone) { if (repo != NULL) goto out; repo = seaf_repo_new (new_head->repo_id, NULL, NULL); if (repo == NULL) { /* create repo failed */ transition_state_to_error (task, TASK_ERR_UNKNOWN); ret = -1; goto out; } seaf_repo_from_commit (repo, new_head); seaf_repo_manager_add_repo (seaf->repo_mgr, repo); /* If it's a new repo, create 'local' and 'master' branch */ branch = seaf_branch_new ("local", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); branch = seaf_branch_new ("master", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } else { if (!repo) { transition_state_to_error (task, TASK_ERR_UNKNOWN); ret = -1; goto out; } branch = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!branch) { seaf_warning ("Branch master not found for repo %.8s.\n", task->repo_id); transition_state_to_error (task, TASK_ERR_UNKNOWN); ret = -1; goto out; } seaf_branch_set_commit (branch, new_head->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); /* Update repo head branch. */ if (task->protocol_version >= 7) { seaf_branch_set_commit (repo->head, new_head->commit_id); seaf_branch_manager_update_branch (seaf->branch_mgr, repo->head); } } out: seaf_commit_unref (new_head); return ret; } static void schedule_download_task (TransferTask *task) { /* This can happen when: * 1. A repo was deleted, but we're also syncing that repo; * 2. So we just mark the repo as deleted. * 3. Before the repo is actually deleted, the user clones * the same repo. */ SyncInfo *s_info = seaf_sync_manager_get_sync_info (seaf->sync_mgr, task->repo_id); if (task->is_clone && s_info != NULL && s_info->in_sync) return; switch (task->runtime_state) { case TASK_RT_STATE_INIT: start_download (task); break; case TASK_RT_STATE_DATA: break; default: break; } } /* -------- upload -------- */ static int start_sendfs_proc (TransferTask *task, const char *peer_id, GCallback done_cb) { CcnetProcessor *processor; if (task->protocol_version <= 6) processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendfs", peer_id); else processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendfs-v2", peer_id); if (!processor) { seaf_warning ("failed to create sendfs proc.\n"); return -1; } ((SeafileSendfsProc *)processor)->tx_task = task; g_signal_connect (processor, "done", done_cb, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start sendfs proc.\n"); return -1; } return 0; } static int start_sendcommit_proc (TransferTask *task, const char *peer_id, GCallback done_cb) { CcnetProcessor *processor; if (task->protocol_version <= 5) processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendcommit-v3", peer_id); else if (task->protocol_version == 6) processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendcommit-v3-new", peer_id); else processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendcommit-v4", peer_id); if (!processor) { seaf_warning ("failed to create sendcommit proc.\n"); return -1; } ((SeafileSendcommitV3Proc *)processor)->tx_task = task; g_signal_connect (processor, "done", done_cb, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start sendcommit proc.\n"); return -1; } return 0; } static void update_branch_cb (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; if (success) { transition_state (task, TASK_STATE_FINISHED, TASK_RT_STATE_FINISHED); /* update local master branch in our usage model */ if (strcmp(task->from_branch, "local") == 0 && strcmp(task->to_branch, "master") == 0) { SeafBranch *branch; branch = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, "master"); if (!branch) { branch = seaf_branch_new ("master", task->repo_id, task->head); seaf_branch_manager_add_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } else { seaf_branch_set_commit (branch, task->head); seaf_branch_manager_update_branch (seaf->branch_mgr, branch); seaf_branch_unref (branch); } } } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_UPDATE_BRANCH) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_UNKNOWN); } /* Errors have been processed in the processor. */ } static int update_remote_branch (TransferTask *task) { CcnetProcessor *processor; processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-sendbranch", task->dest_id); if (!processor) { seaf_warning ("failed to create sendbranch proc.\n"); goto fail; } g_signal_connect (processor, "done", (GCallback)update_branch_cb, task); ((SeafileSendbranchProc *)processor)->task = task; if (ccnet_processor_startl (processor, task->repo_id, task->to_branch, task->head, NULL) < 0) { seaf_warning ("failed to start sendbranch proc.\n"); goto fail; } transition_state (task, task->state, TASK_RT_STATE_UPDATE_BRANCH); return 0; fail: transition_state_to_error (task, TASK_ERR_START_UPDATE_BRANCH); return -1; } static void on_checkbl_done (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #6, #10 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { if (g_queue_get_length (task->block_ids) == 0) { seaf_debug ("All blocks are on server already.\n"); update_remote_branch (task); goto out; } get_chunk_server_address (task); } else if (task->state != TASK_STATE_ERROR) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_CHECK_BLOCK_LIST); } out: g_signal_handlers_disconnect_by_func (processor, on_checkbl_done, data); } static void start_check_block_list_proc (TransferTask *task) { CcnetProcessor *processor; if (task->block_ids) { g_queue_foreach (task->block_ids, free_block_id, NULL); g_queue_free (task->block_ids); } task->block_ids = g_queue_new (); processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-checkbl", task->dest_id); ((SeafileCheckblProc *)processor)->task = task; if (task->protocol_version < 6) ((SeafileCheckblProc *)processor)->send_session_token = FALSE; else ((SeafileCheckblProc *)processor)->send_session_token = TRUE; g_signal_connect (processor, "done", (GCallback)on_checkbl_done, task); if (ccnet_processor_startl (processor, NULL) < 0) { seaf_warning ("failed to start checkbl proc.\n"); transition_state_to_error (task, TASK_ERR_CHECK_BLOCK_LIST); } transition_state (task, task->state, TASK_RT_STATE_CHECK_BLOCKS); } static void start_block_upload (TransferTask *task) { #if 0 if (task->block_list->n_valid_blocks != task->block_list->n_blocks) { seaf_warning ("Some blocks are missing locally, stop upload.\n"); transition_state_to_error (task, TASK_ERR_LOAD_BLOCK_LIST); return; } #endif if (task->block_list->n_blocks == 0) { seaf_debug ("No block to upload.\n"); update_remote_branch (task); } else start_check_block_list_proc (task); } static void on_fs_uploaded (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #6, #10 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { start_load_block_list_thread (task, start_block_upload); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_FS) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_UPLOAD_FS); } out: g_signal_handlers_disconnect_by_func (processor, on_fs_uploaded, data); } static void start_fs_upload (TransferTask *task, const char *peer_id) { int ret; ObjectList *ol; if (task->protocol_version == 1) { ol = object_list_new (); ret = seaf_commit_manager_traverse_commit_tree (seaf->commit_mgr, task->repo_id, task->repo_version, task->head, fs_root_collector, ol, FALSE); if (ret == FALSE) { object_list_free (ol); transition_state_to_error (task, TASK_ERR_LOAD_FS); return; } task->fs_roots = ol; } if (task->protocol_version <= 6 && object_list_length(task->fs_roots) == 0) { update_remote_branch (task); return; } if (start_sendfs_proc (task, peer_id, (GCallback)on_fs_uploaded) < 0) transition_state_to_error (task, TASK_ERR_UPLOAD_FS_START); else transition_state (task, task->state, TASK_RT_STATE_FS); } static void on_commit_uploaded (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #5, #9 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { start_fs_upload (task, processor->peer_id); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_COMMIT) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_UPLOAD_COMMIT); } out: g_signal_handlers_disconnect_by_func (processor, on_commit_uploaded, data); } static int start_commit_upload (TransferTask *task) { task->rsize = -1; task->dsize = 0; if (start_sendcommit_proc (task, task->dest_id, (GCallback)on_commit_uploaded) < 0) { transition_state_to_error (task, TASK_ERR_UPLOAD_COMMIT_START); return -1; } transition_state (task, task->state, TASK_RT_STATE_COMMIT); return 0; } static void check_upload_cb (CcnetProcessor *processor, gboolean success, void *data) { TransferTask *task = data; /* if the user stopped or canceled this task, stop processing. */ /* state #5, #9 */ if (task->state == TASK_STATE_CANCELED) { transition_state (task, task->state, TASK_RT_STATE_FINISHED); goto out; } if (success) { start_commit_upload (task); } else if (task->state != TASK_STATE_ERROR && task->runtime_state == TASK_RT_STATE_CHECK) { transfer_task_with_proc_failure ( task, processor, TASK_ERR_UNKNOWN); } /* Errors have been processed in the processor. */ out: g_signal_handlers_disconnect_by_func (processor, check_upload_cb, data); } static int start_upload (TransferTask *task) { const char *dest_id = task->dest_id; CcnetProcessor *processor; SeafBranch *branch; if (!dest_id) return -1; if (!ccnet_peer_is_ready (seaf->ccnetrpc_client, dest_id)) return -1; branch = seaf_branch_manager_get_branch (seaf->branch_mgr, task->repo_id, task->from_branch); if (!branch) { seaf_warning ("[Upload] Bad source branch %s.\n", task->from_branch); transition_state_to_error (task, TASK_ERR_BAD_LOCAL_BRANCH); return -1; } memcpy (task->head, branch->commit_id, 41); seaf_branch_unref (branch); #ifndef USE_GPL_CRYPTO processor = ccnet_proc_factory_create_remote_master_processor ( seaf->session->proc_factory, "seafile-check-tx-v3", dest_id); if (!processor) { seaf_warning ("failed to create check-tx-v3 proc for upload.\n"); transition_state_to_error (task, TASK_ERR_CHECK_UPLOAD_START); return -1; } g_signal_connect (processor, "done", (GCallback)check_upload_cb, task); ((SeafileCheckTxV3Proc *)processor)->task = task; if (ccnet_processor_startl (processor, "upload", NULL) < 0) { seaf_warning ("failed to start check-tx-v3 proc for upload.\n"); return -1; } #endif transition_state (task, task->state, TASK_RT_STATE_CHECK); return 0; } static void schedule_upload_task (TransferTask *task) { switch (task->runtime_state) { case TASK_RT_STATE_INIT: start_upload (task); break; case TASK_RT_STATE_DATA: break; default: break; } } /* -------- schedule -------- */ static void resume_task_from_netdown(TransferTask *task, const char *dest_id) { if (!task || !dest_id) return; if (task->runtime_state == TASK_RT_STATE_NETDOWN) { switch (task->last_runtime_state) { case TASK_RT_STATE_CHECK: if (task->type == TASK_TYPE_DOWNLOAD) start_download(task); else start_upload(task); break; case TASK_RT_STATE_COMMIT: if (task->type == TASK_TYPE_DOWNLOAD) start_commit_download(task); else start_commit_upload(task); break; case TASK_RT_STATE_FS: if (task->type == TASK_TYPE_DOWNLOAD) start_fs_download(task, dest_id); else start_fs_upload(task, dest_id); break; case TASK_RT_STATE_CHECK_BLOCKS: g_return_if_fail (task->type == TASK_TYPE_UPLOAD); start_check_block_list_proc (task); break; case TASK_RT_STATE_CHUNK_SERVER: get_chunk_server_address (task); break; default: break ; } } } static void state_machine_tick (TransferTask *task) { switch (task->state) { case TASK_STATE_NORMAL: /* If repo was deleted, cancel any transfer task for it. * Also note that the repo doesn't exist if we're cloning it. */ if (!task->is_clone && !seaf_repo_manager_repo_exists (seaf->repo_mgr, task->repo_id)) { cancel_task (task); break; } /* state #1, #2, #3, #4 */ if (task->runtime_state == TASK_RT_STATE_NETDOWN) { const char *dest_id = task->dest_id; if (dest_id && ccnet_peer_is_ready (seaf->ccnetrpc_client, dest_id)) { seaf_debug ("[tr-mgr] Resume transfer repo %.8s when " "peer %.10s is reconnected\n", task->repo_id, dest_id); g_return_if_fail (task->last_runtime_state != TASK_RT_STATE_NETDOWN && task->last_runtime_state != TASK_RT_STATE_FINISHED); resume_task_from_netdown(task, dest_id); } } else if (task->runtime_state != TASK_RT_STATE_FINISHED) { if (task->type == TASK_TYPE_DOWNLOAD) schedule_download_task (task); else schedule_upload_task (task); } else { /* normal && finish, can't happen */ g_return_if_reached (); } break; case TASK_STATE_FINISHED: /* state #13 */ g_return_if_fail (task->runtime_state == TASK_RT_STATE_FINISHED); break; case TASK_STATE_CANCELED: /* state #11 */ break; case TASK_STATE_ERROR: /* state #14 */ g_return_if_fail (task->runtime_state == TASK_RT_STATE_FINISHED); break; default: g_return_if_reached (); } } static int schedule_task_pulse (void *vmanager) { SeafTransferManager *mgr = vmanager; GHashTableIter iter; gpointer key, value; TransferTask *task; g_hash_table_iter_init (&iter, mgr->download_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; state_machine_tick (task); } g_hash_table_iter_init (&iter, mgr->upload_tasks); while (g_hash_table_iter_next (&iter, &key, &value)) { task = value; state_machine_tick (task); } return TRUE; } seafile-6.1.5/daemon/transfer-mgr.h000066400000000000000000000172551323477647300172100ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef TRANSFER_MGR_H #define TRANSFER_MGR_H #include #include #include #include "object-list.h" #include "repo-mgr.h" #include "fs-mgr.h" #include "branch-mgr.h" /* * Transfer Task. */ enum { TASK_TYPE_DOWNLOAD = 0, TASK_TYPE_UPLOAD, }; /** * The state that can be set by user. * * A task in NORMAL state can be canceled; * A task in RT_STATE_FINISHED can be removed. */ enum TaskState { TASK_STATE_NORMAL = 0, TASK_STATE_CANCELED, TASK_STATE_FINISHED, TASK_STATE_ERROR, N_TASK_STATE, }; enum TaskRuntimeState { TASK_RT_STATE_INIT = 0, TASK_RT_STATE_CHECK, TASK_RT_STATE_COMMIT, TASK_RT_STATE_FS, TASK_RT_STATE_CHECK_BLOCKS, TASK_RT_STATE_CHUNK_SERVER, TASK_RT_STATE_DATA, TASK_RT_STATE_UPDATE_BRANCH, /* Only used in upload. */ TASK_RT_STATE_FINISHED, TASK_RT_STATE_NETDOWN, N_TASK_RT_STATE, }; enum TaskError { TASK_OK = 0, TASK_ERR_UNKNOWN, TASK_ERR_NO_SERVICE, TASK_ERR_PROC_PERM_ERR, TASK_ERR_CHECK_UPLOAD_START, TASK_ERR_CHECK_DOWNLOAD_START, TASK_ERR_ACCESS_DENIED, TASK_ERR_BAD_REPO_ID, TASK_ERR_UPLOAD_COMMIT_START, TASK_ERR_DOWNLOAD_COMMIT_START, TASK_ERR_UPLOAD_COMMIT, TASK_ERR_DOWNLOAD_COMMIT, TASK_ERR_UPLOAD_FS_START, TASK_ERR_DOWNLOAD_FS_START, TASK_ERR_LOAD_FS, TASK_ERR_UPLOAD_FS, TASK_ERR_DOWNLOAD_FS, TASK_ERR_LOAD_BLOCK_LIST, TASK_ERR_START_UPDATE_BRANCH, TASK_ERR_NOT_FAST_FORWARD, TASK_ERR_QUOTA_FULL, TASK_ERR_CHECK_QUOTA, TASK_ERR_PROTOCOL_VERSION, TASK_ERR_BAD_LOCAL_BRANCH, TASK_ERR_CHECK_BLOCK_LIST, TASK_ERR_GET_CHUNK_SERVER, TASK_ERR_START_BLOCK_CLIENT, TASK_ERR_UPLOAD_BLOCKS, TASK_ERR_DOWNLOAD_BLOCKS, TASK_ERR_DEPRECATED_SERVER, TASK_ERR_FILES_LOCKED, N_TASK_ERROR, }; typedef struct { char *addr; int port; } ChunkServer; enum { BLOCK_CLIENT_UNKNOWN = 0, BLOCK_CLIENT_SUCCESS, BLOCK_CLIENT_FAILED, BLOCK_CLIENT_NET_ERROR, BLOCK_CLIENT_SERVER_ERROR, BLOCK_CLIENT_CANCELED, /* result codes only used in interactive mode. */ BLOCK_CLIENT_READY, BLOCK_CLIENT_ENDED, }; #define BLOCK_TX_SESSION_KEY_LEN 32 struct _TransferTask; typedef struct _BlockTxInfo { struct _TransferTask *task; ChunkServer *cs; unsigned char session_key[BLOCK_TX_SESSION_KEY_LEN]; unsigned char *enc_session_key; /* encrypted session_key */ int enc_key_len; int cmd_pipe[2]; /* used to notify cancel */ int done_pipe[2]; /* notify block transfer done */ int result; int n_failure; /* TRUE if the client only transfer one batch of blocks and end.*/ gboolean transfer_once; gint ready_for_transfer; } BlockTxInfo; struct _SeafTransferManager; struct _TransferTask { struct _SeafTransferManager *manager; char tx_id[37]; char repo_id[37]; int repo_version; char *token; char *session_token; int protocol_version; char *from_branch; char *to_branch; char head[41]; char remote_head[41]; int state; /* NORMAL, STOPPED, CANCELED */ int runtime_state; int last_runtime_state; int type; gboolean is_clone; /* TRUE when fetching a new repo. */ char *email; int error; char *dest_id; ObjectList *commits; /* commits need to be uploaded */ ObjectList *fs_roots; /* the root of file systems to be sent/get */ GList *chunk_servers; BlockList *block_list; gint tx_bytes; /* bytes transferred in the this second. */ gint last_tx_bytes; /* bytes transferred in the last second. */ /* Fields only used by upload task. */ int n_uploaded; /* For new block transfer protocol */ BlockTxInfo *tx_info; GQueue *block_ids; gboolean server_side_merge; /* These two fields are only used for new syncing protocol. */ char *passwd; char *worktree; /* Used to display download progress for new syncing protocol */ int n_to_download; int n_downloaded; gint64 rsize; /* size remain */ gint64 dsize; /* size done */ }; typedef struct _TransferTask TransferTask; const char * task_state_to_str (int state); const char * task_rt_state_to_str (int rt_state); const char * task_error_str (int task_errno); int transfer_task_get_rate (TransferTask *task); int transfer_task_get_done_blocks (TransferTask *task); void transfer_task_set_error (TransferTask *task, int error); void transfer_task_set_netdown (TransferTask *task); void transition_state_to_error (TransferTask *task, int task_errno); /* * Transfer Manager */ struct _SeafileSession; struct _SeafTransferManager { struct _SeafileSession *seaf; sqlite3 *db; GHashTable *download_tasks; GHashTable *upload_tasks; CcnetTimer *schedule_timer; }; typedef struct _SeafTransferManager SeafTransferManager; SeafTransferManager *seaf_transfer_manager_new (struct _SeafileSession *seaf); int seaf_transfer_manager_start (SeafTransferManager *manager); char * seaf_transfer_manager_add_download (SeafTransferManager *manager, const char *repo_id, int repo_version, const char *peer_id, const char *from_branch, const char *to_branch, const char *token, gboolean server_side_merge, const char *passwd, const char *worktree, const char *email, GError **error); char * seaf_transfer_manager_add_upload (SeafTransferManager *manager, const char *repo_id, int repo_version, const char *peer_id, const char *from_branch, const char *to_branch, const char *token, gboolean server_side_merge, GError **error); GList* seaf_transfer_manager_get_upload_tasks (SeafTransferManager *manager); GList* seaf_transfer_manager_get_download_tasks (SeafTransferManager *manager); /* find running tranfer of a repo */ TransferTask* seaf_transfer_manager_find_transfer_by_repo (SeafTransferManager *manager, const char *repo_id); void seaf_transfer_manager_remove_task (SeafTransferManager *manager, const char *tx_id, int task_type); void seaf_transfer_manager_cancel_task (SeafTransferManager *manager, const char *tx_id, int task_type); GList * seaf_transfer_manager_get_clone_heads (SeafTransferManager *mgr); char * seaf_transfer_manager_get_clone_head (SeafTransferManager *mgr, const char *repo_id); /* * return the status code of block tx client. */ int seaf_transfer_manager_download_file_blocks (SeafTransferManager *manager, TransferTask *task, const char *file_id); #endif seafile-6.1.5/daemon/vc-utils.c000066400000000000000000001042441323477647300163350ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #define DEBUG_FLAG SEAFILE_DEBUG_MERGE #include "log.h" #include "seafile-error.h" #include #include #include #include "seafile-session.h" #include "utils.h" #include "fs-mgr.h" #include "merge.h" #include "vc-utils.h" #include "vc-common.h" #include "index/index.h" static gint compare_dirents (gconstpointer a, gconstpointer b) { const SeafDirent *denta = a, *dentb = b; return strcmp (dentb->name, denta->name); } int commit_trees_cb (const char *repo_id, int version, const char *worktree, struct cache_tree *it, struct cache_entry **cache, int entries, const char *base, int baselen) { SeafDir *seaf_dir; GList *dirents = NULL, *ptr; int i; for (i = 0; i < entries; i++) { SeafDirent *seaf_dent; char *name; struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, entlen; const unsigned char *sha1; char hex[41]; unsigned mode; guint64 mtime; gint64 size; char *modifier; if (ce->ce_flags & CE_REMOVE) continue; /* entry being removed */ path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (slash) { entlen = slash - (path + baselen); sub = cache_tree_find_subtree(it, path + baselen, entlen, 0); g_return_val_if_fail (sub != NULL, -1); /* Skip cache entries in the sub level. */ i += sub->cache_tree->entry_count - 1; sha1 = sub->cache_tree->sha1; mtime = sub->cache_tree->mtime; mode = S_IFDIR; name = g_strndup(path + baselen, entlen); rawdata_to_hex (sha1, hex, 20); seaf_dent = seaf_dirent_new (dir_version_from_repo_version(version), hex, mode, name, mtime, NULL, -1); g_free(name); dirents = g_list_prepend (dirents, seaf_dent); } else { sha1 = ce->sha1; mode = ce->ce_mode; mtime = ce->ce_mtime.sec; size = ce->ce_size; modifier = ce->modifier; entlen = pathlen - baselen; name = g_strndup(path + baselen, entlen); rawdata_to_hex (sha1, hex, 20); if (version > 0) { seaf_dent = seaf_dirent_new (dir_version_from_repo_version(version), hex, mode, name, mtime, modifier, size); } else { seaf_dent = seaf_dirent_new (0, hex, mode, name, 0, NULL, -1); } g_free(name); dirents = g_list_prepend (dirents, seaf_dent); } #if DEBUG fprintf(stderr, "cache-tree update-one %o %.*s\n", mode, entlen, path + baselen); #endif } /* Sort dirents in descending order. */ dirents = g_list_sort (dirents, compare_dirents); seaf_dir = seaf_dir_new (NULL, dirents, dir_version_from_repo_version(version)); hex_to_rawdata (seaf_dir->dir_id, it->sha1, 20); /* Dir's mtime is the latest of all dir entires. */ guint64 dir_mtime = 0; SeafDirent *dent; for (ptr = dirents; ptr; ptr = ptr->next) { dent = ptr->data; if (dent->mtime > dir_mtime) dir_mtime = dent->mtime; } it->mtime = dir_mtime; if (!seaf_fs_manager_object_exists (seaf->fs_mgr, repo_id, version, seaf_dir->dir_id)) seaf_dir_save (seaf->fs_mgr, repo_id, version, seaf_dir); #if DEBUG for (p = dirents; p; p = p->next) { SeafDirent *tmp = (SeafDirent *)p->data; fprintf(stderr, "dump dirent name %s id %s\n", tmp->name, tmp->id); } #endif seaf_dir_free (seaf_dir); return 0; } int update_index (struct index_state *istate, const char *index_path) { char index_shadow[SEAF_PATH_MAX]; int index_fd; int ret = 0; snprintf (index_shadow, SEAF_PATH_MAX, "%s.shadow", index_path); index_fd = seaf_util_create (index_shadow, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); if (index_fd < 0) { seaf_warning ("Failed to open shadow index: %s.\n", strerror(errno)); return -1; } if (write_index (istate, index_fd) < 0) { seaf_warning ("Failed to write shadow index: %s.\n", strerror(errno)); close (index_fd); return -1; } close (index_fd); ret = seaf_util_rename (index_shadow, index_path); if (ret < 0) { seaf_warning ("Failed to update index errno=%d %s\n", errno, strerror(errno)); return -1; } return 0; } #ifndef WIN32 int seaf_remove_empty_dir (const char *path) { SeafStat st; GDir *dir; const char *dname; char *full_path; GError *error = NULL; if (seaf_stat (path, &st) < 0 || !S_ISDIR(st.st_mode)) return 0; if (seaf_util_rmdir (path) < 0) { dir = g_dir_open (path, 0, &error); if (!dir) { seaf_warning ("Failed to open dir %s: %s.\n", path, error->message); return -1; } /* Remove all ignored hidden files. */ while ((dname = g_dir_read_name (dir)) != NULL) { if (seaf_repo_manager_is_ignored_hidden_file(dname)) { full_path = g_build_path ("/", path, dname, NULL); if (seaf_util_unlink (full_path) < 0) seaf_warning ("Failed to remove file %s: %s.\n", full_path, strerror(errno)); g_free (full_path); } } g_dir_close (dir); if (seaf_util_rmdir (path) < 0) { seaf_warning ("Failed to remove dir %s: %s.\n", path, strerror(errno)); return -1; } } return 0; } #else static int remove_hidden_file (wchar_t *parent, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { char *dname = NULL; wchar_t *subpath_w = NULL; char *subpath = NULL; dname = g_utf16_to_utf8 (fdata->cFileName, -1, NULL, NULL, NULL); if (!(fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && seaf_repo_manager_is_ignored_hidden_file(dname)) { subpath_w = g_new0 (wchar_t, wcslen(parent) + wcslen(fdata->cFileName) + 2); wcscpy (subpath_w, parent); wcscat (subpath_w, L"\\"); wcscat (subpath_w, fdata->cFileName); if (!DeleteFileW (subpath_w)) { subpath = g_utf16_to_utf8 (subpath_w, -1, NULL, NULL, NULL); seaf_warning ("Failed to remove file %s: %lu.\n", subpath, GetLastError()); g_free (subpath); } g_free (subpath_w); } g_free (dname); return 0; } int seaf_remove_empty_dir (const char *path) { wchar_t *path_w = NULL; WIN32_FILE_ATTRIBUTE_DATA attrs; int ret = 0; path_w = win32_long_path (path); if (!GetFileAttributesExW (path_w, GetFileExInfoStandard, &attrs)) { goto out; } if (!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { goto out; } if (RemoveDirectoryW (path_w)) goto out; if (GetLastError() == ERROR_DIR_NOT_EMPTY) { traverse_directory_win32 (path_w, remove_hidden_file, NULL); if (!RemoveDirectoryW (path_w)) { seaf_warning ("Failed to remove dir %s: %lu.\n", path, GetLastError()); ret = -1; } } else { seaf_warning ("Failed to remove dir %s: %lu.\n", path, GetLastError()); ret = -1; } out: g_free (path_w); return ret; } #endif /* WIN32 */ static int unlink_entry (struct cache_entry *ce, struct unpack_trees_options *o) { char path[SEAF_PATH_MAX]; SeafStat st; int base_len = strlen(o->base); int len = ce_namelen(ce); int offset; if (!len) { seaf_warning ("entry name should not be empty.\n"); return -1; } snprintf (path, SEAF_PATH_MAX, "%s/%s", o->base, ce->name); if (!S_ISDIR(ce->ce_mode)) { /* file doesn't exist in work tree */ if (seaf_stat (path, &st) < 0 || !S_ISREG(st.st_mode)) { return 0; } /* file has been changed. */ if (!o->reset && (ce->current_mtime != st.st_mtime)) { seaf_warning ("File %s is changed. Skip removing the file.\n", path); return -1; } /* first unlink the file. */ if (seaf_util_unlink (path) < 0) { seaf_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); return -1; } } else { if (seaf_remove_empty_dir (path) < 0) { seaf_warning ("Failed to remove dir %s: %s.\n", path, strerror(errno)); return -1; } } /* then remove all empty directories upwards. */ offset = base_len + len; do { if (path[offset] == '/') { path[offset] = '\0'; int ret = seaf_remove_empty_dir (path); if (ret < 0) { break; } } } while (--offset > base_len); return 0; } static int compute_file_id_with_cdc (const char *path, SeafStat *st, SeafileCrypt *crypt, int repo_version, uint32_t blk_avg_size, uint32_t blk_min_size, uint32_t blk_max_size, unsigned char sha1[]) { CDCFileDescriptor cdc; memset (&cdc, 0, sizeof(cdc)); cdc.block_sz = blk_avg_size; cdc.block_min_sz = blk_min_size; cdc.block_max_sz = blk_max_size; cdc.write_block = seafile_write_chunk; if (filename_chunk_cdc (path, &cdc, crypt, FALSE) < 0) { seaf_warning ("Failed to chunk file.\n"); return -1; } if (repo_version > 0) seaf_fs_manager_calculate_seafile_id_json (repo_version, &cdc, sha1); else memcpy (sha1, cdc.file_sum, 20); if (cdc.blk_sha1s) free (cdc.blk_sha1s); return 0; } int compare_file_content (const char *path, SeafStat *st, const unsigned char *ce_sha1, SeafileCrypt *crypt, int repo_version) { unsigned char sha1[20]; if (st->st_size == 0) { memset (sha1, 0, 20); return hashcmp (sha1, ce_sha1); } else { if (compute_file_id_with_cdc (path, st, crypt, repo_version, CDC_AVERAGE_BLOCK_SIZE, CDC_MIN_BLOCK_SIZE, CDC_MAX_BLOCK_SIZE, sha1) < 0) { return -1; } if (hashcmp (sha1, ce_sha1) == 0) return 0; /* Compare with old cdc block size. */ uint32_t block_size = calculate_chunk_size (st->st_size); if (compute_file_id_with_cdc (path, st, crypt, repo_version, block_size, block_size >> 2, block_size << 2, sha1) < 0) { return -1; } return hashcmp (sha1, ce_sha1); } } #if defined WIN32 || defined __APPLE__ /* * If the names are different case-sensitively but the same case-insensitively, * it's a case conflict. * Note that the names are in UTF-8, so we use UTF-8 function to compare them. */ static gboolean case_conflict_utf8 (const char *name1, const char *name2) { char *casefold1, *casefold2; gboolean ret; if (strcmp (name1, name2) == 0) return FALSE; casefold1 = g_utf8_casefold (name1, -1); casefold2 = g_utf8_casefold (name2, -1); ret = (g_utf8_collate (casefold1, casefold2) == 0); g_free (casefold1); g_free (casefold2); return ret; } #ifndef WIN32 static gboolean case_conflict_exists (const char *dir_path, const char *new_dname, char **conflict_dname) { GDir *dir; const char *dname; gboolean is_case_conflict = FALSE; GError *error = NULL; /* Don't generate "case conflict" files for a case-conflicted file. */ if (strstr (new_dname, "case conflict") != NULL) { return is_case_conflict; } dir = g_dir_open (dir_path, 0, &error); if (!dir && error) { seaf_warning ("Failed to open dir %s: %s.\n", dir_path, error->message); g_error_free (error); return FALSE; } while (1) { dname = g_dir_read_name (dir); if (!dname) break; char *norm_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC); if (case_conflict_utf8 (norm_dname, new_dname)) { is_case_conflict = TRUE; *conflict_dname = norm_dname; break; } g_free (norm_dname); } g_dir_close (dir); return is_case_conflict; } #else typedef struct CaseConflictData { const char *new_dname; gboolean is_case_conflict; char *conflict_dname; } CaseConflictData; static int check_case_conflict_cb (wchar_t *parent, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop) { CaseConflictData *data = user_data; char *dname = NULL; dname = g_utf16_to_utf8 (fdata->cFileName, -1, NULL, NULL, NULL); if (case_conflict_utf8 (dname, data->new_dname)) { data->is_case_conflict = TRUE; data->conflict_dname = g_strdup(dname); *stop = TRUE; } g_free (dname); return 0; } static gboolean case_conflict_exists (const char *dir_path, const char *new_dname, char **conflict_dname) { wchar_t *dir_path_w; gboolean is_case_conflict = FALSE; CaseConflictData data; /* Don't generate "case conflict" files for a case-conflicted file. */ if (strstr (new_dname, "case conflict") != NULL) { return is_case_conflict; } dir_path_w = win32_long_path (dir_path); memset (&data, 0, sizeof(data)); data.new_dname = new_dname; if (traverse_directory_win32 (dir_path_w, check_case_conflict_cb, &data) < 0) goto out; is_case_conflict = data.is_case_conflict; *conflict_dname = data.conflict_dname; out: g_free (dir_path_w); return is_case_conflict; } #endif /* WIN32 */ /* * If files "test (case conflict 1).txt" and "Test (case conflict 2).txt" exist, * and we have to checkout "TEST.txt", it will be checked out to "TEST * (case conflict 3).txt". * To prevent generating too many case conflict files (in case of bug or other * reasons), no more than 10 case conflict files will be generated for the same * filename. After that, all later confilcted files will use the last conflict * file name. */ static char * gen_case_conflict_free_dname (const char *dir_path, const char *dname) { char *copy = g_strdup (dname); GString *buf = g_string_new (NULL); char ret_dname[256]; char *dot, *ext; int cnt = 1; dot = strrchr (copy, '.'); while (cnt < 11) { if (dot != NULL) { *dot = '\0'; ext = dot + 1; snprintf (ret_dname, sizeof(ret_dname), "%s (case conflict %d).%s", copy, cnt, ext); g_string_printf (buf, "%s/%s (case conflict %d).%s", dir_path, copy, cnt, ext); } else { snprintf (ret_dname, sizeof(ret_dname), "%s (case conflict %d)", copy, cnt); g_string_printf (buf, "%s/%s (case conflict %d)", dir_path, copy, cnt); } if (!seaf_util_exists (buf->str)) break; g_string_truncate (buf, 0); ++cnt; } g_free (copy); g_string_free (buf, TRUE); return g_strdup(ret_dname); } /* * @conflict_hash: conflicting_dir_path -> conflict_free_dname * @no_conflict_hash: a hash table to remember dirs that have no case conflict. */ char * build_case_conflict_free_path (const char *worktree, const char *ce_name, GHashTable *conflict_hash, GHashTable *no_conflict_hash, gboolean *is_case_conflict, gboolean is_rename) { GString *buf = g_string_new (worktree); char **components, *ptr; guint i, n_comps; static int dummy; char *conflict_dname = NULL; components = g_strsplit (ce_name, "/", -1); n_comps = g_strv_length (components); for (i = 0; i < n_comps; ++i) { char *path = NULL, *dname = NULL; SeafStat st; ptr = components[i]; path = g_build_path ("/", buf->str, ptr, NULL); /* If path doesn't exist, case conflict is not possible. */ if (seaf_stat (path, &st) < 0) { if (i != n_comps - 1) { if (seaf_util_mkdir (path, 0777) < 0) { seaf_warning ("Failed to create dir %s.\n", path); g_free (path); goto error; } } g_string_append_printf (buf, "/%s", ptr); g_free (path); continue; } dname = g_hash_table_lookup (conflict_hash, path); if (dname) { /* We've detected (and fixed) case conflict for this dir before. */ *is_case_conflict = TRUE; g_free (path); g_string_append_printf (buf, "/%s", dname); continue; } if (g_hash_table_lookup (no_conflict_hash, path) != NULL) { /* We've confirmed this dir has no case conflict before. */ g_free (path); g_string_append_printf (buf, "/%s", ptr); continue; } /* No luck in the hash tables, we have to run case conflict detection. */ if (!case_conflict_exists (buf->str, ptr, &conflict_dname)) { /* No case conflict. */ if (i != n_comps - 1) g_hash_table_insert (no_conflict_hash, g_strdup(path), &dummy); g_free (path); g_string_append_printf (buf, "/%s", ptr); continue; } *is_case_conflict = TRUE; /* If case conflict, create a conflict free path and * remember it in the hash table. */ if (!is_rename) { dname = gen_case_conflict_free_dname (buf->str, ptr); char *case_conflict_free_path = g_build_path ("/", buf->str, dname, NULL); if (i != n_comps - 1) { if (seaf_util_mkdir (case_conflict_free_path, 0777) < 0) { seaf_warning ("Failed to create dir %s.\n", case_conflict_free_path); g_free (path); g_free (dname); g_free (case_conflict_free_path); goto error; } g_hash_table_insert (conflict_hash, g_strdup(path), g_strdup(dname)); } g_string_append_printf (buf, "/%s", dname); g_free (dname); g_free (case_conflict_free_path); } else { char *src_path = g_build_path ("/", buf->str, conflict_dname, NULL); if (i != (n_comps - 1) && seaf_util_rename (src_path, path) < 0) { seaf_warning ("Failed to rename %s to %s: %s.\n", src_path, path, strerror(errno)); g_free (path); g_free (src_path); goto error; } /* Since the exsiting dir in the worktree has been renamed, * there is no more case conflict. */ g_hash_table_insert (no_conflict_hash, g_strdup(path), &dummy); g_string_append_printf (buf, "/%s", ptr); g_free (src_path); } g_free (conflict_dname); g_free (path); } g_strfreev (components); return g_string_free (buf, FALSE); error: g_strfreev (components); return NULL; } #endif /* defined WIN32 || defined __APPLE__ */ char * build_checkout_path (const char *worktree, const char *ce_name, int len) { int base_len = strlen(worktree); int full_len; char path[SEAF_PATH_MAX]; int offset; SeafStat st; if (!len) { seaf_warning ("entry name should not be empty.\n"); return NULL; } snprintf (path, SEAF_PATH_MAX, "%s/", worktree); /* first create all leading directories. */ full_len = base_len + len + 1; offset = base_len + 1; while (offset < full_len) { do { path[offset] = ce_name[offset-base_len-1]; offset++; } while (offset < full_len && ce_name[offset-base_len-1] != '/'); if (offset >= full_len) break; path[offset] = 0; if (seaf_stat (path, &st) == 0 && S_ISDIR(st.st_mode)) continue; if (seaf_util_mkdir (path, 0777) < 0) { seaf_warning ("Failed to create directory %s.\n", path); return NULL; } } path[offset] = 0; return g_strdup(path); } static int checkout_entry (struct cache_entry *ce, struct unpack_trees_options *o, gboolean recover_merge, const char *conflict_head_id, GHashTable *conflict_hash, GHashTable *no_conflict_hash) { char *path_in, *path; SeafStat st; char file_id[41]; gboolean case_conflict = FALSE; gboolean force_conflict = FALSE; path_in = g_build_path ("/", o->base, ce->name, NULL); #if defined WIN32 || defined __APPLE__ path = build_case_conflict_free_path (o->base, ce->name, conflict_hash, no_conflict_hash, &case_conflict, FALSE); #else path = build_checkout_path (o->base, ce->name, ce_namelen(ce)); #endif g_free (path_in); if (!path) return -1; if (!S_ISDIR(ce->ce_mode)) { /* In case that we're replacing an empty dir with a file, * we need first to remove the empty dir. */ if (seaf_stat (path, &st) == 0 && S_ISDIR(st.st_mode)) { if (seaf_util_rmdir (path) < 0) { seaf_warning ("Failed to remove dir %s: %s\n", path, strerror(errno)); /* Don't quit since we can handle conflict later. */ } } } else { if (seaf_util_mkdir (path, 0777) < 0) { seaf_warning ("Failed to create empty dir %s in checkout.\n", path); g_free (path); return -1; } if (ce->ce_mtime.sec != 0 && seaf_set_file_time (path, ce->ce_mtime.sec) < 0) { seaf_warning ("Failed to set mtime for %s.\n", path); } goto update_cache; } if (!o->reset && seaf_stat (path, &st) == 0 && S_ISREG(st.st_mode) && (ce->current_mtime != st.st_mtime)) { /* If we're recovering an interrupted merge, we don't know whether * the file was changed by checkout or by the user. So we have to * calculate the sha1 for that file and compare it with the one in * cache entry. */ if (!recover_merge || compare_file_content (path, &st, ce->sha1, o->crypt, o->version) != 0) { seaf_warning ("File %s is changed. Checkout to conflict file.\n", path); force_conflict = TRUE; } else { /* Recover merge and file content matches index entry. * We were interrupted before updating the index, update index * entry timestamp now. */ goto update_cache; } } /* then checkout the file. */ gboolean conflicted = FALSE; rawdata_to_hex (ce->sha1, file_id, 20); if (seaf_fs_manager_checkout_file (seaf->fs_mgr, o->repo_id, o->version, file_id, path, ce->ce_mode, ce->ce_mtime.sec, o->crypt, ce->name, conflict_head_id, force_conflict, &conflicted, NULL) < 0) { seaf_warning ("Failed to checkout file %s.\n", path); g_free (path); return -1; } /* If case conflict, this file has been checked out to another path. * Remove the current entry, otherwise it won't be removed later * since it's timestamp is 0. */ if (case_conflict) { ce->ce_flags |= CE_REMOVE; g_free (path); return 0; } if (conflicted) { g_free (path); return 0; } update_cache: /* finally fill cache_entry info */ /* Only update index if we checked out the file without any error * or conflicts. The timestamp of the entry will remain 0 if error * or conflicted. */ seaf_stat (path, &st); fill_stat_cache_info (ce, &st); g_free (path); return 0; } int update_worktree (struct unpack_trees_options *o, gboolean recover_merge, const char *conflict_head_id, const char *default_conflict_suffix, int *finished_entries) { struct index_state *result = &o->result; int i; struct cache_entry *ce; int errs = 0; GHashTable *conflict_hash, *no_conflict_hash; for (i = 0; i < result->cache_nr; ++i) { ce = result->cache[i]; if (ce->ce_flags & CE_WT_REMOVE) errs |= unlink_entry (ce, o); } conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); no_conflict_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); for (i = 0; i < result->cache_nr; ++i) { ce = result->cache[i]; if (ce->ce_flags & CE_UPDATE) { errs |= checkout_entry (ce, o, recover_merge, conflict_head_id, conflict_hash, no_conflict_hash); } if (finished_entries) *finished_entries = *finished_entries + 1; } g_hash_table_destroy (conflict_hash); g_hash_table_destroy (no_conflict_hash); if (errs != 0) return -1; return 0; } int delete_path (const char *worktree, const char *name, unsigned int mode, gint64 old_mtime) { char path[SEAF_PATH_MAX]; SeafStat st; int len = strlen(name); if (!len) { seaf_warning ("entry name should not be empty.\n"); return -1; } snprintf (path, SEAF_PATH_MAX, "%s/%s", worktree, name); if (!S_ISDIR(mode)) { /* file doesn't exist in work tree */ if (seaf_stat (path, &st) < 0 || !S_ISREG(st.st_mode)) { return 0; } /* file has been changed. */ if (old_mtime != st.st_mtime) { seaf_warning ("File %s is changed. Skip removing the file.\n", path); return -1; } /* first unlink the file. */ if (seaf_util_unlink (path) < 0) { seaf_warning ("Failed to remove %s: %s.\n", path, strerror(errno)); return -1; } } else { if (seaf_remove_empty_dir (path) < 0) { seaf_warning ("Failed to remove dir %s: %s.\n", path, strerror(errno)); return -1; } } /* then remove all empty directories upwards. */ /* offset = base_len + len; */ /* do { */ /* if (path[offset] == '/') { */ /* path[offset] = '\0'; */ /* int ret = seaf_remove_empty_dir (path); */ /* if (ret < 0) { */ /* break; */ /* } */ /* } */ /* } while (--offset > base_len); */ return 0; } #ifdef WIN32 static gboolean check_file_locked (const wchar_t *path_w, gboolean locked_on_server) { HANDLE handle; /* If the file is locked on server, its local access right has been set to * read-only. So trying to test GENERIC_WRITE access will certainly return * ACCESS_DENIED. In this case, we can only test for GENERIC_READ. * MS Office seems to gain exclusive read/write access to the file. So even * trying read access can return a SHARING_VIOLATION error. */ DWORD access_mode = locked_on_server ? GENERIC_READ : GENERIC_WRITE; handle = CreateFileW (path_w, access_mode, 0, NULL, OPEN_EXISTING, 0, NULL); if (handle != INVALID_HANDLE_VALUE) { CloseHandle (handle); } else if (GetLastError() == ERROR_SHARING_VIOLATION) { return TRUE; } return FALSE; } gboolean do_check_file_locked (const char *path, const char *worktree, gboolean locked_on_server) { char *real_path; wchar_t *real_path_w; gboolean ret; real_path = g_build_path(PATH_SEPERATOR, worktree, path, NULL); real_path_w = win32_long_path (real_path); ret = check_file_locked (real_path_w, locked_on_server); g_free (real_path); g_free (real_path_w); return ret; } static gboolean check_dir_locked (const wchar_t *path_w) { HANDLE handle; handle = CreateFileW (path_w, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (handle != INVALID_HANDLE_VALUE) { CloseHandle (handle); } else if (GetLastError() == ERROR_SHARING_VIOLATION) { return TRUE; } return FALSE; } static gboolean check_dir_locked_recursive (const wchar_t *path_w) { WIN32_FIND_DATAW fdata; HANDLE handle; wchar_t *pattern; wchar_t *sub_path_w; char *path; int path_len_w; DWORD error; gboolean ret = FALSE; if (check_dir_locked (path_w)) return TRUE; path = g_utf16_to_utf8 (path_w, -1, NULL, NULL, NULL); path_len_w = wcslen(path_w); pattern = g_new0 (wchar_t, (path_len_w + 3)); wcscpy (pattern, path_w); wcscat (pattern, L"\\*"); handle = FindFirstFileW (pattern, &fdata); if (handle == INVALID_HANDLE_VALUE) { seaf_warning ("FindFirstFile failed %s: %lu.\n", path, GetLastError()); goto out; } do { if (wcscmp (fdata.cFileName, L".") == 0 || wcscmp (fdata.cFileName, L"..") == 0) continue; sub_path_w = g_new0 (wchar_t, path_len_w + wcslen(fdata.cFileName) + 2); wcscpy (sub_path_w, path_w); wcscat (sub_path_w, L"\\"); wcscat (sub_path_w, fdata.cFileName); if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (check_dir_locked_recursive (sub_path_w)) { ret = TRUE; g_free (sub_path_w); goto out; } } else { if (check_file_locked (sub_path_w, FALSE)) { ret = TRUE; g_free (sub_path_w); goto out; } } g_free (sub_path_w); } while (FindNextFileW (handle, &fdata) != 0); error = GetLastError(); if (error != ERROR_NO_MORE_FILES) { seaf_warning ("FindNextFile failed %s: %lu.\n", path, error); } out: FindClose (handle); g_free (path); g_free (pattern); return ret; } gboolean do_check_dir_locked (const char *path, const char *worktree) { char *real_path = g_build_path (PATH_SEPERATOR, worktree, path, NULL); wchar_t *real_path_w = win32_long_path (real_path); gboolean ret = check_dir_locked_recursive (real_path_w); g_free (real_path); g_free (real_path_w); return ret; } gboolean files_locked_on_windows (struct index_state *index, const char *worktree) { gboolean ret = FALSE; int i, entries; struct cache_entry *ce; entries = index->cache_nr; for (i = 0; i < entries; ++i) { ce = index->cache[i]; if (ce_stage(ce)) { int mask = 0; mask |= 1 << (ce_stage(ce) - 1); while (i < entries) { struct cache_entry *nce = index->cache[i]; if (strcmp(ce->name, nce->name)) break; mask |= 1 << (ce_stage(nce) - 1); i++; } i--; /* Check unmerged cases that can potentially update or remove current files in the worktree. */ if (mask == 7 || /* both changed */ mask == 6 || /* both added */ mask == 3) /* others removed */ { if (do_check_file_locked (ce->name, worktree, FALSE)) ret = TRUE; break; } } else if (ce->ce_flags & CE_UPDATE || ce->ce_flags & CE_WT_REMOVE) { if (do_check_file_locked (ce->name, worktree, FALSE)) { ret = TRUE; break; } } } return ret; } #endif /* WIN32 */ void fill_seafile_blocks (const char *repo_id, int version, const unsigned char *sha1, BlockList *bl) { char file_id[41]; Seafile *seafile; int i; rawdata_to_hex (sha1, file_id, 20); seafile = seaf_fs_manager_get_seafile (seaf->fs_mgr, repo_id, version, file_id); if (!seafile) { seaf_warning ("Failed to find file %s.\n", file_id); return; } for (i = 0; i < seafile->n_blocks; ++i) block_list_insert (bl, seafile->blk_sha1s[i]); seafile_unref (seafile); } void collect_new_blocks_from_index (const char *repo_id, int version, struct index_state *index, BlockList *bl) { int i; struct cache_entry *ce; for (i = 0; i < index->cache_nr; ++i) { ce = index->cache[i]; if (ce->ce_flags & CE_UPDATE) fill_seafile_blocks (repo_id, version, ce->sha1, bl); } } seafile-6.1.5/daemon/vc-utils.h000066400000000000000000000046611323477647300163440ustar00rootroot00000000000000#ifndef VC_UTILS_H #define VC_UTILS_H #include #include "index/index.h" #include "index/cache-tree.h" #include "unpack-trees.h" #include "fs-mgr.h" #define PATH_SEPERATOR "/" struct SeafileCrypt; #ifdef WIN32 static inline int readlink(const char *path, char *buf, size_t bufsiz) { errno = ENOSYS; return -1; } #endif int commit_trees_cb (const char *repo_id, int version, const char *modifier, struct cache_tree *it, struct cache_entry **cache, int entries, const char *base, int baselen); int update_index (struct index_state *istate, const char *index_path); int update_worktree (struct unpack_trees_options *o, gboolean recover_merge, const char *conflict_head, const char *default_conflict_suffix, int *finished_entries); int seaf_remove_empty_dir (const char *path); char * build_case_conflict_free_path (const char *worktree, const char *ce_name, GHashTable *conflict_hash, GHashTable *no_conflict_hash, gboolean *is_case_conflict, gboolean is_rename); char * build_checkout_path (const char *worktree, const char *ce_name, int len); int delete_path (const char *worktree, const char *name, unsigned int mode, gint64 old_mtime); struct index_state; int delete_dir_with_check (const char *repo_id, int repo_version, const char *root_id, const char *dir_path, const char *worktree, struct index_state *istate); gboolean do_check_file_locked (const char *path, const char *worktree, gboolean locked_on_server); gboolean do_check_dir_locked (const char *path, const char *worktree); gboolean files_locked_on_windows (struct index_state *index, const char *worktree); int compare_file_content (const char *path, SeafStat *st, const unsigned char *ce_sha1, struct SeafileCrypt *crypt, int repo_version); void fill_seafile_blocks (const char *repo_id, int version, const unsigned char *sha1, BlockList *bl); void collect_new_blocks_from_index (const char *repo_id, int version, struct index_state *index, BlockList *bl); #endif seafile-6.1.5/daemon/wt-monitor-linux.c000066400000000000000000000565751323477647300200600ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include #include #include #include #include "seafile-session.h" #include "utils.h" #include "wt-monitor.h" #define DEBUG_FLAG SEAFILE_DEBUG_WATCH #include "log.h" typedef struct WatchPathMapping { GHashTable *wd_to_path; /* watch descriptor -> path */ } WatchPathMapping; typedef struct RenameInfo { uint32_t last_cookie; char *old_path; gboolean processing; /* Are we processing a rename event? */ } RenameInfo; typedef struct EventInfo { int wd; uint32_t mask; uint32_t cookie; char name[NAME_MAX]; } EventInfo; typedef struct RepoWatchInfo { WTStatus *status; WatchPathMapping *mapping; RenameInfo *rename_info; EventInfo last_event; char *worktree; } RepoWatchInfo; #define WATCH_MASK IN_MODIFY | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO | IN_CLOSE_WRITE | IN_ATTRIB struct SeafWTMonitorPriv { pthread_mutex_t hash_lock; GHashTable *handle_hash; /* repo_id -> inotify_fd */ GHashTable *info_hash; /* inotify_fd -> RepoWatchInfo */ fd_set read_fds; int maxfd; }; static void *wt_monitor_job_linux (void *vmonitor); static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd); static int add_watch_recursive (RepoWatchInfo *info, int in_fd, const char *worktree, const char *path, gboolean add_events); /* WatchPathMapping */ static WatchPathMapping *create_mapping () { WatchPathMapping *mapping; mapping = g_new0 (WatchPathMapping, 1); mapping->wd_to_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); return mapping; } static void free_mapping (WatchPathMapping *mapping) { g_hash_table_destroy (mapping->wd_to_path); g_free (mapping); } static void add_mapping (WatchPathMapping *mapping, const char *path, int wd) { g_hash_table_insert (mapping->wd_to_path, (gpointer)(long)wd, g_strdup(path)); } /* RenameInfo */ static RenameInfo *create_rename_info () { RenameInfo *info = g_new0 (RenameInfo, 1); return info; } static void free_rename_info (RenameInfo *info) { g_free (info->old_path); g_free (info); } inline static void set_rename_processing_state (RenameInfo *info, uint32_t cookie, const char *path) { info->last_cookie = cookie; info->old_path = g_strdup(path); info->processing = TRUE; } inline static void unset_rename_processing_state (RenameInfo *info) { info->last_cookie = 0; g_free (info->old_path); info->old_path = NULL; info->processing = FALSE; } /* RepoWatchInfo */ static RepoWatchInfo * create_repo_watch_info (const char *repo_id, const char *worktree) { WTStatus *status = create_wt_status (repo_id); WatchPathMapping *mapping = create_mapping (); RenameInfo *rename_info = create_rename_info (); RepoWatchInfo *info = g_new0 (RepoWatchInfo, 1); info->status = status; info->mapping = mapping; info->rename_info = rename_info; info->worktree = g_strdup(worktree); return info; } static void free_repo_watch_info (RepoWatchInfo *info) { wt_status_unref (info->status); free_mapping (info->mapping); free_rename_info (info->rename_info); g_free (info->worktree); g_free (info); } static void add_event_to_queue (WTStatus *status, int type, const char *path, const char *new_path) { WTEvent *event = wt_event_new (type, path, new_path); char *name; switch (type) { case WT_EVENT_CREATE_OR_UPDATE: name = "create/update"; break; case WT_EVENT_SCAN_DIR: name = "scan dir"; break; case WT_EVENT_DELETE: name = "delete"; break; case WT_EVENT_RENAME: name = "rename"; break; case WT_EVENT_OVERFLOW: name = "overflow"; break; case WT_EVENT_ATTRIB: name = "attribute change"; break; default: name = "unknown"; } seaf_debug ("Adding event: %s, %s %s\n", name, path, new_path?new_path:""); pthread_mutex_lock (&status->q_lock); g_queue_push_tail (status->event_q, event); pthread_mutex_unlock (&status->q_lock); if (type == WT_EVENT_CREATE_OR_UPDATE) { pthread_mutex_lock (&status->ap_q_lock); char *last = g_queue_peek_tail (status->active_paths); if (!last || strcmp(last, path) != 0) g_queue_push_tail (status->active_paths, g_strdup(path)); pthread_mutex_unlock (&status->ap_q_lock); } } /* * We only recognize two consecutive "moved" events with the same cookie as * a rename pair. The processing logic is: * 1. Receive a MOVED_FROM event, set last_cookie and old_path, set processing to TRUE * 2. If the next event is MOVED_TO, and with the same cookie, then add an * WT_EVENT_RENAME event to the queue. * 3. Otherwise, recognize them as one delete event followed by one * create event * * This is a two-state state machine. The states are 'not processing rename' and * 'processing rename'. */ static void handle_rename (int in_fd, RepoWatchInfo *info, struct inotify_event *event, const char *worktree, const char *filename, gboolean last_event) { WTStatus *status = info->status; RenameInfo *rename_info = info->rename_info; if (event->mask & IN_MOVED_FROM) seaf_debug ("(%d) Move %s ->\n", event->cookie, event->name); else if (event->mask & IN_MOVED_TO) seaf_debug ("(%d) Move -> %s.\n", event->cookie, event->name); if (!rename_info->processing) { if (event->mask & IN_MOVED_FROM) { if (!last_event) { set_rename_processing_state (rename_info, event->cookie, filename); } else { /* Rename event pair should be in one batch of events. * If a MOVED_FROM event is the last event in a batch, * the path should be moved out of the repo. */ add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } } else if (event->mask & IN_MOVED_TO) { /* A file/dir was moved into this repo. */ /* Add watch and produce events. */ add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); add_watch_recursive (info, in_fd, worktree, filename, FALSE); } } else { if (event->mask & IN_MOVED_FROM) { /* A file/dir was moved out of this repo. * Output the last MOVED_FROM event as DELETE event */ add_event_to_queue (status, WT_EVENT_DELETE, rename_info->old_path, NULL); if (!last_event) { /* Stay in processing state. */ rename_info->last_cookie = event->cookie; g_free (rename_info->old_path); rename_info->old_path = g_strdup(filename); } else { /* Another file/dir was moved out of this repo. */ add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); unset_rename_processing_state (rename_info); } } else if (event->mask & IN_MOVED_TO) { if (event->cookie == rename_info->last_cookie) { /* Rename pair detected. */ add_event_to_queue (status, WT_EVENT_RENAME, rename_info->old_path, filename); } else { /* A file/dir was moved out of the repo, followed by * aother file/dir was moved into this repo. */ add_event_to_queue (status, WT_EVENT_DELETE, rename_info->old_path, NULL); add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } /* Need to update wd -> path mapping. */ add_watch_recursive (info, in_fd, worktree, filename, FALSE); unset_rename_processing_state (rename_info); } else { /* A file/dir was moved out of this repo, followed by another * file operations. */ add_event_to_queue (status, WT_EVENT_DELETE, rename_info->old_path, NULL); unset_rename_processing_state (rename_info); } } } inline static gboolean is_modify_close_write (EventInfo *e1, struct inotify_event *e2) { return ((e1->mask & IN_MODIFY) && (e2->mask & IN_CLOSE_WRITE)); } #if 0 static gboolean handle_consecutive_duplicate_event (RepoWatchInfo *info, struct inotify_event *event) { gboolean duplicate; /* Initially last_event is zero so it's not duplicate with any real events. */ duplicate = (info->last_event.wd == event->wd && (info->last_event.mask == event->mask || is_modify_close_write(&info->last_event, event)) && info->last_event.cookie == event->cookie && strcmp (info->last_event.name, event->name) == 0); info->last_event.wd = event->wd; info->last_event.mask = event->mask; info->last_event.cookie = event->cookie; memcpy (info->last_event.name, event->name, event->len); info->last_event.name[event->len] = 0; return duplicate; } #endif static void process_one_event (int in_fd, RepoWatchInfo *info, const char *worktree, const char *parent, struct inotify_event *event, gboolean last_event) { WTStatus *status = info->status; char *filename; gboolean update_last_changed = TRUE; gboolean add_to_queue = TRUE; /* An inotfy watch has been removed, we don't care about this for now. */ if ((event->mask & IN_IGNORED) || (event->mask & IN_UNMOUNT)) return; /* Kernel event queue was overflowed, some events may lost. */ if (event->mask & IN_Q_OVERFLOW) { add_event_to_queue (status, WT_EVENT_OVERFLOW, NULL, NULL); return; } /* if (handle_consecutive_duplicate_event (info, event)) */ /* add_to_queue = FALSE; */ filename = g_build_filename (parent, event->name, NULL); handle_rename (in_fd, info, event, worktree, filename, last_event); if (event->mask & IN_MODIFY) { seaf_debug ("Modified %s.\n", filename); if (add_to_queue) add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->mask & IN_CREATE) { seaf_debug ("Created %s.\n", filename); /* Nautilus's file copy operation doesn't trigger write events. * If the user copy a large file into the repo, only a create * event and a close_write event will be received. If we process * the create event, we'll certainly try to index a file when it's * still being copied. So we'll ignore create event for files. * Since write and close_write events will always be triggered, * we don't need to worry about missing this file. */ char *fullpath = g_build_filename (worktree, filename, NULL); struct stat st; if (lstat (fullpath, &st) < 0 || (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))) { g_free (fullpath); update_last_changed = FALSE; goto out; } g_free (fullpath); /* We now know it's a directory or a symlink. */ /* Files or dirs could have been added under this dir before we * watch it. So it's safer to scan this dir. At most time we don't * have to scan recursively and very few new files will be found. */ add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); add_watch_recursive (info, in_fd, worktree, filename, FALSE); } else if (event->mask & IN_DELETE) { seaf_debug ("Deleted %s.\n", filename); add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } else if (event->mask & IN_CLOSE_WRITE) { seaf_debug ("Close write %s.\n", filename); if (add_to_queue) add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->mask & IN_ATTRIB) { seaf_debug ("Attribute changed %s.\n", filename); add_event_to_queue (status, WT_EVENT_ATTRIB, filename, NULL); } out: g_free (filename); if (update_last_changed) g_atomic_int_set (&info->status->last_changed, (gint)time(NULL)); } static gboolean process_events (SeafWTMonitorPriv *priv, const char *repo_id, int in_fd) { char *event_buf = NULL; unsigned int buf_size; struct inotify_event *event; RepoWatchInfo *info; int rc, n; char *dir; gboolean ret = FALSE; rc = ioctl (in_fd, FIONREAD, &buf_size); if (rc < 0) { seaf_warning ("Cannot get inotify event buf size: %s.\n", strerror(errno)); return FALSE; } event_buf = g_new (char, buf_size); n = readn (in_fd, event_buf, buf_size); if (n < 0) { seaf_warning ("Failed to read inotify fd: %s.\n", strerror(errno)); goto out; } else if (n != buf_size) { seaf_warning ("Read incomplete inotify event struct.\n"); goto out; } info = g_hash_table_lookup (priv->info_hash, (gpointer)(long)in_fd); if (!info) { seaf_warning ("Repo watch info not found.\n"); goto out; } int offset = 0; while (offset < buf_size) { event = (struct inotify_event *)&event_buf[offset]; offset += sizeof(struct inotify_event) + event->len; dir = g_hash_table_lookup (info->mapping->wd_to_path, (gpointer)(long)event->wd); if (!dir) { seaf_warning ("Cannot find path from wd.\n"); goto out; } process_one_event (in_fd, info, info->worktree, dir, event, (offset >= buf_size)); } ret = TRUE; out: g_free (event_buf); return ret; } static void * wt_monitor_job_linux (void *vmonitor) { SeafWTMonitor *monitor = vmonitor; SeafWTMonitorPriv *priv = monitor->priv; WatchCommand cmd; int n; int rc; fd_set fds; int inotify_fd; char *repo_id; gpointer key, value; GHashTableIter iter; FD_SET (monitor->cmd_pipe[0], &priv->read_fds); priv->maxfd = monitor->cmd_pipe[0]; while (1) { fds = priv->read_fds; rc = select (priv->maxfd + 1, &fds, NULL, NULL, NULL); if (rc < 0 && errno == EINTR) { continue; } else if (rc < 0) { seaf_warning ("[wt mon] select error: %s.\n", strerror(errno)); break; } if (FD_ISSET (monitor->cmd_pipe[0], &fds)) { n = pipereadn (monitor->cmd_pipe[0], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] failed to read command.\n"); continue; } handle_watch_command (monitor, &cmd); } g_hash_table_iter_init (&iter, priv->handle_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { repo_id = key; inotify_fd = (int)(long)value; if (FD_ISSET (inotify_fd, &fds)) process_events (priv, repo_id, inotify_fd); } } return NULL; } /* Ignore errors so that we can still monitor other dirs * when one dir is bad. * * If @add_events is TRUE, add events for each dir and entries under that dir. * Note that only adding events for files is not enough, because repo-mgr will * need to add empty dirs to index. */ static int add_watch_recursive (RepoWatchInfo *info, int in_fd, const char *worktree, const char *path, gboolean add_events) { char *full_path; SeafStat st; DIR *dir; struct dirent *dent; int wd; full_path = g_build_filename (worktree, path, NULL); if (stat (full_path, &st) < 0) { seaf_warning ("[wt mon] fail to stat %s: %s\n", full_path, strerror(errno)); goto out; } if (add_events && path[0] != 0) add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE, path, NULL); if (S_ISDIR (st.st_mode)) { seaf_debug ("Watching %s.\n", full_path); wd = inotify_add_watch (in_fd, full_path, (uint32_t)WATCH_MASK); if (wd < 0) { seaf_warning ("[wt mon] fail to add watch to %s: %s.\n", full_path, strerror(errno)); goto out; } add_mapping (info->mapping, path, wd); dir = opendir (full_path); if (!dir) { seaf_warning ("[wt mon] fail to open dir %s: %s.\n", full_path, strerror(errno)); goto out; } while (1) { dent = readdir (dir); if (!dent) break; if (strcmp (dent->d_name, ".") == 0 || strcmp (dent->d_name, "..") == 0) continue; char *sub_path = g_build_filename (path, dent->d_name, NULL); /* Check d_type to avoid stating every files under this dir. * Note that d_type may not be supported in some file systems, * in this case DT_UNKNOWN is returned. */ if (dent->d_type == DT_DIR || dent->d_type == DT_LNK || dent->d_type == DT_UNKNOWN) add_watch_recursive (info, in_fd, worktree, sub_path, add_events); if (dent->d_type == DT_REG && add_events) add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE, sub_path, NULL); g_free (sub_path); } closedir (dir); } out: g_free (full_path); return 0; } static int add_watch (SeafWTMonitorPriv *priv, const char *repo_id, const char *worktree) { int inotify_fd; RepoWatchInfo *info; inotify_fd = inotify_init (); if (inotify_fd < 0) { seaf_warning ("[wt mon] inotify_init failed: %s.\n", strerror(errno)); return -1; } pthread_mutex_lock (&priv->hash_lock); g_hash_table_insert (priv->handle_hash, g_strdup(repo_id), (gpointer)(long)inotify_fd); info = create_repo_watch_info (repo_id, worktree); g_hash_table_insert (priv->info_hash, (gpointer)(long)inotify_fd, info); pthread_mutex_unlock (&priv->hash_lock); if (add_watch_recursive (info, inotify_fd, worktree, "", FALSE) < 0) { close (inotify_fd); pthread_mutex_lock (&priv->hash_lock); g_hash_table_remove (priv->handle_hash, repo_id); g_hash_table_remove (priv->info_hash, (gpointer)(long)inotify_fd); pthread_mutex_unlock (&priv->hash_lock); return -1; } /* A special event indicates repo-mgr to scan the whole worktree. */ add_event_to_queue (info->status, WT_EVENT_SCAN_DIR, "", NULL); return inotify_fd; } static int handle_add_repo (SeafWTMonitorPriv *priv, const char *repo_id, const char *worktree) { int inotify_fd; inotify_fd = add_watch (priv, repo_id, worktree); if (inotify_fd < 0) { return -1; } FD_SET (inotify_fd, &priv->read_fds); priv->maxfd = MAX (inotify_fd, priv->maxfd); return 0; } static void update_maxfd (SeafWTMonitor *monitor) { SeafWTMonitorPriv *priv = monitor->priv; GHashTableIter iter; gpointer key, value; int fd, maxfd = monitor->cmd_pipe[0]; g_hash_table_iter_init (&iter, priv->info_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { fd = (int) (long)key; if (fd > maxfd) maxfd = fd; } priv->maxfd = maxfd; } static int handle_rm_repo (SeafWTMonitor *monitor, const char *repo_id, gpointer handle) { SeafWTMonitorPriv *priv = monitor->priv; int inotify_fd = (int)(long)handle; close (inotify_fd); FD_CLR (inotify_fd, &priv->read_fds); update_maxfd (monitor); pthread_mutex_lock (&priv->hash_lock); g_hash_table_remove (priv->handle_hash, repo_id); g_hash_table_remove (priv->info_hash, (gpointer)(long)inotify_fd); pthread_mutex_unlock (&priv->hash_lock); return 0; } static int handle_refresh_repo (SeafWTMonitorPriv *priv, const char *repo_id) { return 0; } static void reply_watch_command (SeafWTMonitor *monitor, int result) { int n; n = pipewriten (monitor->res_pipe[1], &result, sizeof(int)); if (n != sizeof(int)) seaf_warning ("[wt mon] fail to write command result.\n"); } static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd) { SeafWTMonitorPriv *priv = monitor->priv; if (cmd->type == CMD_ADD_WATCH) { if (g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, NULL, NULL)) { reply_watch_command (monitor, 0); return; } if (handle_add_repo(priv, cmd->repo_id, cmd->worktree) < 0) { seaf_warning ("[wt mon] failed to watch worktree of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } seaf_debug ("[wt mon] add watch for repo %s\n", cmd->repo_id); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_DELETE_WATCH) { gpointer key, value; if (!g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, &key, &value)) { reply_watch_command (monitor, 0); return; } handle_rm_repo (monitor, cmd->repo_id, value); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_REFRESH_WATCH) { if (handle_refresh_repo (priv, cmd->repo_id) < 0) { seaf_warning ("[wt mon] failed to refresh watch of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } reply_watch_command (monitor, 0); } } /* Public interface functions. */ SeafWTMonitor * seaf_wt_monitor_new (SeafileSession *seaf) { SeafWTMonitor *monitor = g_new0 (SeafWTMonitor, 1); SeafWTMonitorPriv *priv = g_new0 (SeafWTMonitorPriv, 1); pthread_mutex_init (&priv->hash_lock, NULL); priv->handle_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->info_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)free_repo_watch_info); monitor->priv = priv; monitor->seaf = seaf; monitor->job_func = wt_monitor_job_linux; return monitor; } WTStatus * seaf_wt_monitor_get_worktree_status (SeafWTMonitor *monitor, const char *repo_id) { SeafWTMonitorPriv *priv = monitor->priv; gpointer key, value; RepoWatchInfo *info; pthread_mutex_lock (&priv->hash_lock); if (!g_hash_table_lookup_extended (priv->handle_hash, repo_id, &key, &value)) { pthread_mutex_unlock (&priv->hash_lock); return NULL; } info = g_hash_table_lookup(priv->info_hash, value); wt_status_ref (info->status); pthread_mutex_unlock (&priv->hash_lock); return info->status; } seafile-6.1.5/daemon/wt-monitor-macos.c000066400000000000000000000371751323477647300200160ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include #include #include #include #include #include #include #include "seafile-session.h" #include "utils.h" #include "wt-monitor.h" #define DEBUG_FLAG SEAFILE_DEBUG_WATCH #include "log.h" typedef struct RepoWatchInfo { WTStatus *status; char *worktree; } RepoWatchInfo; struct SeafWTMonitorPriv { pthread_mutex_t hash_lock; GHashTable *handle_hash; /* repo_id -> inotify_fd (or handle) */ GHashTable *info_hash; /* inotify_fd(or handle in deeed) -> RepoWatchInfo */ }; static void add_event_to_queue (WTStatus *status, int type, const char *path, const char *new_path); static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd); /* RepoWatchInfo */ static RepoWatchInfo * create_repo_watch_info (const char *repo_id, const char *worktree) { WTStatus *status = create_wt_status (repo_id); RepoWatchInfo *info = g_new0 (RepoWatchInfo, 1); info->status = status; info->worktree = g_strdup(worktree); return info; } static void free_repo_watch_info (RepoWatchInfo *info) { wt_status_unref (info->status); g_free (info->worktree); g_free (info); } static void add_event_to_queue (WTStatus *status, int type, const char *path, const char *new_path) { char *nfc_path = NULL, *nfc_new_path = NULL; if (path) nfc_path = g_utf8_normalize (path, -1, G_NORMALIZE_NFC); if (new_path) nfc_new_path = g_utf8_normalize (new_path, -1, G_NORMALIZE_NFC); WTEvent *event = wt_event_new (type, nfc_path, nfc_new_path); g_free (nfc_path); g_free (nfc_new_path); char *name; switch (type) { case WT_EVENT_CREATE_OR_UPDATE: name = "create/update"; break; case WT_EVENT_SCAN_DIR: name = "scan dir"; break; case WT_EVENT_DELETE: name = "delete"; break; case WT_EVENT_RENAME: name = "rename"; break; case WT_EVENT_OVERFLOW: name = "overflow"; break; case WT_EVENT_ATTRIB: name = "attribute change"; break; default: name = "unknown"; } seaf_debug ("Adding event: %s, %s %s\n", name, path, new_path?new_path:""); pthread_mutex_lock (&status->q_lock); g_queue_push_tail (status->event_q, event); pthread_mutex_unlock (&status->q_lock); if (type == WT_EVENT_CREATE_OR_UPDATE) { pthread_mutex_lock (&status->ap_q_lock); char *last = g_queue_peek_tail (status->active_paths); if (!last || strcmp(last, path) != 0) g_queue_push_tail (status->active_paths, g_strdup(path)); pthread_mutex_unlock (&status->ap_q_lock); } } #if 0 static void process_one_event (const char* eventPath, RepoWatchInfo *info, const char *worktree, const FSEventStreamEventId eventId, const FSEventStreamEventFlags eventFlags) { WTStatus *status = info->status; char *filename; char *event_path_nfc; const char *tmp; event_path_nfc = g_utf8_normalize (eventPath, -1, G_NORMALIZE_NFC); tmp = event_path_nfc + strlen(worktree); if (*tmp == '/') tmp++; filename = g_strdup(tmp); g_free (event_path_nfc); /* Path for folder returned from system may contain a '/' at the end. */ int len = strlen(filename); if (len > 0 && filename[len - 1] == '/') filename[len - 1] = 0; /* Reinterpreted RENAMED as combine of CREATED or DELETED event */ if (eventFlags & kFSEventStreamEventFlagItemRenamed) { seaf_debug ("Rename Event Affected: %s \n", filename); struct stat buf; if (stat (eventPath, &buf)) { /* ret = -1, file is gone */ add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } else { /* ret = 0, file is here, but rename behaviour is unknown to us */ add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } } else if (eventFlags & kFSEventStreamEventFlagItemModified) { seaf_debug ("Modified %s.\n", filename); add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (eventFlags & kFSEventStreamEventFlagItemCreated) { seaf_debug ("Created %s.\n", filename); /** * no need to rechecking recursively in FSEventStream * * these flags are useful if necessary: * kFSEventStreamEventFlagItemIsFile * kFSEventStreamEventFlagItemIsDir * kFSEventStreamEventFlagItemIsSymlink */ add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (eventFlags & kFSEventStreamEventFlagItemRemoved) { seaf_debug ("Deleted %s.\n", filename); add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } else if (eventFlags & kFSEventStreamEventFlagItemXattrMod) { seaf_debug ("XattrMod %s.\n", filename); add_event_to_queue (status, WT_EVENT_ATTRIB, filename, NULL); } else if (eventFlags & kFSEventStreamEventFlagRootChanged) { /* An empty path indicates repo-mgr to scan the whole worktree. */ seaf_debug ("RootChange event.\n"); add_event_to_queue (info->status, WT_EVENT_CREATE_OR_UPDATE, "", NULL); } else { seaf_debug ("Unhandled event with flags %x.\n", eventFlags); } g_free (filename); g_atomic_int_set (&info->status->last_changed, (gint)time(NULL)); } #endif static void process_one_event (const char* eventPath, RepoWatchInfo *info, const char *worktree, const FSEventStreamEventId eventId, const FSEventStreamEventFlags eventFlags) { WTStatus *status = info->status; char *dirname; char *event_path_nfc; const char *tmp; event_path_nfc = g_utf8_normalize (eventPath, -1, G_NORMALIZE_NFC); tmp = event_path_nfc + strlen(worktree); if (*tmp == '/') tmp++; dirname = g_strdup(tmp); g_free (event_path_nfc); /* Path for folder returned from system may contain a '/' at the end. */ int len = strlen(dirname); if (len > 0 && dirname[len - 1] == '/') dirname[len - 1] = 0; if (eventFlags & kFSEventStreamEventFlagItemRenamed) { seaf_debug ("Rename event in dir: %s \n", dirname); } else if (eventFlags & kFSEventStreamEventFlagItemModified) { seaf_debug ("Modified event in dir %s.\n", dirname); } else if (eventFlags & kFSEventStreamEventFlagItemCreated) { seaf_debug ("Created event in dir %s.\n", dirname); } else if (eventFlags & kFSEventStreamEventFlagItemRemoved) { seaf_debug ("Deleted event in dir %s.\n", dirname); } else if (eventFlags & kFSEventStreamEventFlagItemXattrMod) { seaf_debug ("XattrMod event in dir %s.\n", dirname); } else { seaf_debug ("Unhandled event with flags %x.\n", eventFlags); } add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, dirname, NULL); g_free (dirname); g_atomic_int_set (&info->status->last_changed, (gint)time(NULL)); } static void stream_callback (ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { RepoWatchInfo *info; SeafWTMonitor *monitor = (SeafWTMonitor *)clientCallBackInfo; SeafWTMonitorPriv *priv = monitor->priv; char **paths = (char **)eventPaths; info = g_hash_table_lookup (priv->info_hash, (gpointer)(long)streamRef); if (!info) { seaf_warning ("Repo watch info not found.\n"); return; } int i; for (i = 0; i < numEvents; i++) { seaf_debug("%ld Change %llu in %s, flags %x\n", (long)CFRunLoopGetCurrent(), eventIds[i], paths[i], eventFlags[i]); process_one_event (paths[i], info, info->worktree, eventIds[i], eventFlags[i]); } } static FSEventStreamRef add_watch (SeafWTMonitor *monitor, const char* repo_id, const char* worktree) { SeafWTMonitorPriv *priv = monitor->priv; RepoWatchInfo *info; double latency = 0.25; /* unit: second */ char *worktree_nfd = g_utf8_normalize (worktree, -1, G_NORMALIZE_NFD); CFStringRef mypaths[1]; mypaths[0] = CFStringCreateWithCString (kCFAllocatorDefault, worktree_nfd, kCFStringEncodingUTF8); g_free (worktree_nfd); CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)mypaths, 1, NULL); FSEventStreamRef stream; /* Create the stream, passing in a callback */ seaf_debug("Use kFSEventStreamCreateFlagWatchRoot\n"); // kFSEventStreamCreateFlagFileEvents does not work for libraries with name // containing accent characters. struct FSEventStreamContext ctx = {0, monitor, NULL, NULL, NULL}; stream = FSEventStreamCreate(kCFAllocatorDefault, stream_callback, &ctx, pathsToWatch, kFSEventStreamEventIdSinceNow, latency, 0 ); CFRelease (mypaths[0]); CFRelease (pathsToWatch); if (!stream) { seaf_warning ("[wt] Failed to create event stream.\n"); return stream; } FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); FSEventStreamStart (stream); /* FSEventStreamShow (stream); */ seaf_debug ("[wt mon] Add repo %s watch success: %s.\n", repo_id, worktree); pthread_mutex_lock (&priv->hash_lock); g_hash_table_insert (priv->handle_hash, g_strdup(repo_id), (gpointer)(long)stream); info = create_repo_watch_info (repo_id, worktree); g_hash_table_insert (priv->info_hash, (gpointer)(long)stream, info); pthread_mutex_unlock (&priv->hash_lock); /* A special event indicates repo-mgr to scan the whole worktree. */ add_event_to_queue (info->status, WT_EVENT_SCAN_DIR, "", NULL); return stream; } static void command_read_cb (CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) { SeafWTMonitor *monitor = (SeafWTMonitor *)info; WatchCommand cmd; int n; n = pipereadn (monitor->cmd_pipe[0], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] failed to read command.\n"); CFFileDescriptorEnableCallBacks (fdref, kCFFileDescriptorReadCallBack); return; } seaf_debug ("[wt mon] %ld receive command type=%d, repo=%s\n", (long)CFRunLoopGetCurrent(), cmd.type, cmd.repo_id); handle_watch_command (monitor, &cmd); CFFileDescriptorEnableCallBacks (fdref, kCFFileDescriptorReadCallBack); } static int add_command_pipe (SeafWTMonitor *monitor) { CFFileDescriptorContext ctx = {0, monitor, NULL, NULL, NULL}; CFFileDescriptorRef fdref = CFFileDescriptorCreate(NULL, monitor->cmd_pipe[0], true, command_read_cb, &ctx); if (fdref == NULL) { return -1; } CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack); CFRunLoopSourceRef source = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0); CFRunLoopAddSource (CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); CFRelease(source); return 0; } static void * wt_monitor_job_darwin (void *vmonitor) { SeafWTMonitor *monitor = (SeafWTMonitor *)vmonitor; add_command_pipe (monitor); while (1) { CFRunLoopRun(); } return NULL; } static int handle_add_repo (SeafWTMonitor *monitor, const char *repo_id, const char *worktree) { FSEventStreamRef stream = add_watch (monitor, repo_id, worktree); if (!stream) return -1; return 0; } static int handle_rm_repo (SeafWTMonitor *monitor, const char *repo_id, gpointer handle) { SeafWTMonitorPriv *priv = monitor->priv; FSEventStreamRef stream = (FSEventStreamRef)handle; FSEventStreamStop (stream); FSEventStreamInvalidate (stream); FSEventStreamRelease (stream); pthread_mutex_lock (&priv->hash_lock); g_hash_table_remove (priv->handle_hash, repo_id); g_hash_table_remove (priv->info_hash, (gpointer)(long)stream); pthread_mutex_unlock (&priv->hash_lock); return 0; } static int handle_refresh_repo (SeafWTMonitor *monitor, const char *repo_id) { return 0; } static void reply_watch_command (SeafWTMonitor *monitor, int result) { int n; n = pipewriten (monitor->res_pipe[1], &result, sizeof(int)); if (n != sizeof(int)) seaf_warning ("[wt mon] fail to write command result.\n"); } static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd) { SeafWTMonitorPriv *priv = monitor->priv; if (cmd->type == CMD_ADD_WATCH) { if (g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, NULL, NULL)) { reply_watch_command (monitor, 0); return; } if (handle_add_repo(monitor, cmd->repo_id, cmd->worktree) < 0) { seaf_warning ("[wt mon] failed to watch worktree of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } seaf_debug ("[wt mon] add watch for repo %s\n", cmd->repo_id); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_DELETE_WATCH) { gpointer key, value; if (!g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, &key, &value)) { reply_watch_command (monitor, 0); return; } handle_rm_repo (monitor, cmd->repo_id, value); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_REFRESH_WATCH) { if (handle_refresh_repo (monitor, cmd->repo_id) < 0) { seaf_warning ("[wt mon] failed to refresh watch of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } reply_watch_command (monitor, 0); } } SeafWTMonitor * seaf_wt_monitor_new (SeafileSession *seaf) { SeafWTMonitor *monitor = g_new0 (SeafWTMonitor, 1); SeafWTMonitorPriv *priv = g_new0 (SeafWTMonitorPriv, 1); pthread_mutex_init (&priv->hash_lock, NULL); priv->handle_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->info_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)free_repo_watch_info); monitor->priv = priv; monitor->seaf = seaf; monitor->job_func = wt_monitor_job_darwin; return monitor; } WTStatus * seaf_wt_monitor_get_worktree_status (SeafWTMonitor *monitor, const char *repo_id) { SeafWTMonitorPriv *priv = monitor->priv; gpointer key, value; RepoWatchInfo *info; pthread_mutex_lock (&priv->hash_lock); if (!g_hash_table_lookup_extended (priv->handle_hash, repo_id, &key, &value)) { pthread_mutex_unlock (&priv->hash_lock); return NULL; } info = g_hash_table_lookup(priv->info_hash, value); wt_status_ref (info->status); pthread_mutex_unlock (&priv->hash_lock); return info->status; } seafile-6.1.5/daemon/wt-monitor-structs.c000066400000000000000000000033531323477647300204120ustar00rootroot00000000000000#include #include "wt-monitor-structs.h" /* WTEvent */ WTEvent *wt_event_new (int type, const char *path, const char *new_path) { WTEvent *event = g_new0 (WTEvent, 1); event->ev_type = type; if (path) event->path = g_strdup (path); if (new_path) event->new_path = g_strdup(new_path); return event; } static void free_path (gpointer data, gpointer user_data) { g_free (data); } void wt_event_free (WTEvent *event) { g_free (event->path); g_free (event->new_path); if (event->remain_files) { g_queue_foreach (event->remain_files, free_path, NULL); g_queue_free (event->remain_files); } g_free (event); } /* WTStatus */ WTStatus *create_wt_status (const char *repo_id) { WTStatus *status = g_new0 (WTStatus, 1); memcpy (status->repo_id, repo_id, 36); status->event_q = g_queue_new (); pthread_mutex_init (&status->q_lock, NULL); status->active_paths = g_queue_new (); pthread_mutex_init (&status->ap_q_lock, NULL); /* The monitor thread always holds a reference to this status * until it's unwatched */ status->ref_count = 1; return status; } static void free_event_cb (gpointer data, gpointer user_data) { WTEvent *event = data; wt_event_free (event); } static void free_wt_status (WTStatus *status) { if (status->event_q) { g_queue_foreach (status->event_q, free_event_cb, NULL); g_queue_free (status->event_q); } pthread_mutex_destroy (&status->q_lock); g_free (status); } void wt_status_ref (WTStatus *status) { ++(status->ref_count); } void wt_status_unref (WTStatus *status) { if (!status) return; if (--(status->ref_count) <= 0) free_wt_status (status); } seafile-6.1.5/daemon/wt-monitor-structs.h000066400000000000000000000031411323477647300204120ustar00rootroot00000000000000#ifndef WT_MONITOR_STRUCTS_H #define WT_MONITOR_STRUCTS_H #include #include enum { WT_EVENT_CREATE_OR_UPDATE = 0, WT_EVENT_DELETE, WT_EVENT_RENAME, WT_EVENT_ATTRIB, WT_EVENT_OVERFLOW, WT_EVENT_SCAN_DIR, }; typedef struct WTEvent { int ev_type; char *path; char *new_path; /* only used by rename event */ /* For CREATE_OR_UPDATE events, if a partial commit was created when * adding files recursively, the remaining files will be cached in * this queue so that we don't have to rescan the dir from beginning. */ GQueue *remain_files; } WTEvent; WTEvent *wt_event_new (int type, const char *path, const char *new_path); void wt_event_free (WTEvent *event); typedef struct WTStatus { int ref_count; char repo_id[37]; gint last_check; gint last_changed; /* If partial_commit is TRUE, the last commit is partial. * We need to produce another commit from the remaining events. */ gboolean partial_commit; pthread_mutex_t q_lock; GQueue *event_q; /* Paths that're updated. They corresponds to CREATE_OR_UPDATE events. * Use a separate queue since we need to process them simultaneously with * the event queue. And this queue is usually shorter and consumed faster, * because we don't need to process them in multiple batches. */ pthread_mutex_t ap_q_lock; GQueue *active_paths; } WTStatus; WTStatus *create_wt_status (const char *repo_id); void wt_status_ref (WTStatus *status); void wt_status_unref (WTStatus *status); #endif seafile-6.1.5/daemon/wt-monitor-win32.c000066400000000000000000000603331323477647300176460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #include #include #include #include #include #include "seafile-session.h" #include "utils.h" #include "wt-monitor.h" #define DEBUG_FLAG SEAFILE_DEBUG_WATCH #include "log.h" #define DIR_WATCH_MASK \ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE \ | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE /* Use large buffer to prevent events overflow. */ #define DIR_WATCH_BUFSIZE 1 << 20 /* 1MB */ /* Hold the OVERLAPPED struct for asynchronous ReadDirectoryChangesW(), and the buf to receive dir change info. */ typedef struct DirWatchAux { OVERLAPPED ol; char buf[DIR_WATCH_BUFSIZE]; gboolean unused; } DirWatchAux; typedef struct RenameInfo { char *old_path; gboolean processing; /* Are we processing a rename event? */ } RenameInfo; typedef struct EventInfo { DWORD action; DWORD name_len; char name[SEAF_PATH_MAX]; } EventInfo; typedef struct RepoWatchInfo { WTStatus *status; RenameInfo *rename_info; EventInfo last_event; char *worktree; } RepoWatchInfo; struct SeafWTMonitorPriv { pthread_mutex_t hash_lock; GHashTable *handle_hash; /* repo_id -> dir handle */ GHashTable *info_hash; /* handle -> RepoWatchInfo */ GHashTable *buf_hash; /* handle -> aux buf */ HANDLE iocp_handle; int cmd_bytes_read; WatchCommand cmd; }; static void *wt_monitor_job_win32 (void *vmonitor); static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd); /* RenameInfo */ static RenameInfo *create_rename_info () { RenameInfo *info = g_new0 (RenameInfo, 1); return info; } static void free_rename_info (RenameInfo *info) { g_free (info->old_path); g_free (info); } inline static void set_rename_processing_state (RenameInfo *info, const char *path) { info->old_path = g_strdup(path); info->processing = TRUE; } inline static void unset_rename_processing_state (RenameInfo *info) { g_free (info->old_path); info->old_path = NULL; info->processing = FALSE; } /* RepoWatchInfo */ static RepoWatchInfo * create_repo_watch_info (const char *repo_id, const char *worktree) { WTStatus *status = create_wt_status (repo_id); RenameInfo *rename_info = create_rename_info (); RepoWatchInfo *info = g_new0 (RepoWatchInfo, 1); info->status = status; info->rename_info = rename_info; info->worktree = g_strdup(worktree); return info; } static void free_repo_watch_info (RepoWatchInfo *info) { wt_status_unref (info->status); free_rename_info (info->rename_info); g_free (info->worktree); g_free (info); } static inline void init_overlapped(OVERLAPPED *ol) { ol->Offset = ol->OffsetHigh = 0; } static inline void reset_overlapped(OVERLAPPED *ol) { ol->Offset = ol->OffsetHigh = 0; } static void add_event_to_queue (WTStatus *status, int type, const char *path, const char *new_path) { WTEvent *event = wt_event_new (type, path, new_path); char *name; switch (type) { case WT_EVENT_CREATE_OR_UPDATE: name = "create/update"; break; case WT_EVENT_SCAN_DIR: name = "scan dir"; break; case WT_EVENT_DELETE: name = "delete"; break; case WT_EVENT_RENAME: name = "rename"; break; case WT_EVENT_OVERFLOW: name = "overflow"; break; default: name = "unknown"; } seaf_debug ("Adding event: %s, %s %s\n", name, path, new_path?new_path:""); pthread_mutex_lock (&status->q_lock); g_queue_push_tail (status->event_q, event); pthread_mutex_unlock (&status->q_lock); if (type == WT_EVENT_CREATE_OR_UPDATE) { pthread_mutex_lock (&status->ap_q_lock); char *last = g_queue_peek_tail (status->active_paths); if (!last || strcmp(last, path) != 0) g_queue_push_tail (status->active_paths, g_strdup(path)); pthread_mutex_unlock (&status->ap_q_lock); } } /* Every time after a read event is processed, we should call * ReadDirectoryChangesW() on the dir handle asynchronously for the IOCP to * detect the change of the workthree. */ static BOOL start_watch_dir_change(SeafWTMonitorPriv *priv, HANDLE dir_handle) { if (!dir_handle) return FALSE; BOOL first_alloc = FALSE; DirWatchAux *aux = g_hash_table_lookup (priv->buf_hash, dir_handle); /* allocate aux buffer at the first watch, it would be freed if the repo is removed */ if (!aux) { first_alloc = TRUE; aux = g_new0(DirWatchAux, 1); init_overlapped(&aux->ol); } /* The ending W of this function indicates that the info recevied about the change would be in Unicode(specifically, the name of the file that is changed would be encoded in wide char). */ BOOL ret; DWORD code; RepoWatchInfo *info; retry: ret = ReadDirectoryChangesW (dir_handle, /* dir handle */ aux->buf, /* buf to hold change info */ DIR_WATCH_BUFSIZE, /* buf size */ TRUE, /* watch subtree */ DIR_WATCH_MASK, /* notify filter */ NULL, /* bytes returned */ &aux->ol, /* pointer to overlapped */ NULL); /* completion routine */ if (!ret) { code = GetLastError(); seaf_warning("Failed to ReadDirectoryChangesW, " "error code %lu", code); if (first_alloc) /* if failed at the first watch, free the aux buffer */ g_free(aux); else if (code == ERROR_NOTIFY_ENUM_DIR) { /* If buffer overflowed after the last call, * add an overflow event and retry watch. */ info = g_hash_table_lookup (priv->info_hash, dir_handle); add_event_to_queue (info->status, WT_EVENT_OVERFLOW, NULL, NULL); goto retry; } } else { if (first_alloc) /* insert the aux buffer into hash table at the first watch */ g_hash_table_insert (priv->buf_hash, (gpointer)dir_handle, (gpointer)aux); } return ret; } /* Every time after a read event is processed, we should call ReadFile() on * the pipe handle asynchronously for the IOCP to detect when it's readable. */ static BOOL start_watch_cmd_pipe (SeafWTMonitor *monitor, OVERLAPPED *ol_in) { SeafWTMonitorPriv *priv = monitor->priv; OVERLAPPED *ol = ol_in; if (!ol) { ol = g_new0(OVERLAPPED, 1); init_overlapped(ol); } HANDLE hPipe = (HANDLE)monitor->cmd_pipe[0]; void *p = (void *)(&priv->cmd) + priv->cmd_bytes_read; int to_read = sizeof(WatchCommand) - priv->cmd_bytes_read; BOOL sts = ReadFile (hPipe, /* file handle */ p, /* buffer */ to_read, /* bytes to read */ NULL, /* bytes read */ ol); /* overlapped */ if (!sts && (GetLastError() != ERROR_IO_PENDING)) { seaf_warning ("failed to ReadFile, error code %lu\n", GetLastError()); if (!ol_in) /* free the overlapped struct if failed at the first watch */ g_free(ol); return FALSE; } return TRUE; } /* Add a specific HANDLE to an I/O Completion Port. If it's the cmd pipe * handle, call ReadFile() on it; If it's a dir handle, call * ReadDirectoryChangesW() on it. */ static BOOL add_handle_to_iocp (SeafWTMonitor *monitor, HANDLE hAdd) { SeafWTMonitorPriv *priv = monitor->priv; if (!priv || !hAdd) return FALSE; /* CreateIoCompletionPort() will add the handle to an I/O Completion Port if the iocp handle is not NULL. Otherwise it will create a new IOCP handle. The `key' parameter is used by th IOCP to tell us which handle watched by the I/O Completion Port triggeed a return of the GetQueuedCompletionStatus() function. Here we use the value of the handle itself as the key for this handle in the I/O Completion Port. */ priv->iocp_handle = CreateIoCompletionPort (hAdd, /* handle to add */ priv->iocp_handle, /* iocp handle */ (ULONG_PTR)hAdd, /* key for this handle */ 1); /* Num of concurrent threads */ if (!priv->iocp_handle) { seaf_warning ("failed to create/add iocp, error code %lu", GetLastError()); return FALSE; } if (hAdd == (HANDLE)monitor->cmd_pipe[0]) { /* HANDLE is cmd_pipe */ return start_watch_cmd_pipe (monitor, NULL); } else { /* HANDLE is a dir handle */ return start_watch_dir_change (priv, hAdd); } } /* Add the pipe handle and all repo wt handles to IO Completion Port. */ static BOOL add_all_to_iocp (SeafWTMonitor *monitor) { SeafWTMonitorPriv *priv = monitor->priv; if (!add_handle_to_iocp(monitor, (HANDLE)monitor->cmd_pipe[0])) { seaf_warning("Failed to add cmd_pipe to iocp, " "error code %lu", GetLastError()); return FALSE; } GHashTableIter iter; gpointer value = NULL; gpointer key = NULL; g_hash_table_iter_init (&iter, priv->handle_hash); while (g_hash_table_iter_next (&iter, &key, &value)) { if (!add_handle_to_iocp(monitor, (HANDLE)value)) { seaf_warning("Failed to add dir handle to iocp, " "repo %s, error code %lu", (char *)key, GetLastError()); continue; } } seaf_debug("Done: add_all_to_iocp\n"); return TRUE; } /* * On Windows, RENAMED_OLD_NAME and RENAMED_NEW_NAME always comes in pairs. * If a file or dir is moved in/out of the worktree, ADDED or REMOVED event * will be emitted by the kernel. * * This is a two-state state machine. The states are 'not processing rename' and * 'processing rename'. */ static void handle_rename (RepoWatchInfo *info, PFILE_NOTIFY_INFORMATION event, const char *worktree, const char *filename, gboolean last_event) { WTStatus *status = info->status; RenameInfo *rename_info = info->rename_info; if (event->Action == FILE_ACTION_RENAMED_OLD_NAME) seaf_debug ("Move %s ->\n", filename); else if (event->Action == FILE_ACTION_RENAMED_NEW_NAME) seaf_debug ("Move -> %s.\n", filename); if (!rename_info->processing) { if (event->Action == FILE_ACTION_RENAMED_OLD_NAME) { if (!last_event) { set_rename_processing_state (rename_info, filename); } else { /* RENAMED_OLD_NAME should not be the last event, just ignore it. */ } } } else { if (event->Action == FILE_ACTION_RENAMED_NEW_NAME) { /* Rename pair detected. */ add_event_to_queue (status, WT_EVENT_RENAME, rename_info->old_path, filename); unset_rename_processing_state (rename_info); } } } #if 0 static gboolean handle_consecutive_duplicate_event (RepoWatchInfo *info, PFILE_NOTIFY_INFORMATION event) { gboolean duplicate; /* Initially last_event is zero so it's not duplicate with any real events. */ duplicate = (info->last_event.action == event->Action && info->last_event.name_len == event->FileNameLength && memcmp (info->last_event.name, event->FileName, event->FileNameLength) == 0); info->last_event.action = event->Action; info->last_event.name_len = event->FileNameLength; memcpy (info->last_event.name, event->FileName, event->FileNameLength); return duplicate; } #endif static char * convert_to_unix_path (const char *worktree, const wchar_t *path, int path_len, gboolean convert_long_path) { char *utf8_path = NULL; if (convert_long_path) { wchar_t *long_path = win32_83_path_to_long_path (worktree, path, path_len/sizeof(wchar_t)); if (long_path) { utf8_path = g_utf16_to_utf8 (long_path, -1, NULL, NULL, NULL); g_free (long_path); } else utf8_path = g_utf16_to_utf8 (path, path_len/sizeof(wchar_t), NULL, NULL, NULL); } else utf8_path = g_utf16_to_utf8 (path, path_len/sizeof(wchar_t), NULL, NULL, NULL); char *p; for (p = utf8_path; *p != 0; ++p) if (*p == '\\') *p = '/'; return utf8_path; } static void process_one_event (RepoWatchInfo *info, const char *worktree, PFILE_NOTIFY_INFORMATION event, gboolean last_event) { WTStatus *status = info->status; char *filename; gboolean add_to_queue = TRUE; #if 0 if (handle_consecutive_duplicate_event (info, event)) add_to_queue = FALSE; #endif gboolean convert_long_path = !(event->Action == FILE_ACTION_RENAMED_OLD_NAME || event->Action == FILE_ACTION_REMOVED); filename = convert_to_unix_path (worktree, event->FileName, event->FileNameLength, convert_long_path); handle_rename (info, event, worktree, filename, last_event); if (event->Action == FILE_ACTION_MODIFIED) { seaf_debug ("Modified %s.\n", filename); /* Ignore modified event for directories. */ char *full_path = g_build_filename (worktree, filename, NULL); SeafStat st; int rc = seaf_stat (full_path, &st); if (rc < 0 || S_ISDIR(st.st_mode)) { g_free (full_path); goto out; } g_free (full_path); if (add_to_queue) add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->Action == FILE_ACTION_ADDED) { seaf_debug ("Created %s.\n", filename); add_event_to_queue (status, WT_EVENT_CREATE_OR_UPDATE, filename, NULL); } else if (event->Action == FILE_ACTION_REMOVED) { seaf_debug ("Deleted %s.\n", filename); add_event_to_queue (status, WT_EVENT_DELETE, filename, NULL); } out: g_free (filename); g_atomic_int_set (&info->status->last_changed, (gint)time(NULL)); } static gboolean process_events (const char *repo_id, RepoWatchInfo *info, char *event_buf, unsigned int buf_size) { PFILE_NOTIFY_INFORMATION event; int offset = 0; while (1) { event = (PFILE_NOTIFY_INFORMATION)&event_buf[offset]; offset += event->NextEntryOffset; process_one_event (info, info->worktree, event, (event->NextEntryOffset == 0)); if (!event->NextEntryOffset) break; } return TRUE; } static void * wt_monitor_job_win32 (void *vmonitor) { SeafWTMonitor *monitor = vmonitor; SeafWTMonitorPriv *priv = monitor->priv; /* 2 * sizeof(inotify_event) + 256, should be large enough for one event.*/ RepoWatchInfo *info; DWORD bytesRead = 0; ULONG_PTR key = 0; OVERLAPPED *ol = NULL; /* Use I/O Completion Port to watch asynchronous events on: * 1) dir watch handles(events created by ReadDirectoryChangesW) * 2) the cmd pipe (which is a socket indeed) */ if (!add_all_to_iocp(monitor)) { seaf_warning("Failed to add all to iocp\n"); return NULL; } while (1) { BOOL ret = GetQueuedCompletionStatus (priv->iocp_handle, /* iocp handle */ &bytesRead, /* length of info */ &key, /* completion key */ &ol, /* OVERLAPPED */ INFINITE); /* timeout */ static int retry; if (!ret) { seaf_warning ("GetQueuedCompletionStatus failed, " "error code %lu", GetLastError()); if (retry++ < 3) continue; else break; } else { /* clear the retry counter on success */ retry = 0; } if (key == (ULONG_PTR)monitor->cmd_pipe[0]) { /* Triggered by a cmd pipe event */ priv->cmd_bytes_read += (int)bytesRead; if (priv->cmd_bytes_read != sizeof(WatchCommand)) { reset_overlapped(ol); start_watch_cmd_pipe (monitor, ol); continue; } else priv->cmd_bytes_read = 0; seaf_debug ("recevied a pipe cmd, type %d for repo %s\n", priv->cmd.type, priv->cmd.repo_id); handle_watch_command (monitor, &priv->cmd); reset_overlapped(ol); start_watch_cmd_pipe (monitor, ol); } else { /* Trigger by one of the dir watch handles */ HANDLE hTriggered = (HANDLE)key; info = (RepoWatchInfo *)g_hash_table_lookup (priv->info_hash, (gconstpointer)hTriggered); if (info) { DirWatchAux *aux = g_hash_table_lookup (priv->buf_hash, (gconstpointer)hTriggered); process_events (info->status->repo_id, info, aux->buf, bytesRead); reset_overlapped(ol); if (!start_watch_dir_change(priv, hTriggered)) { seaf_warning ("start_watch_dir_change failed" "for repo %s, error code %lu\n", info->status->repo_id, GetLastError()); } } else { /* A previously unwatched dir_handle's DirWatchAux buf was scheduled to be freed. */ g_hash_table_remove (priv->buf_hash, (gconstpointer)hTriggered); } } } return NULL; } /* Get the HANDLE of a repo directory, for latter use in * ReadDirectoryChangesW(). This handle should be closed when the repo is * unwatched. */ static HANDLE get_handle_of_path(const wchar_t *path) { HANDLE dir_handle = NULL; dir_handle = CreateFileW (path, /* file name */ FILE_LIST_DIRECTORY, /* desired access */ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */ NULL, /* securitry attr */ OPEN_EXISTING, /* open options */ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, /* flags needed for asynchronous IO*/ NULL); /* template file */ if (dir_handle == INVALID_HANDLE_VALUE) { char *path_utf8 = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL); seaf_warning("failed to create dir handle for path %s, " "error code %lu", path_utf8, GetLastError()); g_free (path_utf8); return NULL; } return dir_handle; } static HANDLE add_watch (SeafWTMonitorPriv *priv, const char *repo_id, const char *worktree) { HANDLE dir_handle = NULL; wchar_t *path = NULL; RepoWatchInfo *info; /* worktree is in utf8, need to convert to wchar in win32 */ path = wchar_from_utf8 (worktree); dir_handle = get_handle_of_path (path); if (!dir_handle) { seaf_warning ("failed to open handle for worktree " "of repo %s\n", repo_id); g_free (path); return NULL; } g_free (path); pthread_mutex_lock (&priv->hash_lock); g_hash_table_insert (priv->handle_hash, g_strdup(repo_id), (gpointer)dir_handle); info = create_repo_watch_info (repo_id, worktree); g_hash_table_insert (priv->info_hash, (gpointer)dir_handle, info); pthread_mutex_unlock (&priv->hash_lock); add_event_to_queue (info->status, WT_EVENT_SCAN_DIR, "", NULL); return dir_handle; } static int handle_add_repo (SeafWTMonitor *monitor, const char *repo_id, const char *worktree) { HANDLE handle; handle = add_watch (monitor->priv, repo_id, worktree); if (handle == NULL || !add_handle_to_iocp(monitor, handle)) { return -1; } return 0; } static int handle_rm_repo (SeafWTMonitorPriv *priv, const char *repo_id, gpointer handle) { pthread_mutex_lock (&priv->hash_lock); g_hash_table_remove (priv->handle_hash, repo_id); g_hash_table_remove (priv->info_hash, handle); pthread_mutex_unlock (&priv->hash_lock); /* `aux' can't be freed here. Once we we close the dir_handle, its * outstanding io would cause GetQueuedCompletionStatus() to return some * information in aux->buf. If we free it here, it would cause seg fault. * It will be freed in the completion code of GetQueuedCompletionStatus(). */ CloseHandle (handle); return 0; } static int handle_refresh_repo (SeafWTMonitorPriv *priv, const char *repo_id) { return 0; } static void reply_watch_command (SeafWTMonitor *monitor, int result) { int n; n = pipewriten (monitor->res_pipe[1], &result, sizeof(int)); if (n != sizeof(int)) seaf_warning ("[wt mon] fail to write command result.\n"); } static void handle_watch_command (SeafWTMonitor *monitor, WatchCommand *cmd) { SeafWTMonitorPriv *priv = monitor->priv; if (cmd->type == CMD_ADD_WATCH) { if (g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, NULL, NULL)) { reply_watch_command (monitor, 0); return; } if (handle_add_repo(monitor, cmd->repo_id, cmd->worktree) < 0) { seaf_warning ("[wt mon] failed to watch worktree of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } seaf_debug ("[wt mon] add watch for repo %s\n", cmd->repo_id); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_DELETE_WATCH) { gpointer key, value; if (!g_hash_table_lookup_extended (priv->handle_hash, cmd->repo_id, &key, &value)) { reply_watch_command (monitor, 0); return; } handle_rm_repo (priv, cmd->repo_id, value); reply_watch_command (monitor, 0); } else if (cmd->type == CMD_REFRESH_WATCH) { if (handle_refresh_repo (priv, cmd->repo_id) < 0) { seaf_warning ("[wt mon] failed to refresh watch of repo %s.\n", cmd->repo_id); reply_watch_command (monitor, -1); return; } reply_watch_command (monitor, 0); } } /* Public interface functions. */ SeafWTMonitor * seaf_wt_monitor_new (SeafileSession *seaf) { SeafWTMonitor *monitor = g_new0 (SeafWTMonitor, 1); SeafWTMonitorPriv *priv = g_new0 (SeafWTMonitorPriv, 1); pthread_mutex_init (&priv->hash_lock, NULL); priv->handle_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); priv->info_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)free_repo_watch_info); priv->buf_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); monitor->priv = priv; monitor->seaf = seaf; monitor->job_func = wt_monitor_job_win32; return monitor; } WTStatus * seaf_wt_monitor_get_worktree_status (SeafWTMonitor *monitor, const char *repo_id) { SeafWTMonitorPriv *priv = monitor->priv; gpointer key, value; RepoWatchInfo *info; pthread_mutex_lock (&priv->hash_lock); if (!g_hash_table_lookup_extended (priv->handle_hash, repo_id, &key, &value)) { pthread_mutex_unlock (&priv->hash_lock); return NULL; } info = g_hash_table_lookup(priv->info_hash, value); wt_status_ref (info->status); pthread_mutex_unlock (&priv->hash_lock); return info->status; } seafile-6.1.5/daemon/wt-monitor.c000066400000000000000000000060601323477647300167030ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include "common.h" #include "seafile-session.h" #include "utils.h" #include "wt-monitor.h" #define DEBUG_FLAG SEAFILE_DEBUG_WATCH #include "log.h" #include int seaf_wt_monitor_start (SeafWTMonitor *monitor) { if (ccnet_pipe (monitor->cmd_pipe) < 0) { seaf_warning ("[wt mon] failed to create command pipe: %s.\n", strerror(errno)); return -1; } if (ccnet_pipe (monitor->res_pipe) < 0) { seaf_warning ("[wt mon] failed to create result pipe: %s.\n", strerror(errno)); return -1; } if (ccnet_job_manager_schedule_job (monitor->seaf->job_mgr, monitor->job_func, NULL, monitor) < 0) { seaf_warning ("[wt mon] failed to start monitor thread.\n"); return -1; } return 0; } int seaf_wt_monitor_watch_repo (SeafWTMonitor *monitor, const char *repo_id, const char *worktree) { WatchCommand cmd; int res; memset (&cmd, 0, sizeof(cmd)); memcpy (cmd.repo_id, repo_id, 37); cmd.type = CMD_ADD_WATCH; g_strlcpy (cmd.worktree, worktree, SEAF_PATH_MAX); int n = pipewriten (monitor->cmd_pipe[1], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] fail to write command pipe.\n"); return -1; } seaf_debug ("send a watch command, repo %s\n", repo_id); n = pipereadn (monitor->res_pipe[0], &res, sizeof(int)); if (n != sizeof(int)) { seaf_warning ("[wt mon] fail to read result pipe.\n"); return -1; } return res; } int seaf_wt_monitor_unwatch_repo (SeafWTMonitor *monitor, const char *repo_id) { WatchCommand cmd; int res; memset (&cmd, 0, sizeof(cmd)); memcpy (cmd.repo_id, repo_id, 37); cmd.type = CMD_DELETE_WATCH; int n = pipewriten (monitor->cmd_pipe[1], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] fail to write command pipe.\n"); return -1; } seaf_debug ("send an unwatch command, repo %s\n", repo_id); n = pipereadn (monitor->res_pipe[0], &res, sizeof(int)); if (n != sizeof(int)) { seaf_warning ("[wt mon] fail to read result pipe.\n"); return -1; } return res; } int seaf_wt_monitor_refresh_repo (SeafWTMonitor *monitor, const char *repo_id) { WatchCommand cmd; int res; memset (&cmd, 0, sizeof(cmd)); memcpy (cmd.repo_id, repo_id, 37); cmd.type = CMD_REFRESH_WATCH; int n = pipewriten (monitor->cmd_pipe[1], &cmd, sizeof(cmd)); if (n != sizeof(cmd)) { seaf_warning ("[wt mon] fail to write command pipe.\n"); return -1; } seaf_debug ("send a refresh command, repo %s\n", repo_id); n = pipereadn (monitor->res_pipe[0], &res, sizeof(int)); if (n != sizeof(int)) { seaf_warning ("[wt mon] fail to read result pipe.\n"); return -1; } return res; } seafile-6.1.5/daemon/wt-monitor.h000066400000000000000000000023701323477647300167100ustar00rootroot00000000000000#ifndef SEAF_WT_MONITOR_H #define SEAF_WT_MONITOR_H #include "wt-monitor-structs.h" #include "utils.h" typedef struct SeafWTMonitorPriv SeafWTMonitorPriv; struct _SeafileSession; typedef enum CommandType { CMD_ADD_WATCH, CMD_DELETE_WATCH, CMD_REFRESH_WATCH, N_CMD_TYPES, } CommandType; typedef struct WatchCommand { CommandType type; char repo_id[37]; char worktree[SEAF_PATH_MAX]; } WatchCommand; typedef struct SeafWTMonitor { struct _SeafileSession *seaf; SeafWTMonitorPriv *priv; ccnet_pipe_t cmd_pipe[2]; ccnet_pipe_t res_pipe[2]; /* platform dependent virtual functions */ void* (*job_func) (void *); } SeafWTMonitor; SeafWTMonitor * seaf_wt_monitor_new (struct _SeafileSession *seaf); int seaf_wt_monitor_start (SeafWTMonitor *monitor); int seaf_wt_monitor_watch_repo (SeafWTMonitor *monitor, const char *repo_id, const char *worktree); int seaf_wt_monitor_unwatch_repo (SeafWTMonitor *monitor, const char *repo_id); int seaf_wt_monitor_refresh_repo (SeafWTMonitor *monitor, const char *repo_id); WTStatus * seaf_wt_monitor_get_worktree_status (SeafWTMonitor *monitor, const char *repo_id); #endif seafile-6.1.5/debian/000077500000000000000000000000001323477647300143755ustar00rootroot00000000000000seafile-6.1.5/debian/README.Debian000066400000000000000000000002271323477647300164370ustar00rootroot00000000000000Seafile ------- For more information about Seafile, please visit http://seafile.com -- plt Fri, 30 March 2012 16:43:10 +0800 seafile-6.1.5/debian/changelog000066400000000000000000000061301323477647300162470ustar00rootroot00000000000000seafile-daemon (6.1.5) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 2 Feb 2018 13:50:34 +0800 seafile-daemon (6.1.4) unstable; urgency=low * new upstream release -- Jonathan Xu Tue, 19 Dec 2017 17:09:34 +0800 seafile-daemon (6.1.3) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 3 Nov 2017 13:58:10 +0800 seafile-daemon (6.1.2) unstable; urgency=low * new upstream release -- Jonathan Xu Wed, 25 Oct 2017 13:58:10 +0800 seafile-daemon (6.1.1) unstable; urgency=low * new upstream release -- Jonathan Xu Tue, 19 Sep 2017 18:08:10 +0800 seafile-daemon (6.1.0) unstable; urgency=low * new upstream release -- Jonathan Xu Wed, 2 Aug 2017 16:37:10 +0800 seafile-daemon (6.0.7) unstable; urgency=low * new upstream release -- Jonathan Xu Tue, 20 Jun 2017 16:37:10 +0800 seafile-daemon (6.0.6) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 28 Apr 2017 16:37:10 +0800 seafile-daemon (6.0.4.1) unstable; urgency=low * new upstream release -- Jonathan Xu Wed, 15 Mar 2017 16:37:10 +0800 seafile-daemon (6.0.4) unstable; urgency=low * new upstream release -- Jonathan Xu Tue, 21 Feb 2017 13:58:10 +0800 seafile-daemon (6.0.3) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 10 Feb 2017 15:27:16 +0800 seafile-daemon (6.0.2) unstable; urgency=low * new upstream release -- Jonathan Xu Thu, 5 Jan 2017 14:06:16 +0800 seafile-daemon (6.0.1) unstable; urgency=low * new upstream release -- Jonathan Xu Mon, 12 Dec 2016 14:47:32 +0800 seafile-daemon (6.0.0) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 14 Oct 2016 13:49:07 +0800 seafile-daemon (5.1.4) unstable; urgency=low * new upstream release -- Jonathan Xu Fri, 29 Jul 2016 13:49:07 +0800 seafile-daemon (5.1.3-1ubuntu1) UNRELEASED; urgency=medium * new upstream release -- m.eik michalke Thu, 30 Jun 2016 23:59:07 +0200 seafile-daemon (5.1.2-5ubuntu2) unstable; urgency=medium * fixed dependencies for seafile-daemon and seafile-cli -- m.eik michalke Mon, 27 Jun 2016 11:16:33 +0200 seafile-daemon (5.1.2-5ubuntu1) unstable; urgency=medium * repackaging with cleaned up orig.tar.xz archives * added symbols file -- m.eik michalke Fri, 17 Jun 2016 19:04:41 +0200 seafile-daemon (5.1.2-4) unstable; urgency=medium * split package into seafile-daemon, libseafile0, libseafile-dev and seafile-cli * updated the debian/copyright notice so people know who's responisble for the packaging * rewrote the rules file, much simpler now * prep for release on github -- m.eik michalke Wed, 15 Jun 2016 22:38:24 +0200 seafile-6.1.5/debian/compat000066400000000000000000000000021323477647300155730ustar00rootroot000000000000007 seafile-6.1.5/debian/control000066400000000000000000000044301323477647300160010ustar00rootroot00000000000000Source: seafile-daemon Section: net Priority: extra Maintainer: m.eik michalke Build-Depends: debhelper (>= 7), autotools-dev, libssl1.0-dev | libssl-dev (<< 1.1), libsqlite3-dev, intltool, libglib2.0-dev, libevent-dev, uuid-dev, libtool, libcurl4-openssl-dev, valac, libjansson-dev, python, libsearpc-dev, libccnet-dev Standards-Version: 3.9.5 Homepage: http://seafile.com Package: seafile-daemon Section: net Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, ccnet (>= 5.1.2) Conflicts: seafile Suggests: seafile-gui, seafile-cli Description: Seafile daemon File syncing and sharing software with file encryption and group sharing, emphasis on reliability and high performance. . This package contains the Seafile daemon. Package: libseafile0 Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends} Conflicts: seafile Description: Shared libraries for Seafile This package contains the shared libraries for the Seafile daemon. Package: seafile-cli Section: utils Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, libseafile0 (>= ${binary:Version}), ccnet (>= 5.1.2), seafile-daemon (>= ${binary:Version}), python-searpc Conflicts: seafile Description: Seafile command line interface. This package contains the command line interface to manage Seafile libraries. Package: libseafile-dev Section: libdevel Architecture: any Depends: ${misc:Depends}, libseafile0 (= ${binary:Version}) Conflicts: seafile Description: Development files for package libseafile0. This package contains the development files for the libseafile0 package. Package: seafile-daemon-dbg Section: debug Architecture: any Depends: seafile-daemon (= ${binary:Version}), ${misc:Depends}, Description: Debugging symbols for the seafile-daemon package. This package contains the debugging symbols for the seafile-daemon package. Package: libseafile-dbg Section: debug Architecture: any Depends: libseafile0 (= ${binary:Version}), ${misc:Depends}, Description: Debugging symbols for the libseafile0 package. This package contains the debugging symbols for the libseafile0 package. seafile-6.1.5/debian/copyright000066400000000000000000000036121323477647300163320ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: seafile Upstream-Contact: Lingtao Pan Source: https://github.com/haiwen/seafile Files: * Copyright: 2012 plt License: GPL-2 with OpenSSL exception This program is released under GPL-2, with the following addition permission to link with OpenSSL library. . If you modify this program, or any covered work, by linking or combining it with the OpenSSL project's OpenSSL library (or a modified version of that library), containing parts covered by the terms of the OpenSSL or SSLeay licenses, Seafile Ltd. grants you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of OpenSSL used as well as that of the covered work. . This software 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. . You should have received a copy of the license with your Debian system, in the file /usr/share/common-licenses/GPL-2, or with the source package as the file COPYING or LICENSE. Files: debian/* Copyright: 2016 m.eik michalke License: GPL-2 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This software 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. . You should have received a copy of the license with your Debian system, in the file /usr/share/common-licenses/GPL-2, or with the source package as the file COPYING or LICENSE. seafile-6.1.5/debian/dirs000066400000000000000000000000071323477647300152560ustar00rootroot00000000000000usr/binseafile-6.1.5/debian/docs000066400000000000000000000000001323477647300152360ustar00rootroot00000000000000seafile-6.1.5/debian/libseafile-dev.install000066400000000000000000000001471323477647300206420ustar00rootroot00000000000000usr/include/seafile usr/lib/pkgconfig usr/lib/libseafile.a usr/lib/libseafile.la usr/lib/libseafile.so seafile-6.1.5/debian/libseafile0.install000066400000000000000000000000741323477647300201450ustar00rootroot00000000000000usr/lib/*.so.* usr/lib/python2.7/dist-packages/seafile/*.py seafile-6.1.5/debian/libseafile0.symbols000066400000000000000000000424571323477647300202020ustar00rootroot00000000000000libseafile.so.0 libseafile0 #MINVER# seafile_add_chunk_server@Base 5.1.2 seafile_branch_construct@Base 5.1.2 seafile_branch_get_commit_id@Base 5.1.2 seafile_branch_get_name@Base 5.1.2 seafile_branch_get_repo_id@Base 5.1.2 seafile_branch_get_type@Base 5.1.2 seafile_branch_new@Base 5.1.2 seafile_branch_set_commit_id@Base 5.1.2 seafile_branch_set_name@Base 5.1.2 seafile_branch_set_repo_id@Base 5.1.2 seafile_calc_dir_size@Base 5.1.2 seafile_check_quota@Base 5.1.2 seafile_checkout_task_construct@Base 5.1.2 seafile_checkout_task_get_finished_files@Base 5.1.2 seafile_checkout_task_get_repo_id@Base 5.1.2 seafile_checkout_task_get_total_files@Base 5.1.2 seafile_checkout_task_get_type@Base 5.1.2 seafile_checkout_task_get_worktree@Base 5.1.2 seafile_checkout_task_new@Base 5.1.2 seafile_checkout_task_set_finished_files@Base 5.1.2 seafile_checkout_task_set_repo_id@Base 5.1.2 seafile_checkout_task_set_total_files@Base 5.1.2 seafile_checkout_task_set_worktree@Base 5.1.2 seafile_clone_task_construct@Base 5.1.2 seafile_clone_task_get_error_str@Base 5.1.2 seafile_clone_task_get_peer_id@Base 5.1.2 seafile_clone_task_get_repo_id@Base 5.1.2 seafile_clone_task_get_repo_name@Base 5.1.2 seafile_clone_task_get_state@Base 5.1.2 seafile_clone_task_get_tx_id@Base 5.1.2 seafile_clone_task_get_type@Base 5.1.2 seafile_clone_task_get_worktree@Base 5.1.2 seafile_clone_task_new@Base 5.1.2 seafile_clone_task_set_error_str@Base 5.1.2 seafile_clone_task_set_peer_id@Base 5.1.2 seafile_clone_task_set_repo_id@Base 5.1.2 seafile_clone_task_set_repo_name@Base 5.1.2 seafile_clone_task_set_state@Base 5.1.2 seafile_clone_task_set_tx_id@Base 5.1.2 seafile_clone_task_set_worktree@Base 5.1.2 seafile_commit_construct@Base 5.1.2 seafile_commit_get_conflict@Base 5.1.2 seafile_commit_get_creator@Base 5.1.2 seafile_commit_get_creator_name@Base 5.1.2 seafile_commit_get_ctime@Base 5.1.2 seafile_commit_get_desc@Base 5.1.2 seafile_commit_get_device_name@Base 5.1.2 seafile_commit_get_id@Base 5.1.2 seafile_commit_get_new_merge@Base 5.1.2 seafile_commit_get_parent_id@Base 5.1.2 seafile_commit_get_repo_id@Base 5.1.2 seafile_commit_get_rev_file_id@Base 5.1.2 seafile_commit_get_rev_file_size@Base 5.1.2 seafile_commit_get_rev_renamed_old_path@Base 5.1.2 seafile_commit_get_root_id@Base 5.1.2 seafile_commit_get_second_parent_id@Base 5.1.2 seafile_commit_get_type@Base 5.1.2 seafile_commit_get_version@Base 5.1.2 seafile_commit_new@Base 5.1.2 seafile_commit_set_conflict@Base 5.1.2 seafile_commit_set_creator@Base 5.1.2 seafile_commit_set_creator_name@Base 5.1.2 seafile_commit_set_ctime@Base 5.1.2 seafile_commit_set_desc@Base 5.1.2 seafile_commit_set_device_name@Base 5.1.2 seafile_commit_set_id@Base 5.1.2 seafile_commit_set_new_merge@Base 5.1.2 seafile_commit_set_parent_id@Base 5.1.2 seafile_commit_set_repo_id@Base 5.1.2 seafile_commit_set_rev_file_id@Base 5.1.2 seafile_commit_set_rev_file_size@Base 5.1.2 seafile_commit_set_rev_renamed_old_path@Base 5.1.2 seafile_commit_set_root_id@Base 5.1.2 seafile_commit_set_second_parent_id@Base 5.1.2 seafile_commit_set_version@Base 5.1.2 seafile_copy_result_construct@Base 5.1.2 seafile_copy_result_get_background@Base 5.1.2 seafile_copy_result_get_task_id@Base 5.1.2 seafile_copy_result_get_type@Base 5.1.2 seafile_copy_result_new@Base 5.1.2 seafile_copy_result_set_background@Base 5.1.2 seafile_copy_result_set_task_id@Base 5.1.2 seafile_copy_task_construct@Base 5.1.2 seafile_copy_task_get_canceled@Base 5.1.2 seafile_copy_task_get_done@Base 5.1.2 seafile_copy_task_get_failed@Base 5.1.2 seafile_copy_task_get_successful@Base 5.1.2 seafile_copy_task_get_total@Base 5.1.2 seafile_copy_task_get_type@Base 5.1.2 seafile_copy_task_new@Base 5.1.2 seafile_copy_task_set_canceled@Base 5.1.2 seafile_copy_task_set_done@Base 5.1.2 seafile_copy_task_set_failed@Base 5.1.2 seafile_copy_task_set_successful@Base 5.1.2 seafile_copy_task_set_total@Base 5.1.2 seafile_create_repo@Base 5.1.2 seafile_create_repo_async@Base 5.1.2 seafile_crypt_key_construct@Base 5.1.2 seafile_crypt_key_get_iv@Base 5.1.2 seafile_crypt_key_get_key@Base 5.1.2 seafile_crypt_key_get_type@Base 5.1.2 seafile_crypt_key_new@Base 5.1.2 seafile_crypt_key_set_iv@Base 5.1.2 seafile_crypt_key_set_key@Base 5.1.2 seafile_del_chunk_server@Base 5.1.2 seafile_deleted_entry_construct@Base 5.1.2 seafile_deleted_entry_get_basedir@Base 5.1.2 seafile_deleted_entry_get_commit_id@Base 5.1.2 seafile_deleted_entry_get_delete_time@Base 5.1.2 seafile_deleted_entry_get_file_size@Base 5.1.2 seafile_deleted_entry_get_mode@Base 5.1.2 seafile_deleted_entry_get_obj_id@Base 5.1.2 seafile_deleted_entry_get_obj_name@Base 5.1.2 seafile_deleted_entry_get_scan_stat@Base 5.1.2 seafile_deleted_entry_get_type@Base 5.1.2 seafile_deleted_entry_new@Base 5.1.2 seafile_deleted_entry_set_basedir@Base 5.1.2 seafile_deleted_entry_set_commit_id@Base 5.1.2 seafile_deleted_entry_set_delete_time@Base 5.1.2 seafile_deleted_entry_set_file_size@Base 5.1.2 seafile_deleted_entry_set_mode@Base 5.1.2 seafile_deleted_entry_set_obj_id@Base 5.1.2 seafile_deleted_entry_set_obj_name@Base 5.1.2 seafile_deleted_entry_set_scan_stat@Base 5.1.2 seafile_destroy_repo@Base 5.1.2 seafile_diff_entry_construct@Base 5.1.2 seafile_diff_entry_get_name@Base 5.1.2 seafile_diff_entry_get_new_name@Base 5.1.2 seafile_diff_entry_get_status@Base 5.1.2 seafile_diff_entry_get_type@Base 5.1.2 seafile_diff_entry_new@Base 5.1.2 seafile_diff_entry_set_name@Base 5.1.2 seafile_diff_entry_set_new_name@Base 5.1.2 seafile_diff_entry_set_status@Base 5.1.2 seafile_dir_construct@Base 5.1.2 seafile_dir_get_id@Base 5.1.2 seafile_dir_get_type@Base 5.1.2 seafile_dir_get_version@Base 5.1.2 seafile_dir_new@Base 5.1.2 seafile_dir_set_id@Base 5.1.2 seafile_dir_set_version@Base 5.1.2 seafile_dirent_construct@Base 5.1.2 seafile_dirent_get_is_locked@Base 5.1.2 seafile_dirent_get_is_shared@Base 5.1.2 seafile_dirent_get_lock_owner@Base 5.1.2 seafile_dirent_get_lock_time@Base 5.1.2 seafile_dirent_get_mode@Base 5.1.2 seafile_dirent_get_modifier@Base 5.1.2 seafile_dirent_get_mtime@Base 5.1.2 seafile_dirent_get_obj_id@Base 5.1.2 seafile_dirent_get_obj_name@Base 5.1.2 seafile_dirent_get_permission@Base 5.1.2 seafile_dirent_get_size@Base 5.1.2 seafile_dirent_get_type@Base 5.1.2 seafile_dirent_get_version@Base 5.1.2 seafile_dirent_new@Base 5.1.2 seafile_dirent_set_is_locked@Base 5.1.2 seafile_dirent_set_is_shared@Base 5.1.2 seafile_dirent_set_lock_owner@Base 5.1.2 seafile_dirent_set_lock_time@Base 5.1.2 seafile_dirent_set_mode@Base 5.1.2 seafile_dirent_set_modifier@Base 5.1.2 seafile_dirent_set_mtime@Base 5.1.2 seafile_dirent_set_obj_id@Base 5.1.2 seafile_dirent_set_obj_name@Base 5.1.2 seafile_dirent_set_permission@Base 5.1.2 seafile_dirent_set_size@Base 5.1.2 seafile_dirent_set_version@Base 5.1.2 seafile_disable_auto_sync_async@Base 5.1.2 seafile_enable_auto_sync_async@Base 5.1.2 seafile_encryption_info_construct@Base 5.1.2 seafile_encryption_info_get_enc_version@Base 5.1.2 seafile_encryption_info_get_magic@Base 5.1.2 seafile_encryption_info_get_passwd@Base 5.1.2 seafile_encryption_info_get_random_key@Base 5.1.2 seafile_encryption_info_get_repo_id@Base 5.1.2 seafile_encryption_info_get_type@Base 5.1.2 seafile_encryption_info_new@Base 5.1.2 seafile_encryption_info_set_enc_version@Base 5.1.2 seafile_encryption_info_set_magic@Base 5.1.2 seafile_encryption_info_set_passwd@Base 5.1.2 seafile_encryption_info_set_random_key@Base 5.1.2 seafile_encryption_info_set_repo_id@Base 5.1.2 seafile_file_last_modified_info_construct@Base 5.1.2 seafile_file_last_modified_info_get_file_name@Base 5.1.2 seafile_file_last_modified_info_get_last_modified@Base 5.1.2 seafile_file_last_modified_info_get_type@Base 5.1.2 seafile_file_last_modified_info_new@Base 5.1.2 seafile_file_last_modified_info_set_file_name@Base 5.1.2 seafile_file_last_modified_info_set_last_modified@Base 5.1.2 seafile_get_config@Base 5.1.2 seafile_get_config_async@Base 5.1.2 seafile_get_decrypt_key@Base 5.1.2 seafile_get_repo@Base 5.1.2 seafile_get_repo_list@Base 5.1.2 seafile_get_repo_property@Base 5.1.2 seafile_get_repo_token@Base 5.1.2 seafile_is_auto_sync_enabled_async@Base 5.1.2 seafile_list_chunk_servers@Base 5.1.2 seafile_post_file@Base 5.1.2 seafile_post_file_blocks@Base 5.1.2 seafile_post_multi_files@Base 5.1.2 seafile_put_file@Base 5.1.2 seafile_put_file_blocks@Base 5.1.2 seafile_repo_construct@Base 5.1.2 seafile_repo_get_auto_sync@Base 5.1.2 seafile_repo_get_desc@Base 5.1.2 seafile_repo_get_enc_version@Base 5.1.2 seafile_repo_get_encrypted@Base 5.1.2 seafile_repo_get_file_count@Base 5.1.2 seafile_repo_get_group_id@Base 5.1.2 seafile_repo_get_head_cmmt_id@Base 5.1.2 seafile_repo_get_id@Base 5.1.2 seafile_repo_get_is_corrupted@Base 5.1.2 seafile_repo_get_is_original_owner@Base 5.1.2 seafile_repo_get_is_shared@Base 5.1.2 seafile_repo_get_is_virtual@Base 5.1.2 seafile_repo_get_last_modified@Base 5.1.2 seafile_repo_get_last_modify@Base 5.1.2 seafile_repo_get_last_sync_time@Base 5.1.2 seafile_repo_get_magic@Base 5.1.2 seafile_repo_get_name@Base 5.1.2 seafile_repo_get_origin_path@Base 5.1.2 seafile_repo_get_origin_repo_id@Base 5.1.2 seafile_repo_get_origin_repo_name@Base 5.1.2 seafile_repo_get_permission@Base 5.1.2 seafile_repo_get_random_key@Base 5.1.2 seafile_repo_get_relay_id@Base 5.1.2 seafile_repo_get_repaired@Base 5.1.2 seafile_repo_get_repo_desc@Base 5.1.2 seafile_repo_get_repo_id@Base 5.1.2 seafile_repo_get_repo_name@Base 5.1.2 seafile_repo_get_root@Base 5.1.2 seafile_repo_get_share_type@Base 5.1.2 seafile_repo_get_size@Base 5.1.2 seafile_repo_get_store_id@Base 5.1.2 seafile_repo_get_type@Base 5.1.2 seafile_repo_get_user@Base 5.1.2 seafile_repo_get_version@Base 5.1.2 seafile_repo_get_virtual_perm@Base 5.1.2 seafile_repo_get_worktree@Base 5.1.2 seafile_repo_get_worktree_invalid@Base 5.1.2 seafile_repo_new@Base 5.1.2 seafile_repo_query_access_property@Base 5.1.2 seafile_repo_set_auto_sync@Base 5.1.2 seafile_repo_set_desc@Base 5.1.2 seafile_repo_set_enc_version@Base 5.1.2 seafile_repo_set_encrypted@Base 5.1.2 seafile_repo_set_file_count@Base 5.1.2 seafile_repo_set_group_id@Base 5.1.2 seafile_repo_set_head_cmmt_id@Base 5.1.2 seafile_repo_set_id@Base 5.1.2 seafile_repo_set_is_corrupted@Base 5.1.2 seafile_repo_set_is_original_owner@Base 5.1.2 seafile_repo_set_is_shared@Base 5.1.2 seafile_repo_set_is_virtual@Base 5.1.2 seafile_repo_set_last_modified@Base 5.1.2 seafile_repo_set_last_modify@Base 5.1.2 seafile_repo_set_last_sync_time@Base 5.1.2 seafile_repo_set_magic@Base 5.1.2 seafile_repo_set_name@Base 5.1.2 seafile_repo_set_origin_path@Base 5.1.2 seafile_repo_set_origin_repo_id@Base 5.1.2 seafile_repo_set_origin_repo_name@Base 5.1.2 seafile_repo_set_permission@Base 5.1.2 seafile_repo_set_random_key@Base 5.1.2 seafile_repo_set_relay_id@Base 5.1.2 seafile_repo_set_repaired@Base 5.1.2 seafile_repo_set_repo_desc@Base 5.1.2 seafile_repo_set_repo_id@Base 5.1.2 seafile_repo_set_repo_name@Base 5.1.2 seafile_repo_set_root@Base 5.1.2 seafile_repo_set_share_type@Base 5.1.2 seafile_repo_set_size@Base 5.1.2 seafile_repo_set_store_id@Base 5.1.2 seafile_repo_set_user@Base 5.1.2 seafile_repo_set_version@Base 5.1.2 seafile_repo_set_virtual_perm@Base 5.1.2 seafile_repo_set_worktree@Base 5.1.2 seafile_repo_set_worktree_invalid@Base 5.1.2 seafile_repo_token_info_construct@Base 5.1.2 seafile_repo_token_info_get_client_ver@Base 5.1.2 seafile_repo_token_info_get_email@Base 5.1.2 seafile_repo_token_info_get_peer_id@Base 5.1.2 seafile_repo_token_info_get_peer_ip@Base 5.1.2 seafile_repo_token_info_get_peer_name@Base 5.1.2 seafile_repo_token_info_get_repo_id@Base 5.1.2 seafile_repo_token_info_get_repo_name@Base 5.1.2 seafile_repo_token_info_get_repo_owner@Base 5.1.2 seafile_repo_token_info_get_sync_time@Base 5.1.2 seafile_repo_token_info_get_token@Base 5.1.2 seafile_repo_token_info_get_type@Base 5.1.2 seafile_repo_token_info_new@Base 5.1.2 seafile_repo_token_info_set_client_ver@Base 5.1.2 seafile_repo_token_info_set_email@Base 5.1.2 seafile_repo_token_info_set_peer_id@Base 5.1.2 seafile_repo_token_info_set_peer_ip@Base 5.1.2 seafile_repo_token_info_set_peer_name@Base 5.1.2 seafile_repo_token_info_set_repo_id@Base 5.1.2 seafile_repo_token_info_set_repo_name@Base 5.1.2 seafile_repo_token_info_set_repo_owner@Base 5.1.2 seafile_repo_token_info_set_sync_time@Base 5.1.2 seafile_repo_token_info_set_token@Base 5.1.2 seafile_session_info_construct@Base 5.1.2 seafile_session_info_get_datadir@Base 5.1.2 seafile_session_info_get_type@Base 5.1.2 seafile_session_info_new@Base 5.1.2 seafile_session_info_set_datadir@Base 5.1.2 seafile_set_config@Base 5.1.2 seafile_set_config_async@Base 5.1.2 seafile_set_org_quota@Base 5.1.2 seafile_set_org_user_quota@Base 5.1.2 seafile_set_repo_property@Base 5.1.2 seafile_set_repo_token@Base 5.1.2 seafile_set_user_quota@Base 5.1.2 seafile_shared_group_construct@Base 5.1.2 seafile_shared_group_get_group_id@Base 5.1.2 seafile_shared_group_get_perm@Base 5.1.2 seafile_shared_group_get_repo_id@Base 5.1.2 seafile_shared_group_get_type@Base 5.1.2 seafile_shared_group_new@Base 5.1.2 seafile_shared_group_set_group_id@Base 5.1.2 seafile_shared_group_set_perm@Base 5.1.2 seafile_shared_group_set_repo_id@Base 5.1.2 seafile_shared_user_construct@Base 5.1.2 seafile_shared_user_get_perm@Base 5.1.2 seafile_shared_user_get_repo_id@Base 5.1.2 seafile_shared_user_get_type@Base 5.1.2 seafile_shared_user_get_user@Base 5.1.2 seafile_shared_user_new@Base 5.1.2 seafile_shared_user_set_perm@Base 5.1.2 seafile_shared_user_set_repo_id@Base 5.1.2 seafile_shared_user_set_user@Base 5.1.2 seafile_sync_info_construct@Base 5.1.2 seafile_sync_info_get_bad_local_branch@Base 5.1.2 seafile_sync_info_get_deleted_on_relay@Base 5.1.2 seafile_sync_info_get_head_commit@Base 5.1.2 seafile_sync_info_get_need_fetch@Base 5.1.2 seafile_sync_info_get_need_merge@Base 5.1.2 seafile_sync_info_get_need_upload@Base 5.1.2 seafile_sync_info_get_repo_id@Base 5.1.2 seafile_sync_info_get_type@Base 5.1.2 seafile_sync_info_new@Base 5.1.2 seafile_sync_info_set_bad_local_branch@Base 5.1.2 seafile_sync_info_set_deleted_on_relay@Base 5.1.2 seafile_sync_info_set_head_commit@Base 5.1.2 seafile_sync_info_set_need_fetch@Base 5.1.2 seafile_sync_info_set_need_merge@Base 5.1.2 seafile_sync_info_set_need_upload@Base 5.1.2 seafile_sync_info_set_repo_id@Base 5.1.2 seafile_sync_task_construct@Base 5.1.2 seafile_sync_task_get_dest_id@Base 5.1.2 seafile_sync_task_get_error@Base 5.1.2 seafile_sync_task_get_force_upload@Base 5.1.2 seafile_sync_task_get_is_sync_lan@Base 5.1.2 seafile_sync_task_get_repo_id@Base 5.1.2 seafile_sync_task_get_state@Base 5.1.2 seafile_sync_task_get_tx_id@Base 5.1.2 seafile_sync_task_get_type@Base 5.1.2 seafile_sync_task_new@Base 5.1.2 seafile_sync_task_set_dest_id@Base 5.1.2 seafile_sync_task_set_error@Base 5.1.2 seafile_sync_task_set_force_upload@Base 5.1.2 seafile_sync_task_set_is_sync_lan@Base 5.1.2 seafile_sync_task_set_repo_id@Base 5.1.2 seafile_sync_task_set_state@Base 5.1.2 seafile_sync_task_set_tx_id@Base 5.1.2 seafile_task_construct@Base 5.1.2 seafile_task_get_block_done@Base 5.1.2 seafile_task_get_block_total@Base 5.1.2 seafile_task_get_dest_id@Base 5.1.2 seafile_task_get_dsize@Base 5.1.2 seafile_task_get_error_str@Base 5.1.2 seafile_task_get_from_branch@Base 5.1.2 seafile_task_get_fs_objects_done@Base 5.1.2 seafile_task_get_fs_objects_total@Base 5.1.2 seafile_task_get_rate@Base 5.1.2 seafile_task_get_repo_id@Base 5.1.2 seafile_task_get_rsize@Base 5.1.2 seafile_task_get_rt_state@Base 5.1.2 seafile_task_get_state@Base 5.1.2 seafile_task_get_to_branch@Base 5.1.2 seafile_task_get_ttype@Base 5.1.2 seafile_task_get_tx_id@Base 5.1.2 seafile_task_get_type@Base 5.1.2 seafile_task_new@Base 5.1.2 seafile_task_set_block_done@Base 5.1.2 seafile_task_set_block_total@Base 5.1.2 seafile_task_set_dest_id@Base 5.1.2 seafile_task_set_dsize@Base 5.1.2 seafile_task_set_error_str@Base 5.1.2 seafile_task_set_from_branch@Base 5.1.2 seafile_task_set_fs_objects_done@Base 5.1.2 seafile_task_set_fs_objects_total@Base 5.1.2 seafile_task_set_rate@Base 5.1.2 seafile_task_set_repo_id@Base 5.1.2 seafile_task_set_rsize@Base 5.1.2 seafile_task_set_rt_state@Base 5.1.2 seafile_task_set_state@Base 5.1.2 seafile_task_set_to_branch@Base 5.1.2 seafile_task_set_ttype@Base 5.1.2 seafile_task_set_tx_id@Base 5.1.2 seafile_trash_repo_construct@Base 5.1.2 seafile_trash_repo_get_del_time@Base 5.1.2 seafile_trash_repo_get_head_id@Base 5.1.2 seafile_trash_repo_get_owner_id@Base 5.1.2 seafile_trash_repo_get_repo_id@Base 5.1.2 seafile_trash_repo_get_repo_name@Base 5.1.2 seafile_trash_repo_get_size@Base 5.1.2 seafile_trash_repo_get_type@Base 5.1.2 seafile_trash_repo_new@Base 5.1.2 seafile_trash_repo_set_del_time@Base 5.1.2 seafile_trash_repo_set_head_id@Base 5.1.2 seafile_trash_repo_set_owner_id@Base 5.1.2 seafile_trash_repo_set_repo_id@Base 5.1.2 seafile_trash_repo_set_repo_name@Base 5.1.2 seafile_trash_repo_set_size@Base 5.1.2 seafile_web_access_construct@Base 5.1.2 seafile_web_access_get_obj_id@Base 5.1.2 seafile_web_access_get_op@Base 5.1.2 seafile_web_access_get_repo_id@Base 5.1.2 seafile_web_access_get_type@Base 5.1.2 seafile_web_access_get_username@Base 5.1.2 seafile_web_access_new@Base 5.1.2 seafile_web_access_set_obj_id@Base 5.1.2 seafile_web_access_set_op@Base 5.1.2 seafile_web_access_set_repo_id@Base 5.1.2 seafile_web_access_set_username@Base 5.1.2 seafile_web_query_access_token@Base 5.1.2 seafile-6.1.5/debian/patches/000077500000000000000000000000001323477647300160245ustar00rootroot00000000000000seafile-6.1.5/debian/patches/fix-pkgconfig-paths.patch000066400000000000000000000007771323477647300227300ustar00rootroot00000000000000Fixing wrong pkgconfig paths. --- a/lib/libseafile.pc.in +++ b/lib/libseafile.pc.in @@ -1,4 +1,4 @@ -prefix=(DESTDIR)@prefix@ +prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -85,10 +85,3 @@ rm -f rpc_table.stamp rm -f rpc_table.tmp rm -f vala.tmp vala.stamp ${valac_gen} - -install-data-local: -if MACOS - sed -i '' -e "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles) -else - ${SED} -i "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles) -endif seafile-6.1.5/debian/patches/series000066400000000000000000000000321323477647300172340ustar00rootroot00000000000000fix-pkgconfig-paths.patch seafile-6.1.5/debian/rules000077500000000000000000000007301323477647300154550ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- %: dh $@ --with python2 --with autotools_dev override_dh_auto_configure: ./autogen.sh dh_auto_configure -- --disable-fuse override_dh_auto_test: # make check seems to be broken override_dh_strip: # emptying the dependency_libs field in .la files sed -i "/dependency_libs/ s/'.*'/''/" `find debian/ -name '*.la'` dh_strip -pseafile-daemon --dbg-package=seafile-daemon-dbg dh_strip -plibseafile0 --dbg-package=libseafile-dbg seafile-6.1.5/debian/seafile-cli.install000066400000000000000000000000571323477647300201440ustar00rootroot00000000000000usr/bin/seaf-cli usr/share/man/man1/seaf-cli.1 seafile-6.1.5/debian/seafile-daemon.install000066400000000000000000000000651323477647300206370ustar00rootroot00000000000000usr/bin/seaf-daemon usr/share/man/man1/seaf-daemon.1 seafile-6.1.5/debian/source/000077500000000000000000000000001323477647300156755ustar00rootroot00000000000000seafile-6.1.5/debian/source/format000066400000000000000000000000141323477647300171030ustar00rootroot000000000000003.0 (quilt) seafile-6.1.5/dmg/000077500000000000000000000000001323477647300137225ustar00rootroot00000000000000seafile-6.1.5/dmg/seafileLayout/000077500000000000000000000000001323477647300165305ustar00rootroot00000000000000seafile-6.1.5/dmg/seafileLayout/Background/000077500000000000000000000000001323477647300206075ustar00rootroot00000000000000seafile-6.1.5/dmg/seafileLayout/Background/dmg_background.jpg000066400000000000000000002276251323477647300242750ustar00rootroot00000000000000ÿØÿàJFIFHHÿá lExifMM*bj(1r2އi¢ÎHHAdobe Photoshop CS Windows2009:02:17 05:58:15 ÿÿ @ ($(, 7HHÿØÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀj !ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?Y§ó ÓµWe\sÓù×ÐB%¶Š)ã» Ky_»ò×ø·/_lf¨Ë¦ÜÃ;$ÖóDïB§ò5õ±vÐ¥˜¶*mæ3H”cöÛýi^%>}ª¸ì¡Tú ¸§{²[V"Ùû¼•ÏÞþñ¦´LrqŽÿJ¢HLD¸8Èô¡íöŒ·^ÔšdOÞOSÐzUwLry5œÏ,àúõëQ²mäõ¬™h…”àÔ&"̱è*(|‰4â(A<¼ˆ÷È&™$ m®{Î?•R%’ª3rÛFÀÇnôôˆ¹ôQZŶt¾`AެzÒÎ}Íj@øâ¹rBcæ u« HÙl³SÉúÑ`l·ob!XüÒÊ´zxü)ϧHÖÁÂ?’\«I·ï‘Ž·4]"w,.ŸVˆÿ7Ú“‚€ \¾þÝ*‹X‡Fnp 8É'<‘œãŽ¿ýj}AØI,’-Ìœ€Ç$Ùéš«%¶Á½ÇÌ~êú}i‰3>dÆIäÿ:¢Á$ƒžÙíYÈÖ$oLîCP2gšÍ£D2E20$( P: v¦xÀäÔ¤;’¥¼ ÏæÈÀvmL–=‡^3ëÚ‘mäp­+1 ®O 3œNI?RZ’Þ„‹lÌ3±ûŠ”@d# …èéZŶ]ˆÇß­]DÜp>cVKeûT„0G#(ìŽÿ#Zq؈dÀ„¹áXço¹©nÌ] XJˆ3ª8Ë9nç·µO žrÀ#€*y“Z Í ’Ø>Õœòî}Oµ'Ø–,ycÔÑÌ+äµÛûÉ?¿ÔÖEÚäš´À¡%¹;»°ÇJ¬ðí›ðš4L¯*+6UJŒ Ï8çõÍ@bÏo³±¢by]‡çJb®HÉ= “Úiï<è¡wK#Qî{V´ÖÑŒÙKkO®$`_9àc©ÖÁ}.ZÔ¬4øcŠÚód,ñË•9U<|•N8ZdqµÀÞ?½ƒÇåWNî:‘;'¡ ½»Èá#±'ڮƊ–<˜ó…%pO=qÎ Y ز¶Xˆis‘ò®~ïþ{sÜ3ÙÛžCÉ'ëøÔ=î+—¡ƒ!F8QǵYò„ ÿ_­dÞ¥$N±ìŒ‚“Émƒ?Ÿ¥@ðw0ú „ÊhͼBÄøÿ…fKj#˜|ßÂ=+¢,É”e·Æ]ÿT^g̤…ÿdgLiOl‚Cå—dçnåÚHõ#& xö—Tùƒq–Qœgô©±¥ÆùB5Éö,dò›°ì –RØ¿N¹«™° íϧëL–˯ü´~\€ $’HwúT–ºt÷’ÅÄXãjzã¿ôÿS’Š›fbÛm@!}=kNÖÜEó2†‘‡ÊðûÕ6Iz8ÌŸ"ç'%›Ö´­ èª8¬äÆ‘¢‘íTsSÇQïÞ¹äÍb‰ w5¨OÍ$ÆÑMíÀùˆì*¬ö ±,ò†'o#œVÊfN&Töä±-×ùU¶ç,¹‡õúVÉE(‘mü‚IMÛöÿµŒgòªòD6«² ÀrrIs’rrzóŽ=)Ø«‹ok'™æCàŽ¸À#ŸÒ¬%±íA…[Ö\¾mãc>|úî?Óçf;1EEÇa~Êdl‘Æ?*˜ÚÉnñ1—8eÈê3Ö¥ÉlROs>+]¤1cÐU”‡'ÏSTÙ65´ëX âFp»OD‡Þ®,kÊ™$ûb°”ÍU‹1Ç©«@¬›4H ÑheRäã# ¥wmmu+ËÜóÔŠ©,%ÿÏJÖ,ÎH«-—ՈÇåT¦µÚã'¹ô­c+™8ؤöF÷AQ¥‰wÞãžÞÕ§0¬L-<ñF¹õ«1Ùƒ…O»Rä4‹ðÙª’*̶I²#æ!;y•›f‰˜‡ÿ^¢)“òŠ.+¤@€ç<šµA01’j›E”GÝ>ç5aWoÖ²l´‡…¥Æ)\«zàQ£Þ˜ƒo¤Ûš.+ 1ô'ð¨ž-Çši‰¡éMx6à`ƒŽr*¹‰å`TÂ<I²’$ Áºô§Fȧh8=ê-")vƒÚ£1íà žô\v"Hööæ¥TÇÖ©²lXUÛõ©j)"L`ZiôG½4×½1X~æ*'õ¥@¥€$õô¥¶ÃáGBL#&šbhŒ¯sL|»rI>õW‡*í÷56KÈJ–RAŒ_åA\ ›•`ôÍ+@ æ•Æ‘ž”õŒŽÜÕ\›,|f¤ÀÅMÇaô£nÑžô\,4©ÎO^¢”F[;{ žiÜ,&àRýÞh„Æ9?…&[’¦h™0Û’G‚´›h¸X]›Fi¥I94\,!RhÙØS¸¬vŠ6•Ãtô¢á``X‚ÙüM1ŸO΋ŽÃDxúÒˆòi\,;o`)Á6ŠW‡ªc­HªFy4›‡„Í8%!‰åûRyt\,(òñÚ‹…„)šO/Ú‹…ƒËâ˜\VË¥)œgµ;…†”ÍãÉHnwÅk9ékn=Œ¼YêîH°6÷3ùÏø4 Œª½õº«kô¾˜{pÐwé"²½à³è³óŸ«ý]ÈÖµîq{¤—$’Hãܲ…j›Ô-Çn<ÞnõpÛ·k¥›vnÝ»ü&å'×uõ°€t†5 5»¿¨À´(ÄÜ×A/&ZÐK[ûÏgó{“»î§sZáCžZû5;Ü!Û~—¦ÍßÛDPA$¹[4–jÐ`?Äøµ'VíI¤ê@à´11Ù@w»×m„ÁkMa€7Ýô¿ª»®:ò möêLûì·OÌD9[=À‘#³?”S:­¢O=‚Õv++ÚêdnÔÇæîú>äQ·Þñî?E¾e*U¹ï¨0Ìî?›ÏýùÍîuþ*åäŠØ.¼ £ãùÉ„/¬+:É€\dÇ›ûÏþBdjyì§ÔêÉ®šyñAsgR˜BðP9ŽØ_ÉÚ]ç¶¡ ^÷°n{´kB´æ— L4@#²‰¬Ds<¦Òm>;-µ•ºÆÔ×l~èN¾›lr¢Ö<1ï9²ñÇò>ŸöUêèÇk¬õ-"óQ 's€ývûßàÔCô/q!²Ì4Nç5Ÿ»îw¹Ök@/€`ÀàG橱…ÚðЬ¶§ÛYï1£”ÅfÃäÐ µH"°—ÿЭTËÆáA3;Hú.ö£µ¡Æ6€ó24ïó’ÇźÛUM.sÁ3ä'ó˜Øö´‡èÈî¸óµË]Î%.3jo¨×Áú- ó-¹[¯ ÒøsO­Ù¤}å8'ƨVAp&ÇkAˆÓÚçsùÊ̾ç8n.ÜfË ’ãḦ“ª:"v;‹v€C%ö÷ëÃþpE¯=£@`£AwäUš©à à#𣨙Ö{ÿY4É4ç»8Ž &äþû£óR­­¥ÎÕÇROúÿšµZÀÚ¶ÒIÜ]´OþgòPP's‡õ[üPQ‹’üxý#Æ¿˜Ïûó• †êI×Ä­œ–óøŸà©YFß{‡»–å9<9/¨sãth »£ó\{òÖ›é{þCº¬úÁt¿A:ư;¢BAh=¢©ï'é!°+×TÀçä³q‡ šçAvÕVç5‡p>Òç6 äÛ›Kí§éöïÜ©l yìƒXceß ‹V6›ß­‡äýVïü *U Åé÷ÝkCX]eŽ oî;v«y.keM¨Ñe‚Çnvã¨ho´Ù_³o³jvQ¼ÀÁ©qòîŠê=GÑ $üLø¥Z£‰lü,ZË)¥íµÍÕÖVùc¥µmÙú/¦ßðŠú”Ñmmt2Í¡íÓ]¦[îö»÷×ÖK’çD’I$†µœ»ú©êĶ÷±»µ†€Ý}Ѥþwò7"( gGÿÑ+h €ƒ·‰óW1èû‹Cžáìiíü´Zñàî"\~‹Q…s Çé»ÿ"µLœêZ¶KFâã;ߤ?×z·E<0¨¤¼5åÁ°~‹AÖš°ÆÃ[«’ŽS葪k#ÚÝIEe`5&2<Éå6fL‚(öw(vU‚k¸ÌOd”b纟Î#_ÍAñ(7a¼VÛ¬×mÔI#ÄJÑ{[¨ï2|>«qçòO+ \k©q2íü?ó%YÔk%²?5¼kÙån?5Ò$Ãg];»ù*µ´@=Ïç(˜[D9V¾áAÇÜK7—–éˆÙÿReqúGû‰Î?¼ýÅÞïÌZnÆ Þ?ªÕâ9ÎÞñ¯`{l+W>Œwú‚ÇÖî‚5ãù(Œ£Ô;@†J¾1÷­ú=ÏŠ3q­º2JAZµN=Nml¨>#ß jéwÑþNÔfc6¶Ì¯€WªÇ 0|uü]ŒÍ¬;„‘®‡Û«½¼&®á·7ìûˆ1:{ø)¿ÊÍ~Ç6ZÙ]~š¶êû_ħs\àÐâ]´ äù¿ÔþJIÿÒè½9&O(µÓØfÖ 5îQšÍ¢%_3ið¬Æl€ÑîñV)­¡ÂIÔ‰0cd–ˆŸ(¡»tî£2\"¢Ö‚`˜Ö '8j~mu1„ѯñR> D$Ša´DøzfîcƒšKHâ!4#j¤€I!³R«:‘ôò ù¯@HÓ²«’œ%KL\óA{·;R8'RO·4žÕªñ¯Á3ê ÁÎÆ·¦)AÇåG®ÿ_¹¬ƒ¢˜d&™.D+•-“#§h‡ Ó%Ü-oL!–ÉÓåýêÓÛ0Aì?Љdh5'’—¸_ÿÓíšÈø¢5‘ñ(ž_R бÄÁ³[Ȧ֧kâ8@”ÓâTO‚™ @hóJÕL`4&üªE¦d÷Ô$]1ÀR´RÒH‰Òe;@˜>"tJ?ÑãæRU1p…IÑJ#SòKX3ß²VªDZ{èT\KÉ$ø¢2"gŽ|R Ž51$„m\,a@˜ÓÉ Ù> ^@¯Š¤£°ÿrDvïD uÖ>ôƒ~hZiÍ<Ήz@w™îŽÖ€A"S´LÄÌ8“OÿÔô`ÈÖÒ Ôе-‰Z©Ø£¶L”m‰lJÑH RÛà³DÛ!U"Û¶O‘v%´÷ì•«…û*.i?4bÙKbVªA²>)”oM>Ä8“Hvö A°<ÑC!8bVªFâ¦Öóª˜jpÔ-4À5H6ÀOZŸÿÕõH m ÒILv„¶©$’˜íKj’I)ŽÔ¶©$Š˜mKjšI)†Ä¶)¤’˜mKjšI)†ÔûT’ALa<'I%- 'I%?ÿÙ8BIM!SAdobe PhotoshopAdobe Photoshop CS8BIMÿáhttp://ns.adobe.com/xap/1.0/ 4294967295 1600 1064 1 72/1 72/1 2 2009-02-17T05:58:15+08:00 2009-02-17T05:58:15+08:00 2009-02-17T05:58:15+08:00 Adobe Photoshop CS Windows adobe:docid:photoshop:be22d98d-fc74-11dd-9d91-92538dbd3cac image/jpeg ÿÛC      ÿÛC  ÿÀª€"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?îÕÿµ'h`ÌvñœÉ'rÄöºÒjz²…ÖÀ*¯óþžÝÏÃéí¾ Eâ‹]SEû#j‡KxºQ³y”ÇýÓëý+ˆÔõÓ#0DCÜH2OPƒÔçüž¾‚¿£ãV3¿+½¾gáne¾¥]z÷sQ†G-žŸ·ó¬ÒRÒ!4 ä ¢79ÿhÿAÿ×§RŒÒœ¯Q¸s!õ>ÞƒüŒ‹ëöºÉ!>Ã<ÿúÿ•6bˆõ ¶¹»’Y‰Ç¨ÿëÿ*,ì:;€Åº{ÿõ©Ö6†r$‘rAÓ?ýjµ)€bP÷ ÙG©ôÕ-7ÐÈÖn“ÊŒ•†zp£Ôû?¥Q³ÒúU†%,òOñó÷·ó­tï>A˜ÈrI3õ?ìûw­€[Ã$Q7&âp3öF?/ÐqÖlW5´)‹h´ûwŠ'ÄIþ¾|rçû£×Óÿ­T®íMä h‡ü±ÞúzžÕrîî™V;yÄqýÄN=Ï•SŽÏU‚ò9-,ï„‘ÿ·vLc}*%+u. õ5>Aý­ñ*8T>ÇtO¶!ë^u{x`T‚2O&U9ô¯­¿b_ØÿÄ?ü_6»¢Ù¾Ÿimksoq ñ0Ù+ÄÊ gBOáÓ§'À¾*|ñÀ_]øvÿO¼ŸYŒb{¸ vPÿgOñ7à=kʆ6”±¥.d–·= a§1¨Ö—zýÇž]iÏ¢’ÂIšVG`r€Ð{ŸSþLVúi‘‚ Én¼qõúŸJì›Á7±øÊAct¦KùcÁ…€F‡Ó§ó®k_•ôØžŽaž$}¤>ƒÚ»©Ù«¶sJûš„¨ ·€åGßïõ©#”$^Z1Ž5ûÏÔÿõɪé•ÜÀƤ÷ÏÿZ¶<=á ¼C*æKXa^~yBî}MR‘-YBÚ«„$Ãk9aÉQëïŸÖ¤Õ,ÓýT$j»ƒŽU”žùÿëz㲃áÛÞF!ƒTðõ¼i÷Œº”isï]ÿìñû(¿Ç_‰_ƒî¼MáX4ÍBSûÛ}Z)n­Û&5þ"ØåO稊؊tbç7¢ÜªTgRJ1[žWñ{@y¾3ë¶1G!H®ö€˜ÉùTÿŸÿP¬¢š -ä]ZDýcÛ´Xcè29Ÿä××ðQØÕ>|^¹‡Gñ/‡•|H¦êáõ E-爫墟á=IêOó®…à+?‡Þ&Ò﵉ü1®YYÝÇ-ζ‘ýª%`^-ëÊ—\ÃîçÖ¹pXªU°ñ«t×ÌßBtëJ[3×?bÑð:ÆßÅéñ”mçû4HÁŠ.žÈ¿»÷¸Îvó¾¼CYo=äé·ÄÑ*¤’Ô†R2ª»+ŒmãǯãgH×þ,xÇXÐ4«/ hzÅ¥ÒéúDZ‡Û?³áhÔ,{Ï-Ð: ã ®?NÓ§ÔÌV€,‹Üêžyï“Ï×ò;a0ÏÚJ­ß½mÛM—뮬Ï[ÜP²ÒúÛë¡aä‡P™Ò+•Ž?õQ¹V?¼ØŸnÿÎÃY¥”%Øï'œ“’ÞçÛùý:ëÛè±hÖœá‰É$õ“Üûúºg8Z¥Ãj39 ¶å¤=ùýŸ®—*<Õ.gägË#]Nv’êzâ®éÚ{܇HÉHÿ嬸Ïà?Ï5>‰á÷Ö$ ƒ²rK@õ>õ·«Í†mÖ(-À*uò¿Úoöéõ¢1êÅ)tF>§"hè°D£í€£“›ÓùϦ¬^µ75ËýÕ‘ì=ÿÏ×:ÄÜJ “H~AßüÿŸ«¯ ¼¹•‹Ìãîõóùÿ:Bk¡wĺ&¯§›+½jÃP±‡SƒíVFx%ºˆž"ÃçRˆdVS\4ò†l¼*ƒ€=¾•ÐüAø³â_‰––¿­^ëx^ÄiºbNT‹ qÝ.ÏAÉÉàsÅsÖv¯{&  |ÍÙEE7>_}+ù]ŠšýͼÇý¡ŽUy=ÏùíQlÂùŒI ÷}[ߨUÔ³O%\©0tE'r:Ÿe÷ÿëUKóÌU@‘ä8qŸð´l‹•É2F}‡zŠýÌk· ±ïÙGô­´û ûó7SÐ/ÓÒ±5yÓd±' q÷¥g&\7(É iA0ÓïóÚ¥‚/,A\e›Ûüþu=ŽŒÎ|–aÏ ÿë:í¾ÜxßâˆÖž!½ð¢ÚO¾=TŽéîv~äåˆuÁôê2%É;7n‹sh.i(ÞÞ§ij.$ódÇ–¿t÷ªΦú¤ÆÞËûǦÿþµ[¼y/[ȇpQ÷qíõþU*é«a4¯ÆÏoóíJN⎚˜ÆÌ[€Š»¤níõúU¨´ÁaçÜÒ1Á#ïè=ÿ—Öµ¢Ò—NŒË&ZCÔãœúå×­T¹ŽI§( y„`‘Ò!è=ýê,_1•4/#²®7ôf^Dcû«ïïU®öY§—Sœâµ.ÂØÂQ úÕ }2KË’ªüüÇûžß_åXÉô6¦º²•¶ž÷2íõù§·ùéZvšb²\%ºpÎ8,}hZi å˜ãù N$qÆ}‡ùÿëWÔîd  %¬|(òÓÿ­üê-©nwÑÚ•ÒË!BÀƒ £€ßýoçYR–™Ã°9Îzóþ5r}×’† …Ž´¦ÝaF,@r}=…g4iŒÇ·£cãaߨR[[ó##¬}øÕ¥¶mF]î @‡h¹ôþ¦¥¸qn <è肹¤Í¢Šw2ˆ8àÉŒ tQéU£C,€p9 $ÙLpYÛõ§AlÓüª0§©Ç_jÅÄÑ0y ..vÓAµpOr­[„T`c¯j©zÆCäÆ 3u52·);•'”¼‚8ÆãüÏùÿ=ª+¶¨AÃ1ïŸóÅ\–5°Œ¨Ávê}jªÚ´Ï¸‚Xþ8¬$ÍR)ÇnÒÉœåéVE°02êÞ•um<… cwR}?úõ ‘‚cy×ÜÔ´2‹ÆW À(ÇÊó5^YX$nfè;šžòà8;‰ýúÕVÅX³[¹ô©`‚Þ-¤³Ìy'°ªž¤n˜Ç+ê{µX¾•çÄQôêÇÓüúUg‹È8À2°Ï=Þ¢O¢.+«(\†F£-ù –ÑrJŽÝØÖ‹[%¬E˜§’{½fÜ+^HÁ>êúÖm[VUîÊg7d•O òãVV\*œ|£¨AëþµrÛNò—Í”($|ªyzÿõ»ý*­ë ÉfÉN ÷ýϵ+w}0óßq ªƒÕ½ÍH#f] }î=?ÃùÕ«{—ž@Õ=¶žæa–?Ž}ÍoXÆr+¤M·'$·8?ÅîjXíJÍ’ÍÈÏosþr;CÌÈÏó5 ôÂ#%Hä“Ô{ýkU¬Îýãöxðþ#xæþÃǾ;?t{}*êî Dé¯ö‹´Pb¶Úœƒ!Ï>Øêk‰Òóå$²€§w=*…¸ÊòzzÓ±µkÖÎ Æ}ª©Eó9_ä)Ér¥bÏÚ$»b™å¿Ïùþu* \Fœm嘟»ÿ×§ˆü±åF`9=zÔ±[$Qp| xþô­þ*íŒ{œÍ‘«wF{¹ô«6vk\ݨ½‡Eÿd{ÔÖZ[«£±P`z ô¦«j­}8Eû‰œ§Þ´JÚ²è‚æôÎሠ‹÷S è2\;a¹°÷ú{TpZ´­ÆIëÈýkOKÑÛS•”¶éÌ’z´‚m‘6‘ö¥ÍÒh±Ð$—³üì¤ú?¥hA§ø:Oƒ7Ú骦¦‰›ö\ÚÜÚm¥i{Ùã=‡9®.Kï´4…¤,„æY åÏ öÿ?\ëíPÝ19+tËZô*BöÕ­o§åèÿ¦pÒÒú_úüË7ú£]JÎÄ„^ƒßü•Gaj×N®Àìþéš­c _È)À\òÏ­oñ‰~Uy\~í3€©ôõª°ïmö4]Š­;•O@?¼}·åEãªæ_0üÍÞfôã ú}*[‰À.~w=d>žÃéôëQ‡a#F…D¸ùäè!Ÿ_åRÐ'Ø‘ÛïŽ' &?}7Aþè÷ÇåÒ ›Ä0Kyæ†8ÏÊÁÿxûÿ*¯yz¦5†¶1Èå¿Ú?áTšc…=zŸ_¥Kª.)­M5ø¯[¶ÚµüXî²{Ô“|uñŽœëoiâU®$;T+ääöu¬+ÙMœ^\JZgãŸýzf‘ ßH_ìÑžA‡˜:‚€ÿ õ=ÍrÕ§O¬WÜŽŠsŸv}sû~ßþ$øGâ)ü5©Ý\x’K˜'¹’wue¶dœD¿Þ9ŸÃ¶kɾ:~Ô~6øáâ[ézÞ£ek>k(ÜfÌþ\©õþ•û:ü2Öí~!C,v/Øî“>t}áq½U´ƒ>6ðÔètý'i€ŽukÈJ§œ¿ëÛô¯žK:Ö3K{k½ÏFX¼LèÆ•Ý®ûùxÏâÿ‰m>iÓQ’iµ«ˆ%—Ì倅Ñ^M7‰u­RÜßj:•ó[±)k†U}‡sÛëÓïÿÁ'o ý“lµïdžîÊîMcû—áÙ£Æ>8ñ5—‡4 ïuKÒ|¨Vâ [%‰Ý€öãØ?Å_µŸø†ïD¼±–ÎöÂv·º‰Ê–ŽE$08'œçüäŸnJ)òFI¾×W<¹Æ£\òM/C“[)5‹µµµV*'‚[ÿ¯Œû~'Z nO*Å¡\=µì_4Ú„-µãÿb6ê«uo§ -Ä"Ê´¶* ŒK6s‘ÜgÓùŸlÅ´z¦÷Pe?q\ã;¿R3Ó©­];èÌÔÚØìÿiO\ë_¼@ÚíåΠM×ú+ÊÛä²;•ÏcÝzÏÞÅxõõ“ÚÜ+Ìk‰HòQ9èßOOÌóÅuÿ.£ãíRþ`óIuqû˜‡&Cú>¦©è~º¾º1ŒÍy/.ýE¸ôý?®Xz<´ãéd+U¼äßvføoÃóÏ|ñF|Ë™”¤²db0GAïþ}3Üéރö!Bœž¤ž\ÿ‡ÿ\zšÞÑü)oá7nÐqÕº=ýñŸóœ‘®Ý>­3ǪÀ ùŽxU!ÓôúvÆ ;2¨æüŒ-jåµ)U‚@œ»ž˜ÓÿÕÓ4Í ÂÒx‚på 6q|ãpÇü ¿ ÿ#gBð«ø–áB©ŽÆ#¸oã~?½ ®»VkéˆÏÑFFÿ¦éì;}q†—qJ¥½ÔsÚÄðxBÈ"([’37Xøûíþ×·o¯N ÖY5ív5PÒ™[ cïœu>Õ>»©\x“Sxa/3Hß3cïŸðØü5ð¢hþ%Óà(&¾º-…=°­’}ÿ=ê*KÝo±¥4¢ÒêÎSì'KUR¢k釲Síüê+‹cbT—¸šGoàÿëöÇù;WGN/’$»“æ‘ØpžçÓéÛëPiúšÀŽ0@%˜tÿhûûV–3æ1ì4Y5+ˆ ¢òÌ{{ŸóïZðéQ›`âÍNtk¦~Š;šÜƒE‰m‚ª•²FÁÇ tÝÔ{zž˜öëOT‘¦”* yäDNÂ=ÿ<ôvêKÙ…ª;\M±Fùd;T/ö€žjX´±¤ÇÎÙ.¤°ão°ôüúVä Ñc,ø’öa‚GDÝ•…®]üÍgqo¾Þ¾ÃÛùõ¡¡ÅßDcj3‚YîÝÃÆ}‡·ÿ® °ÑK¸fPÌG€zý?kéÚ“¸,¹' íÿê÷ïF±:YÄaˆ’Ç ¬ùnîÍTú##S•bSg+üMýãPçH̨ «ž?€z}•iÚhÒT²Ÿ=ºùä?ø¯åZ‹¥®E]Ò¿Îj\o¸Ô¬c&šº|*ˆ¡¤nê;’¶(f˜’ç#¨ôßÿÖknßE1›‰ð±Ï]¾€çÐ~'µT½G’Pm•z¢{û±¦ã`S»1/å˜*€²Qþ¤Õ+Кl^Z¸uöÿëÖÍñM&«Ì‡©Ï9ÿåYØKvT´¬ïþ>ÕÏS²ÜÚ ©ÐXü9ð®£ð&ç_o4~;XK(¼2,‡³)“uçýÐAãolzóXZ~ˆ¬gdñ,€uö¦µ´ï 410T_õóc8ÿdzšƒVž9a0ÄvpñÇü´=Àþ¦°§EÆîM»úiåéëvk:¼ÖIZÆN©r“FQŠÖ0@ýïo§©ïX—™¹mÍ•E8UÆ3þNkNì›™70Ú‹ÑG§ùÇÖ¢kp›™ˆR½OdŸZ™0Ûù`’pGR?‡ØUf¶7ìKFppy'Ð{ÿ*Ð0›Ç=c‚3‚@çè=ÿ•-ÎÛ8Ô• Tb4rÔw: Š'ìè>PTm›tÂ.í–nM^¹ùI! žyã½W¶±{郲ÊŒt÷>õ‹F©”ììå˶@?h¤5 ª3ïW–ÈBTdŸÊª]?Hãù™ºŸZM[p½È`±ºÖoá±Óí§»»¹p‘Å m$’±ìª9'ØT7–- É4Ç$7Q1IRE(èÀà©Aê+³ø/ñkZý>'è¾1ðÜÖðëÚ ÿhµyáG¸©R ž †#µdüKñæ«ñ“â6µâ­rH§Ö$áõÖ©yàhîÈÒn5Ûu,8xÞÜFHšà§SrÙ`B/E¥x©ZÀôv¾Æ}Â5ãî`Bº¾µ=¶œ#S$¸ÉäüþŸþ¯ZЂÈ'ï$=}þ•^ç7'$ƒ§mÆ’‡V7.ˆÏ»&à–l„÷¯Ò¡ŠÄÜIæH2:…é»ßè+E- ìÙž÷¿úÕè> ðµO>2×µÏ\é>4ÒgµM@]9å\ß;L8`çÐuÈ¥$–¬iôG›}™QK¹O¯ÿúÔ‹¥O¨Jk`çî,—1 _™…Ms—pì9?u:ãßüÿúàK2ìs’Ç©ÏJÙÇ¢2rîlè µ‰îkkÏG"sº]vÅ=A(È# ƒÆ+êÿ†ŸðL cÇ?°'Œ~#Çâ YYÛêV×­¦Ç«[J¡mVå$Œ] LI¼Ì¥wœ¨ØøöÞÒÙ”°9`¸ÞÿìLúô‡€}'Þ=Ö´ßÞ(Ó¡Ô.í,_[Ó XE+ P¢+àÈc'k)ãvàw½’I¬+ЪÒörKU}:_ÔÒJi¾u}_#šÕ~ kD/.Ém»Ê‡É×lžÀÎÅ"S’Éä“’NI&±nq¨Ü¬+…`XŒçéÞ»)Fv|öÿýÜÕn¹J:„ÿgÈ §®=ÿÏø ïn4Oƒ×?±»jG]ñ2üm]tD4¡n³FŸŸ¿»Ý·œîÎî1Œ×˜^JÓ¾ÐHç<ósïíW´5Ãne*‹Ôúõÿ•)ÓuIµg}:ùz2PMµ{ÿW!Ñ4G¹!˜Eÿ8¹äˆvÅÄp;(õ5h@ UŽ5Ë öÔÔÖö)m#“³?3c™ ¯B>S’R¹RD†ϸÆ9'ø¤5nÓN ºæäª$}hÇ õ5vÏK2srDQÄ2éþ¦¨j·Í¨J±Æ Äœ¢ú´}ëe•Ùï¢+jwï¨JdiÂ/e÷>ôË[ÌT¶y翹©íìKª71ç'ø½þ•©¥h²jS˜aÀAþ¶NÃÚªrwb”’DVŒÚœÆ(جJ{'¯°­¸íchh<«z‘ÁŽÕb+8ÚÜA1ÙC÷Û¼‡ÐUJìêy0b8c@ÈAýOùúöF*(æ”›g¼]êhW+ ~_ZŽÒ6Ô%RA©ÀÏÿ^©[fþP"5?‹õë¢ÒíÖÞ5fUbÜ*v>¿‡©ïüú¼Ì^š¬ [H•І‘‡îÓ·Ôÿ²:ûÔwwÁÉrÌÇç~î} þ_ZŠïQXÖ}Ì~ûçößç­e½ëÜʪ˜ ØvŒzý—ëRÕØ’ê^ûC¼Åâ\rz‡øÿ*¯w|±Æ!„½IîçÔû{U[‹Õ<˜rÀýãÝÏøTP¡”Gsëÿ֤ʌz“¦eb,?ˆŸóÒ–æqb›T“!ïéÿ×þT²Ì¶H~ótõúÕXÐÌç“ÏSŒÿúê_‘e Ìä’Nzž¦¯iº<ú­ôV–ò\Ý\8Š(¢Bï#€ª$“ÇiÑ[;¸Ž5%ÏýjØÒµ»‡Ú®¡¦ÜÉi«XÌ—ÝDpöò)Jÿ´“‹³¶áu{2ö…kqðÓÆ³Ù_[\Øêv‘O ÜWå·o)¾B¬ ÏCþàôÛfQ¨j&E²Œâ(Qˆ’忸¾ƒ¡fíõÀ®Äž:Õ~!xîûÄž!¿¹Ôõ]MÞ[«‰Hó.¦;:ÐpªN‰>»v’J«…Pª£„‰Gaè=OsïX(ÊO]•íú¹F+M®÷>ÚÓÇþ*ý–´­&òþ)tùõYì§€)Uke‰ ðOÍ׿Zò]GBƒL>ÂZK9:3à2êþ„vìGå]\Ñ¥ÁÝ:Í0 j“¹ÏòÉ9>‚¸ö¸–{†¶µA/ðpÿ_¡éïïÒpXZt½œR»{uÔœN&uZçw²D>ñF¯áoZÞøsP½ÒõKG-嫘æŽA PHǿ֢ծf¾»¹Ìò]Þ^;Kyu+ïyYŽX–=rzžý:u¿%¤ztfÒÓçwÈ’Cü>£üOà8Í g•l%of!‘Xd¹=ä=³À®Õ~kjsºŽÜ½?­L§µ‹F¶¸%ÈÌhFXŸïëè?X×€Éþ“r­)â(‡&Sž>£Çè+§×<-©ézež±ªé×ðXê µ‹Ë ª_€@>[‡ÆHëô¦èž¹¼Ô4fMFnpVÕ}>¿áè)Å©lÄß.æu¯†n5mng!eÔn[,ÝVÝ}xÎ;þ=:û×ÂÏÙÃOo‚¾'ñDž"Òtû¯2ìùØ‹D±çaÏ©Ç~AèzcxkÁ0ø^À3å¤n]ÏÞs×ýÇ®1^ÇPÒõoé–úÀ»Ü ÔMžÕmÃ0G»€ÛsÏo®*+F\Ÿ»vµžŠ÷Ku¯}ŒáUJ~úº~vßgòÜä*×.|Oª4;K$¤ùœî>ƒÛüýw¼gâ[¯jo»´ÒÎÀ;ƒ×=‡·ùö­¯x>Ø,²§?ú¨Ç~ý{ÎOÿ¬]‚>â»ÜÉѼ„ô¡ˆ;ŸëÈê> èæ/ŠšRHD·×.ììF`FÜûØvúôŽÞ)´ ¡tXI©È7d®zŽÊcþzßìû<êß¾)Øêº ¸–.æõdyNc`õSžnüôäÆ×…Geg©¾œªÖŒb®î¿3çkO˪ê- Jć9' õûÇúë^ŸðcötÖ~3øÆß¾·Š{éÑÝÄ“,"]‹–]Ç€q×3Zèügðzïà–«q¥jP´Z‚12H£=IÀOW?øèçÞ¸ÛzóBÔc¸°¸º±»‹÷pµ¤ˆQ‡<÷=ÿ*×ÚJ­'* j´oUëm4ù™4¡QFªz=VÏþæ|a§ÜèºÕΟ<";ËIšÑ ŒîèÅLkŽÀŽOãèv~fYBË}02#ÝþuÒXxwû7WGÎÔgá@;¼¼’p3Üú÷äôɬ/߈ÖHуÊßë…ö矠®„Þ† §±Ìë×XÝlÛï°çð皥§xqîeVd,Í£9ϯ?Ì×eyð£ZÐ-4ûÝ_J¿°¶Õâ3ؽÄF4»NîŒx#‘“Ø~°^[•¸‡N±)%ÝÛ¤!Á 73Uô#éׯD¥.dîÓå¶§/­ÏCÉ gØŸÖ³ì4ZuwB'` ©êAîÚ=‡jô³gˆÿgψáÿÁhšÂÁÌqÛL."D|®HêÝF;c¿|ø4Ñ­÷:™'sÀ’IéîÏJŠUaV ¥7tõMl]HÊ”œ$¬ÖéœÜ::iP‚W|ÏÀä“éþúõrÏ@‘5ÍÁÈÎqƒ·ý½qž•ÒXxh[+]Ý• <ò¨¿×ÿf#Ò©ê¦IæP¨D–Ž6äÆü´ö¥Y›“9­DI-ª®&<¢D ÿz±ý*† ‘é§tÇ’zŸ¯ùúýzAE„óºgä“ÉÏ\óßÿÖ}ùÓa6£t‚ò¹Èœ{žýz¦¦O±­=wØÃ[¯îª–‘úqƒ±#ùÄÖî“á±0ÂÁBs<çžÃÔŸóÇ]Ý#ÂÍh! 8§œò"žìÏbÖfŒDm-AŠÊC¿w=OÔúžÕš…µ4uo¢05‰c’#oÙCÃà¹î3ëê{W9¨7Ú2ØÙpª3éÇùÇצæ ßj9 G”ŒãüÿSÍT’Ì«o`Ôqéõúÿ*Îjæ°v1^ÔÆIqµ—®xòÿúõEã:‹•Rc·ï7ùêOéZw1}ºB‘D~w#'ÿ®OaLºE³µÜ¨?v•=ýO¹®Y»0(\µ@€ G\{ýk6çÒIÉ#׊ô?ŽÞð?†õí0xÄš§‰¬.4«yï翲û#Û^°>l*•p9÷ÆOZàb±}N`̤§ð_z㌹⤓Wî­øMr¶›(Abú„ÁØTtüMjGf-ã ¼±ïëW–Ä[®ÕÉcU5 _»Œo‘¸â©ÂÊìJWÑ÷òmsc,ÝO¯ùÿ>ñýl”–$ÊzŸOj¼¶ƒM„»ó3þŸJ¦Ñ´íœg=¬esX¢¡‰¦rH=XŽÔD0ycÜŠ»¶PXfCÐÞçÚ¢tÉO^…ÍB…‡ÌTxÁÉ<®¬ýFè®UXðxéW¯¦+ò® *©§;›ŽFzzÊo[#H¾¬£‰ûÌo|=Ïùçó¦Ì pŠ'ž{ûš¿2’¨$Ÿ_çQýœ[ œ;·næ²hµ.çSðƒáO‡ü{¡xÆë[ñÆ“á Ïi ¨i–·¶ï+ë÷àZÅ´ü¬xäçï0 :ZžB#æ>¾ßç­]K`¡ÎIûÍÛè*•ä†ì€¯AÓuf Óm¿‘|÷²HϺ&õú‰~èMIm§IøW¦Ïùæ¯ÚéÁ€wÐtÏùõþµæg$ ˆÇ>ƒØSåêÅ~ˆÎ¹oµ1ÁÄcŽ7ŸO¥C™¸`Jü§…ø½…hEdnˆ$b1Àø½‡µ]K³€p}1è=¿ ̬fǧ¨ˆÈäÀíÎïaíüê¥áóH‘× ýÄþ§üÿSZ—Œd!ÜaGÜO_sUM£4›˜eä+EˆÏ˜Î[7’BÇ%ÉÏ<ãÿ¯þ~„]©Ðu=kAãòÁQÉ=j[ <« \ð§øý¿ÏJÒ4‰s¹Ÿk¦n*Î ð3ÖºÿXÿd7ˆô÷È_íXð½7yh_Èo¨íü3½ ¼Œ3Ú<ЇÖ6ÏÜoAèÝþ¹㆜m~-xÅ ímu{…’B÷µ@îO8_©|7¹ðû/‡¦co©Z[l½¿ó;ÎÝñŸ}ǯ皽ḔìRåTœã¾Iïþ}€~‰áƽ”±È@w3‚?úþÝ«:”•YGM×äTj8'®å-Ãtû›*ƒ’ǯÿ¯ùWEöu·DŽ4è«ýM_[E³‰b9è¨:ŸsSYéAVIdb}÷õö知zè¨èrN§1BÛNXây$'gñ69aW¬tŸ<‹‰À††UOD§Þ´´ýÞ´N¢("EcÂïzÎ×u3¨:Ãn¬°¯ÝSÕÿÚoð­”RWfMßC«øJŸüI7‰âñö©âm"]i|:º=ªÏö½HcÊKÙÛõãê;ù奉*ÌÃ-èOøŸ­ÈlB .ÏÕ¿½ÿÖ­-7D’þäÛ[ó!ÿXøáEM:MÍɶïÓ·¡R¨”TRÛúÔë?g¯‡~ ñÞ³¯Úx×Åš—„íìôiî´ë‹M8ÞÛåÇ•nÀ}ÅlžO§QX¶¶-¼ CmýôŸÞ=Àü?å¥m¥GmnÖ¶ä$¯›?x÷ÿŸðËÕõ{ µ´SiÇNÜû×]:\ɻߧù~§4ªs$’ÛúÔ¥ª^¶¡(¶¶PÇÁôQþ?çÖY-¬B5R@퟼}O·óéW ±K+\€88>§ƒþÏ6ìôñï¥8äü<Ÿ§ç]ƒ½Ù‹ŸcÕô»Q«2亽ÿ[ÔÕ«­HB†$‘ó7AôÕBm@B‡#æ?Óéüë6âù§(ÉcÑOosZßRä×ïu*ªç?¾žæ›-à·O.3¹˜üÇ»õ¿Q{±oDùºŸ_j[d2±<õ=¾”2ùz–àS! “Ôö«bA ¼±éêjÈ@ãÔUˆ`'©ù»ŸJ†SÐdp–''©ôÿëÕ˜­ØÈ±Ä¤±ì;õécS½cIrx·ÿ^µí­SD·ÏÊ× 9'¢š‰›©ØbŇlBnù›ìÿëÖ%̆rÎÄ„ñ5röo<—s„Sõ,jM#E“R™Y”ü+è?ÏzM\qÑ]èzšÊ±\(àÃüú׬x¹<ƒü/†tÝbÏX‚É—_šòexnî7 ¯å@7qÇQÇž{MÓÊžøÆïðçÖ¢¿îUâ·›xVnƒ¹ü¸ÿÙ4*Xb$*V œîMküIÒ|/ øÛUO ^Ᶎ–Qö ‹ø„w)´dº€8 8°8íJ2´¹,õ»ÛMû÷Ô—¬y¯ÙyýÝŽN+(´Ëa,€6pTwö8ôôþ˜¬ë±ö‚×7eš<áW©sè?©ïÓ¥j]/ÚYînXˆÆp;±þè÷=Ïà;šÐÑ<3=åäsIk·ÿx†é¸ã¿ÿ¨z¬gÍmYµ¯üOñ‡Å xcúíòßZx^&‹H´*‹`Y”̀Ϧ=Hè<-à‹ X™$!¥~YÏÞcǯùéì+WÂ^ ‡ÃöM4Ùi™à–?çðü0 ë2jw&ÖÔÇ· öÿëþ58F ’šIyyêÉ«ZuæïÿÇñ&¥&«pm­Çå%Nãôǯo­t¾ ñ†ŸwðG[ðXðž™{>«yÂëò\Æ‚Qxûœœà†<øzG†[ÛÁÿíÄÒŽ³Ÿî¯û#¹ïù×wi¢éþÒ–Yîm¢B>EdoÞŸNݯӪ¯I(É^Í5¾ëm…J¤¡~N©®›?S,¬¼)¤«Jw D­À”öÏ¢>§Ž¼>‹­^x›âºX írñ] N3´‹iüþ•­âó‹5…|O¥Å<§knŠá¶AˆÿÏòúöý“ü1â_Ow­ø’ÆúïOÒÜÀ$‰•d”«UÜ$LØŘc©á°ó«Rûväv`0s­Z0®ßt|»à_ ?ƒ´¤»˜£Ü°€œž€g¿ÿ\ð+¥Ðµ~MZÖÞÌ‹ÍcS• ¶`BK1TdtÉ'°‰ñká>àïj6ø§I–+)LV±¤û3ÅQHç'±—V»c<’ýÕ ‘שöþfº ÁínÆy¹aºy›‘>¾çÓðõ5Òh^ kg0ņ¼nšVû°Sïíÿ×£X1Á XX–ŽÎgŸø™±ú±ý-.T§Ðæµ¹#в³&+XOïeÈÜíŽyîÇò¹I–èaBÇm Cþzûõ>ý«‹±±ŽÖ!ÎAÿ¯~½:çIbX†e(§ø?Ú>ýÀÿë . Á{"Ⲍ€zF=O½cßÔdhca Ì’ƒÜý{õ·©Ô%h `±¯Í,§=ϯ°ïüêËm´ˆ+|ʬrÒï7©?ýjæ¨ï¡×OÌÈž$¶·@dCýZub¼}I¬Ë´2±–VÆ:JÓ»/q+Jà€zJ –ªÎª1gýÿþµsI1}LijmF@qˆÇ@‹ßéþ~ºÖöKh¤(ËýëV-,YÄp7Hßÿ?¥QÔ%û"”CºVãŽ1íþýK’ÚJú#7PŸË&8Îé‚GoaP¥šØ‚ïƒ)çýÚ½Óã2Ê”ú»ÿת’!¹lHnÕ„Ó6‡‘žð=䛈OzÕ»}=mÀb79ïÓÿÕ^«À¿Aû/'ŽÛÆúSx™õ_ìñá]˜ºgvsœcæéŒwÍy¬‹•''hêG½…aI©ÞݶkUëÿ m4ãdú«”&€KÄíþ#Ýý«7RŸUpàÊ=+CTºû:m\?øè¬øl™ðÍ“ž™ã>þÀR’ìîRKbH$ryçùšI€Î}±š¹0í${cwùô¦Äcqä·JÍÄ»•L~W$nvíëL[lÎA=Ïô«~I9f8#©=ª¬ìg%Tƒ‚}MK•ÆÊwYº!+þmKžo`6Ž€qWa³ 0ÂŽ%Á¸8$!QÈÞ¬®{hŠwDJ à‘ߨUd´7L #^˜ïì*ð·óÉÚ‹ÇÿZ¬%¦±Â¨ü‡°¤ ä>{- ±Z(˜‹ù¥CsûÀ‡Ê>êtÝWgQ ÉF:Z„Û´²d“Ðt«q¶Ä'Ü mYØ1cøK P-ô+8”ÛÎòñælÈÝ·\Ö5§¼¸‚1•Ž&ÌqƒÀädû““ì:é|i>¯ñ¿ÅwQ•1]ê—&@Ã)*™IÁǧ|àõÁ<–&5Sw³V»¶ëñ:£‰å¢é´·¾ÈöÓ|5ªÎßeÐõ«p9f›VI6ûÿ¨€üjäÖÖ–±ím§@8E2†f>§åçôÕÔt¸4i^¶†Â©å‰Ïsßžÿþ¡kÃÞk›=RâF\ÛÛ $~Ê<Ø×þúüM{¨¨#ΩQɘš@å•À™Ž°öþu¡§è¦ù–YWÊ‚²#`?¼Õ§§hçRuvQ¼_2«pûMT¼G« ²-m0gñ›Üú-t(ÛVc{»"†¹¨¶©m,6êL•ÀÆ §?xûzVu¦”|©vò 7Lå±ùŸS]&‰ 1ð¶±"©y#0†`=XŒAêȽá ½î¬Çn¡î!†&fÇ ª¿×¥JÕ»÷ÿ!·mÍiÚ,·wÞÝwJøÞýžÕÓYi1éöæÖÙ¶¢¯ŸÔ÷õõ?ähØè‰¦BÖ¶äŒÜOéíŸ\V^½©"ÆÈm*9aÐ{Ÿóú×daÊ®ÎiIÈÌ×uq ²´P‘§^Á}ÏùýzCm§¥…¿ÏRIäŸ_óÒ®ÛiÉa'¹c€Xúÿž•«£øxêgq\cˆñæý?Úôþ¸¬cmY›—DA§èL¾–úe -ÚF Œc(ç'òü>´ÛM:KéÔ*œŸº1÷}Ïøvþ]–›¢>£ðŠêp„m× @ý{Êr›ÿøÓ"0VSþ¸ÿywýãú®›»~¤TvH©<ÌHeÏ!OosUÞc+,Í÷›»}=ªI¹ œ¼ßÞöúU9˜á dôÇÿ^ƒtwŸ ôïë^ ñe–­¦x¯SñµÔ0 (·I7œƒæa°q´‡§ZæàÊüªÇ±ðoâLj~øöÇÄÞÔ_IÖôðëÂÄ’…à©XŽEVi%¸¹–âw2ÜÜ;K$Œ³1Ë1ú’OãXFU$ú;=úìÕ­¢Ñ=÷lº“,{«ôýz½þVb©Î ÇåSI %Ï@:ÿŸå]ïìó¥ü8Öµ­n/ˆÚ¶·¥ZǦHúYÓ¢ókÏáWÀ€ìéZ7öOƒo¥EßwöËxÉïä˜þ|~^–´‡ºž¶HÂK×ã}nƒØ†~x=ó¯rðwìa¬jŸ³.µâÓu§Ej·±\µ§Û"ve‰fFA6ò€`“O^,^:…I¥v’×­ÎŒ>­[¨E»&ÿç¸,RÎÐÍ ­ëÿ-·°ýœ!Ÿ|÷ Ëþg¶¿Ó§jëu¯j¯ WWI§ÁÜǨ[‘€1!ÿ>õWMð}Ä·1Mq@ø÷eFý£‚Éõ5× ‘’ѯ¼å”%ª3t_Ës ÒDL§þ=àÇï|W§ø?Àñ趦â|I#™È'МcÛ­Ïø14¸ÍÉF囯à?Ïÿ^øîå¶ÀŒ¸þœ§ÌùbdÝÌÿë¨\ kPH?.ùŸÿ^v—áæÔØÛÅ“;f”ËCýÅ>ž§½hiz ÞÈÐÆIåžUïþÂÿS]Ž“máí0M:¢@Š6'MþÃÛß½¨¢¬„P¶Óm|-¤ æTò ÿ–žÃý‘ú×›xóÅ·:ö ÑDKJç ˆÇ¦?ÏOÄløçÅ÷íûG&Fá@éÿžÕ7„|n/o¼Œ~U<³±è©<ú¸ª„y}énwƒ<ƒn/oA2±ùFÝÌIìv¬úÞÕ{Gð«}x„8æ;=Ï¿Oÿ]%þ¤lõØcíð:†1ùóø~<¹Ïš. ©v’‘ÉxšüÛ3`ƒpÙÏý2ãüº| ;Ã’_N$u`3ÀÇ,ÇùWK‡Þþä¼™CzrOn=}_ÔÕ<=k±B‚¸õñÿ=:ôª‰.Tgc˜Õš/Z²&ÓrìCÓüÿ.¸mNe¹¸C"1Ý Mÿ-9ûíþÏ·sútš‡X™n®¼LIŠ6ë9ÏÞoöGëú×Waá´Ó¢k‰È27'#òü»ÔåUGÔg5cáØô˜šâã-+s“×?ç íéžÍ;Ã-q!»ºP QIþ¾95Óiþk¹EÍÊ”Uåœm÷>Ÿ^ßSQêådU »¢oõiŒÈîGd…bë6ì‡nç+¬6ÅT2#ÝDF ǦöôQØVV£h´Ó0–æ_˜“üþ™àçÓ¨êoà]"'žr¯q'<ÃòíŽý=Ç©C.±u½ƒI¼©ÝÏ×°Ïà+jnâ±Ëß[Ë«Üîeg.~DÏÞõ'ýŸSø+wCð\–Rˆ£ %ü£s» uÇSéŽÃ·×§M ø1ì¦UTYu¹ÉHTô°þ½,jªšlabä·[›’2Iõǯ¢þ4åVîȦÎ[X1ÙÀú}ƒ0U9¸¸#æfþ¤ö«ŒÕ‚ݧ•ÙÇÔƒþ¼÷¹þ/§^§VÛr†G—kw6r_מùî{ô ÇšÇÏ*Å¡æ8Ïñ´ÞßÏè+X«!Äæ¥°2º¹@æ4#þÛAßô®V•µ žÚÙ” ¥•ºcûÄú?çÒkÓ½ôíijC3 Í3îIì£õéõÌ{­­?‰m£;²Ã pßÞ>ƒÐvúÑ'ÐÒj7áÇÃØ¾ øãFÐ¥¦èvú­ÚÛ­î¥/“o7üµ™»/oĦ¹ÏøoþÏêºl·¶:šiwrÚ‹«7ßms±Šù‘·u dOÖÍú6£!yp±)À^ÇÛüÿ‰¬—±}ZajE¸88þ?aíÇ'üŽiB\÷¾–ÛÏ½ÎØMrÚÚ÷ò2 £ë3 0ÿ‡ó­k}tøÀÀ2?_jܴЗLw(2ž?‡ØU-jé,”Ó8ÇÃíMC—V%RîÈÅÖ.¾Æ¦49•ºã¢óþ}3ã²KæÌ”ôøkV-8Zƒuuƒ)åWsþúÙÓ‡¾“sd‚XLèƒ3¥‰¯dƒÜÕ›m4C†eAý+JÛKò¢"òx ;Óf‹Ì-ÈÚ>óv£’Ú”ê_DfͱÎá›×ØTW:.£>‰w¨Ûi×ÒéÚ{$W7QÀíojÎ~Ewj³v‚kµø3ðŠ÷ãÇÄ« éš–…£ÞêK$w:½ØµµˆGs¹ðy ` u5‰£|QñW†~ëþ ³Öî!ðLj.£›S°‰‘¡¾–v3€UNA€¹ÏËV£æötìÚµü“ðŽšPÓž{ko_êÇ–Wó$äÇãþzQuD Ìü`¿ýjЗ v®Ó¿°öþuÂçaó*\:"“3¾Ê-S|Ÿ3ž‹ëM[C’î@sÉôQéþzUÿ³“!fûÿeª7dÎLiò¢ýæõö¤ãmXÓ¹JêA9Ø™XÇ·Z[k0n`V1éÔû ¹k¦°H"5üIÿ?çŠ.Û*QÕA†# õ¨åêÊæèŠW'Ì%ƒŽƒØUqšx*ñW;à ˆ¾Ý?ÄÕ˜lqÕJ…ÿåK•¶V*CdH$áU:û{}i“aù#lkÐtÝW¦Q Ç!éÆê¯öv¹pH8=J§&SXLîÜç èKö(`±ïžjò[”àe›¯bjK};y,Øuãô¦¡r\Š6Úo™ó°;GëW¢³ Ao•Wþ·Ö®Cd‚¨¾œþZuÛ­²dŒvUíÿ×ÿ#XÂÛäÊ7¬-Ó¢î<ÿ?çò测¶”áNönžÿýaþxë§©Ý4Œ@ÃãŽþßOóÓ¬z7‡ŸR¹€pÜŸLgù3øVR¼‘qÑjgh^}Jà3 ‚A$çßéíßùwš¼q·ˆî¤EÜnnÙø4ŒÏŸëR.“‘h¥Føß£²O¯µhxjÄ\köÏ5¼R»L›‹;,=ü뢹Uú˜Î§3·B¿ˆ<>¶¾/Ô’à•Xå!Üõ#Û×ß×§¡þðŒ—z7ŠÌˆ‹i“Âùù&_¶Û3>±Ûk©ø†4ôø¡­[Éá6âÚ £þ²âé §“¶Q€3^óû*~Ö~ø9ð¯â‹ªü<±¿¹¸Ó…Ð6òÉ2…2ÃÆ3HJî…#î üÝ91ç œ å¶šw^fôiFu\%$·×^ÌøçÅì,-Åœ!™D0=ƒz};wçžÑ1Áß;ðXvöçõéè·šŽc¨7Ùü ‰eYcÔo%SýÒór¸È=y«gá}ν Ï£i:deð²Æ5m3ëºCòúívF­õžŸwùœîÒ:ýåøEõ_…~,{HÄ—Q}—ÌP2#]çæìûVßÿ Gcð÷Æ‘@Û¦†ÒÙæ›®ÜÜ <úãòþ~£ð“໣|ñ|v?Ù먻ڱ›ûBï9ÉÞ@àôé<{W'2Ãá£)U’·4WåìoGZ¼£q{?ÔøQ/u–ö»‚ yÓŠ{}XóøÖTV0Ú!xRy<cïŸò+ÖüuðÄzn£5„6ºM½†Ÿ+Å ^Õ™È8.Ç~K¶2Iéø\Ü_µkCç]Åb±¯ÝQ}ïÃ?ý~•ëÒ¯N~÷2ôºÐóªR”}Û?¸ç´]M—l÷òßÇåV8Q¿X~Ÿ¥tzN‹áFXÌ×¾)QœªÇanG³s/ä?É­/†®®& éB~U+÷8=?ŸÓ®Þ“`4wo(ƒv¼¼Äùîwôôë]ZHçu-¥¯|5àÃö¾šMCQ>57k$ŽÑGý¥öï)¶+w–d1î gž§'“òþŸá%eKkßI+öPg'®{É'©­(ä1ü%¹¶Œ1‘µ¸dP_>D¼ç»rMPš†4ÅQqûÇzÿ½ê{ÿ>,T\Û©'y_^žKMŽŒV.5T-¬­§_7æyÍä¢1µAç€=jµ¼$È™ú –E9ÜÀ´ÐžÕvÂØ[‚톑ù?çһɽ‘¹ð÷Ã6ºÿ‹´2÷T´Ñmµ¸íçÔ.0Y#0 3ãªM[ø‘áÛO|@Õô];Y²ñ¦vöðjV`ˆ/•O 9àýON§­sí1à/ÎíùŸzÛÐô§Æ'˜3 €†…ÏÍ}-·Ÿ~äJk–ÖÖûþ„ú>–4èÄ“ó? vZšêìD…™ŽsÏ©>ƒüñL¹¼X•™˜Žy=Ð{ÿ/¯Jö>¥p®À…Ú£ù ¦ŒÒêÉl­Qœ;© Nk­ÐôuŠ0ì0ŽþÃüóPèZ0PÀU^ø —XÖ¼¡äAÉ?/§°ÿ?ÖŒ¥&Ýí[V9À2Çåùz}?Ïòë>bºTjî<˹~êã;=×üú L°b eeÔŸu;}ëRÖÜ[ƒ4ÌK·Þlóîõ4š&äšu„0šé²‡;ˆûκó?Ï¿e¦øÛV‡án¯d/g´ÓΣh~Ʋl±ùW]™Á Æsשɮ>53¶ùEN@<çò®£Âvqjº–·%«ÜÅ%¿®åY9aÔ®[§n¾Çž¼’æW³_™tjr·gk§ù %÷‡4Ô·dŠf¸òm$ê2ÙôÏãÏ^ÛÁ¾ K(Zêã†7¾:²?Ïõ5è ð Xð¿Ã_êZÍ“ÙÚEö–šs‚4€¨¾GO×¹®Æ>/[‡¶`G|ª‹Éþl}§’†%V‹TÝÕÞ¿6V"”¡%έ¢ü‘WÅ^#iœ[[ ò€¼õì=MPÒô7šF xšPs³ý…÷õ?äO¤èîÒ•V (ÿY ÿ–#û«êǹíõ®ÇDÐ"´´¹†x¸Ê©»Û’?ÿ×­g5c&ö+iºE¾§‰¥UŠÚ1…QÆþzê å>&øŽmCR†(ÆÛÅ"(û¨çõükw^ûo‰oVÞ9t¡ „")ÔíÓË7.1Ž8ïÓÒ»ïŠ_²ÍßÂMSK›PÔ4‹×¹Ó Ã‹¨âÚÉ«; Äž˜à}y®W‹£N¬cRKšW²ô±Õ -IS•HÇEküÏð§ƒOŒÞ^+ –bzqê}?¥tvúq­ÕÊäò"ˆr°õ÷?Ó5²ž™X\]P‰‘qÜÇ'>ƒ É=ÏáôŠ{g¸¸ a¤o—ää/û+Ôþ»­Ìïs™Å­Ñ”ör_Nò9ÚvŒÿÀG·¯­ohzÓä)Q0CçÌ~ì F1õöïüïi: €”Œ¢ÍŒÉ!û/ùüêíÇ—oŠ V$;¹ûÌßÞonÕ”ê_D5¦UØŽÒÜ$jÑÃÌ}â¼Þ¬O­I£ødñ{z›UyŠ#ÛÜûÿ*ÙÑü7çyvyŽ6è}ÍI¬\y8b˜~êtzŸåÖ²u5å‰J]˜zÝÑ·°L§;÷=þ¿Ë4°j°øƒÂZNŒt]>‹K渓TU?j»x¿Ùà{Èt“©LL„d‘ÉèÞßáëÞµ´ëTÒµ{(Ýq;\"„#”ËÏ¿ùõ¢£•÷ZŽ›’zlô9­fü:ó ÜeP9óüê{ï†z ÿÂý]OíjúæE¸Ò<¼lE$-×o“Ðç¨xyõÏ^¼ªÍº‘UGÞƒ‘þÈî]Ÿ†ÒÁ ³m,8ûªaÛüû“¨Ò‹Ri­]­®›ÃYŽIÉ8ß§]<ÎsOðúYFg¸*\ŒôÀéøz »e 5ôÂy„Sû´<~'üñõ­û µ ViT¬`üˆx'Üÿž:úQª2yx L$íF ävŠ~õ.³nÈ•Nڜã ¼G…QÁœƒú ?fÝZ¦™ÜÜ2¼î?= ýjèîm’‹Œp:= çß”ÕÌšµÁb¶ÕP0\ã ôþ€úÖÔ¥r$Ž[WI5›’AÁú{ëØqZúƒžÉÔùk.¡p>UÆ ;ûÿ×ë]&‰áµtcË{(ýÚ…Œ@:ÕÍIF”kjë%Ô£tóž€zýaÞ´•³(ug7«¥Á%•›†žOšæàŒãßü¸Ý^1:5¼’Ý ó$?yÎpyõ'‚ÜŽ£WQ*›x–5$Ë!?37~GR:tò1¥°Y•@LÀ8Tè%=?ï‘úôéšÚ“¶¤3–›O*’€ÃÖ4Æ7ûŸEü~™®wÄR\Nö–¤<²eœ(©'²é§SâK¹f´´Ä—2ÿ¬pv…ß²Žçðë÷p?³bŠÙ±6àî’S€nHþH;lý:âÁáÓa‚Ø‘j§s»|­rùôQØv¬]ES‘XS¢ãòÿ?žk£ÔcmJSRè9çü÷é‰ylÚ¼­ !–Ý×u¹þèþ§ð Ö,ç'¶m^o* Eº2îêk{Oðâép+2)”Œ…ö¿¥øm4¨U™“jÂO­Tñâé‘y™º»úÿç§RÃsoDsÚõÒé‘a¦n˜çoÿ_üô뇗äwu‚ç”VíîÏ?Ër ,ŒÞÞ ç”SÓê}¿dêõ[†$°ŒdIôúÔHÞ›èbÞ‰59‹|Â0jÕŽˆ A$ŠNxUý«jÃAXK*ä@äûZ.`iÕX)Ùâ1è=Oóúu…¬ÑÕèŒK¨ZF`Ð8vÇ =ùæ²uYÖªusÓÜûÖÆ³x¶PáWøž~¦°’Éï÷'°åÏ ¬§ÙCk³7û?í®ZU.¤ðÎãKqx'Œä=¿hÝ ˆmI#tÃÛß½@mÂ#ƒ“À‹Ce#8Ûy*däžßÒ£Ìijp݇dãZ jZMÌ>nÃ²Š¥tí3ã#hûÌj\lR“eŸß‘’#“ëIm§‰È*‹øçüM]¶Ó ÍÝc^§ÿúÿϽ:ñ€ÌqaU'¨_þ½gìï«/Ÿ¢(]>ðcåUêGAþÏQ­üÒ~T^§ÓüM^[5Š¨Ú«Ôú{Ÿz± ˆà=z¯½' ±óX¥—@  _Óÿ¯M˜,KÿUÙº•\¬KÁîXúÖªù-;øG­SŠZ O©XÆflqØzÔ«Œr2Ý?ú­¥¯–0pXõ©m¬L¿3 (üp)*`å¡RÞÀÈw6Žý…[ŠÓÌ Uñ?ýrjìvû{úõÍ>}¶Ñd p=?úõ¤ac7>…;’¶È áTrG·×Þ°5K£+0ÁbÜ`wöS¼2³rzqÔ{ HÐÎ¥pwz €=·ó¬¦ÛvFVWe /B“R¸]Å¿O§ó®²ßN‹L´Ú¸9ê{¹ÿ?ç×kKðþ¦ZþúîD†aâÇÐ ÿŸç¹£øGA½œ5Ƶu˜è,Iûë¯ò­a¶¾ŒÎRrÿ‡9­ÜÇrEÌ~dR¬LàD1ÔÌ=Æ·ôOI?ˆôŸ³“q¤Ü]DaWh!ÆAô#Ðþ¹®«Gøyàsd#ÅZŠ[É#Kbf#ñéþz×ÒßðO¯‡¿ õߊ³imâ)5xáíoqbbˆ0<cÀ ñ‘×¥rã1±¡JUœ[²ìõü pØiU©wW~kCæÚmíçÇiÚ\ W;§œŒ* «Î{ëùW=áÏ j)¢øŽÖÆÂêTºÓÒ/0¨Ý3}ªÝ²sÓî’o­}ËÿOøGð×BÕí.#×$Ðou ÿö;O<ܰQÃc® kä+/ø?N2Åiã-bk‹¤Ø«ýœãhܧ=}¹?Zå˱¿ZÃB¢MmÑ½ŽœfØV”O~«©ÉéüYGÓæäžÃ¿Ò½[Ô³i¯œ_ùžeàÚZýèûcá7üò_öy×­äž}>o$RÈ„†xYâb=3׿áÚm‡ÅŸþ ñÿ„¼9o©iZ.Ÿ §GGiY®Ì”’~gpNsÇ=1Åv?ÿà£~!ð·ìïâkx"’àè)Vï#îyC¶ÒXõÉöõ¯Ÿ¤ñN©ã'Æ mOPk}V8 ‡Í³‰×åëÊzÿN¿;‚ÂcçV§×,ãÌ¬šº¾ž}»žÞ'„…8}ZéÙÞÎÚkúœçìëâMQßR›Ã×VîIyíþR¬Ç’ëÏÜ'’öqœÛ†Ü’.•p°ƒÂ•¼÷?ìÿ?§[ŸÚº–£:í½¾hÔü¿¾|Ê{÷û£¿¯ç[6¶71HȳIö¶]Ò¹rVÙ~™ëè;}z}}8Õ[µ÷?ó>f­JoTŸõò2müw¦–‹È’;ƒÌÒ²ñôÿxúv§Maö’8âe áW«ê}I­›ˆV‰7°¨9ff?Ä}Iÿ>ö-t‘¤¡š`íÇ9Ûëþ~»Ýõ9›Ob­¸Ñ¼3,Ra®e¹Y1×ËÂ0ãßšç/]¯äl6!yþ·ó®ÿþ|ð¨µoÿÂ=¢O&¥¨Eý»"·[,`7hÏ]Ì0r q©içm~oOø÷ôª)Ê^÷2¶¿™¤¢´³¾Ÿw‘çv±–s#€ÎÃOÿUNÒ“€fsÀõ÷úzSUJ·äúÞÝëcEÑÖÐ-ÍÀÌÊ©­R5”º’èZ8²O´NLܪžÞõvæìD¬ìJy=öÿËëQÜÞÃHí´Ž§¦=1ïüª´rjÖ±ÎÀ¬>k"޽8úóúÐÙ)uc­`“Sœ3)X×…Qü‡½uzŒå°¨½Híì* FR3ò¨N¤…öúÕ½_X(‚U‡ò9þçèXÆsoDuÏàoþ êÞ,·Ö4(!Ò/áÓÛM’çn¡9ÞG>eäç±ô5Ìizzé±,ó¨{‰?Õ¡äóüª¾—¦¦ž«upªó0ýÚ£ßé[v妜“)êsÊûåùb!+ó;Ýéä»yú„åU»ù²kKce™‰‘ºžãØ{ûö«¶rLòÈ@£*00£×Ÿóßé¼-rá˜QÊ©è=ÿÏÖ¶´]êrucl§3ðþtåægsSÂúž§+$‹3Çn¿q|´&cëÈé^»à k]@gŸQCG6ÑžŠÞO·òçÇ„<&8–`±¢N8Aè=ÿÏÓ½øÇðÓÄ>x{]¸ŠÒ-#Ä#ý E6ù+¸\™—ž3Žœp+ÊÄ΋”iI+ËE{k¥ô:i{gJ´uv¾ûã'í‘©øƒáV¤ÁVzeF¹ ²ü·P¿.0wgœ?Jñ¸|O¯½ÃÇsxLê?xÂöÂ=ˆ\#ò¨”“x_DFâxMÁ$ò-Ã:œÿ¼GåZšE„if Ÿ»µƒ¡ÏÌO§¾LúšåÂ`pøh8Ó‚Z¾žlÛޝZIÔ“z/É7Š|"þ ‹Nyµ3R¶¼³K²lÊ·’[þY78ï^oâÿ˭܈bF¿* õú?Ë2x«Äí«J ¶P°ŽW€qý=ûÒx{Ãk!i¦aå¯.äuöçúšì¡KÙÅ:ŽïÒÇ%ZŠRm+/[‹á ­°7sòÉÎæÁõ¹ôôúó]î²òj·²^4²A•º";hȉGþ/_ñÆÜÛ ?Î+#©Ž(¾âwÿ²þ_^šWrå@Z,cìÂïYU|ÓRa5ŠRÄÒÈUF|£há÷G¿¯§JÒÒ´RåÇ³Í —s÷a_óþcKÒ_ÌX£P&Ç$ð°ŽäŸ_ÿUiŽÚ* D@î,GÍ)þñöô”êtEFYVayQåaS’OÞ‘¿¼ßÐv«:‡>ÒEÍÈÄ*rˆx-îjæáóvÞ|êDKÊ©çw¹­Ûyí­õ g¼Id´©’8ÈÉ‘œ{ã¥rT¬Ö‘ÔÚîÕÌ]NC ´³¸ƒ±õ?çÿ­‘‡®µI‹ynÀõ>¿çõ®ƒÄÖöŸˆï%Ó£¸‡My .é= ÄšlG\7ð/§¹§ –ŠkFÂpWiê‘ ø2úÊ"ØÉ$Ä~í8ãÜóÖ¶þ| Ö~&xÂÔ^A%”6r¤¦v*|ð§;8=±×ð®R×I›Ä7…ܸ„8.º?ǵz'ë¹ü®ÚMg ŠfuÈûŠ›¾èþ§üžlmJÑ¥%NK™®ßðNœ¢êÅÔ‹å¿øþ;ø¨x+Ä×a 7mrÍ •@ ’NÀ ãƒÉÿë翞PóÚJ‘¡ùTà–>§üûžÕÒx·R¹ñLjnf¾‘ã•–3Ð8 p¤/Ö±¯"²œ„S´ã«îêk› R¿³Š©$åe}?à›â£EÔ“§£}5ÿ€gj¶Å¬tÁ—ý‘íêk.âÌY©¹¸Ì# ½Aè=Oÿª¶šØE™¦  (ÎAþ5Ïêìú”ÄÂ5 p9cè¯òëÖ»©6úœ3VÔçµv“T¸$†Ø^ =”{ÿ/­]Ñü(mLrf'…ÑGë[Ïöbe?i˜ñ®Á ,·“ Í)è£ú/ó5Êêk¼½¼,ÁA&YOžÿþ‚=ë£Ô× …˜±9–SÁ'üqÛ°÷5-’: D p1Á“Ø{zŸë[QijgSSœžÁeŒò ½ ¤ ?úÞµÎø–öD”ZZƒ-Ôß)+À\v€§·×§SâKÖþÍj—“|£o=‡¦~ÕͶ’‚)P8hÛ‰çy¸þôQúý+º›êÌ$sÙi´Š® ?òÚl`ÎG;G¢שâ±u0úœ»Tl·ŒãŒÿŸóÎéõ\êRyq–ÑñÇüÿŸAX:Œ }!µ·ÊFœK ?Ùí,ûó×$ÎfþÙµ½¹a ²:žOû+Žþý¿žÞ“áxôÈQºŒ"ƒük£Ñ¼'›É,`"cîûŸóêM}~é4¨ZI2Ÿº§œõÿý_Fç}¾‡5â ”Ò¢gr Ç ë·ÿ¯\ÔzYšúó8#(È>ÿç¯óèJ7寯rcÎQ ûÞÿOóõÇÕ¤}^á•IX—¸{þþº«—sú«I«Ü0äD'¥YÓü>#A4©…^G9ö¤ÿžõ»¦øuBy²)X×þ²Ï­>öÝšB‹…e>Žÿ$»–çÑ7³¹Q´8Îæê±Orω­ÜGeP8þ=Xúšß×.cÓ s´r£øœúšåM”š¬í$„ùdàœg>€‡ùÓ4¤“Õ˜ß`}Ff’BÅ Àå`)×±­¤M€Ž9ÀôÔ÷ü+nò%³B ÀcžÃÔúŸÀUWÒ|ý>âèðÐ#3ÇÔ…ÇÞ¾ã·^3q±Ò§s'TÒ?³õ k?´Äý'ÁÞIªêå„&îo*% ¥Ë3`ó€p0M`øëÂW~ñ†« ßˆ–óF»’ÎèÅ ‘LˆÅ[k£#­H×’éó«ÙÜOm$ ¸ÜDå7³sô¬ÙC\»9.Còw3ç=Ͻfá5;ßݶÖÖþ·ÛÊÅ)EÇmo¿—¡Iá3pB€TÑÚˆ×$ žÞžÂ­ o/;ºùTÖö-;ž6úU(‰È§ ŸšIl¿«qZèDêHéÏ_¯µ]ƒOópª6"Œ’GOsïè*i‘-!н|úýOéüí@—"„Ê¶é’ …è8Ïÿ\ÿ/ç‹«^—rAéÇòÿç­]Ôï 9ŒqÇoaïþzÕ}7F“PºUw½¿ÄÖrmè"­«*iš,šÀwnàc=¿Ä×aa£G¢ÚØ3c¯·ôÿ&»¿|9ðŸüá]CFñCkzÆ«fók–FÉ 4ÁÀXUßÈÏ#Ó=øç­tÉ.îQÙÿ«ŒŽ#ûÇßùS “2óÝ[m:ÿLŠÒiÙþwó(ZiRÝ]+²~ôýÄíõ>ÿÊ®ÙiM«È-à mÄŽ87ÐJеÒÎ¥)µƒq€œM(ë+t{zš±®j1èV­ghU\ ’ʽ#Ü_SýztXÁÊûu9Ä;´ÛŽ6Q‰ç ÷P}=Oà9©|+âx‡LGž{$Žê"Ò¡+$Çp彺ázw>ù°ÀËAòÎ== õ>‚µ|?¦µ®­dÅK†™ GÔçp9>þõ”áÌŸ6ÆŸ-¬vŸ¼W}ª|nñ ZŒ·´WWARÞGÏ—ò¯Ì™û¬99üë"×ÁƒÂl¢[»ËÁ”˜Œ_qØO^~gôa§üIÖg ·•íÆá‘‘Àäú?Ïç5­q|;lö‘n¸žèâNìíê1Óü¤áiòÒŠeùâj¹Ô’ófFµzšdfÎÙ‹Ï/úÉz–?çóéÓ5xÙ·ò”í…~cßq=Î:“úöã­èôÃw‘ƒÊÿ}º…ƒù{ôéÖΙáÖÔ¤ó$W[u=3ËžãüOà;ã®1[³++ÑàŠzµû kÞ >³·Õ-o"šM`ó.ÃM»žä€6úcŽ•äš%ÜÐÃz–ëˆfEˆ§ðÜà•ÿwŒù{zWÁë¯ ÅðÿÇ6¾!±ÕïæÆ8´¿ìù– —{ŽÒùꃌãÜ}9Ý+Am8,h‘µÜˆ;|–ëêG·a\xJP„ªÅ'g+ëÕ´›¶¦Øšò”iɵt­§K6µ3mü6–’nµE2 ¶~í˜÷þ•9²L¶ bAÎO,ìˆú“é[Ú=2s;˜·Þ•¿¼Þ¿JšÛHx¹¹¹D<ì÷>ÿËó®îc…«êcZiÁ|ùÆë‡åTóåÿõÿý^µÙøsös¸ø‘ð Äþ:‡ÄzE”—Ê’ÆgÄ÷@c89㯧5Åê÷¨JðÂÃhÈ‘óŒz€{{š¤¶Í*", $*¯ŽŒG ìÖ²­’Šöråw]/§UóîmBP‹~Ò7Ñõ¶½˱,DØU#ŒŒgý£éì?¯M +BûHf*DH»ùþ/sýiiú C2‘9ù‡ß>§Ú¶<=¤¶·-ìQ‚"‚ÕÝ›ŽØÿ?äæªT²UݰÒÒÜyÒ‚Iû õo§ùúËsxs»G$ã!GùéùúSn®ÉÜÄ€Àdwüþ½ë§ø¹àoi7·³ð—Äú²‚y/ŸO–·¹’-¤dí=ýñÔ[΢Œ”,õ¿GÒÝzo×~ƒ…7(¹¾žhãí­e×]Tˆ¢ä§SŽíïï]þ—á¿mgeQš2¸<¨çÍ;Â~ Òí™&o[ÚĶì3±ß…ë_Iø«à‡ÃÝö2±ñ-·ŒíS^ír-ͼ•Ö5aöp<Áµ¸`nåx®<^:%$ýé[áäoC :Ê\­h¯ºÿ3Ã>6ük¿øŽÚ ½±Ò,%ÑtÈ´ØÂÐ[ï>ì’ÖCž¿ â¹ +N[HÖêäo‘¹Ž?_§ÿªµâðŽ•hÍ{?ˆà»’BJ©²YÉîr?ÏJtv‰šwºI[¶#e;p{ú é£B Õ’òhä­)JNRw~¨m»3Ü1ó1þÇ ÿËò«¶Ñ§VeÝ^ßSþyþq[Ä×r) Dcî©äsþyúuØÑt–Õ[an§ænòAZ¶cr}H:«‚w}œ™‡YO öþuéð®æ XÒ1øF?Æ«øG›ö³*Æ‘Œò8ŒzýýU¥âOG§À--NмÿõÏ¿·ù<•*9>XŠä¾'ñ:YÂ-mpнÇ${ŸSUì¥ÔuK{X//.î#²Söhg™¤ŠÅ[’UI!Iôÿ¯Ÿ£irO2Ë >k|ʬ2#ßoA]>“§¤ˆrÅ-£9’CÕÏõ5””b¬4ÙwO²GÓmÕ‰ŽÒعf?yÉ#ó&°üQâVÕ%¶Ë¶ùUW€ßýoSÿפñ/‰›Re´µ`O*wõúŸþ¹¦èz)‘ŽJ€ï$ÇØ{Ÿ¤Â<¾ô†ØíAó‹3¶¬ôújêôí8L™LPÅ÷WÓßýïåMÒôÑ.Ј,`È÷>þžŸÏXâ0FÝ£ýß­cRm½(k©\"¸àîõêþ™¦9™Q¯!êO¯òúÒiú{s1ädàGî}ÿ—Ö¶a‚;x Q¡ûîGúÃþÝë–¤ú#hG¨ÈâK{*"L]]»Ê}~ž‚¯èú¼q,ÃBš“HÑÍã‰$Qyþu´ÁbFQÐz×J¶Ñ‡VA)TLãÑj‹Àn³¯·ùýk{\ÓôØt½6[;é®nçäOE¶lðîÏåY¡$.ãt¾æ°§RêèÖ¤vefDµ‹{Ž%Aþužš|šýÛ3Xá˜u>ÃßùUø¬äÖ®H–%êÝǰ÷þU¿c¥¥¼j¡B…°­%S‘y“|Þ…M7H[hÔ***Œ(Â=øÕý*×ÌÔ`s‘H¤µÈý*e¶3ps°{uö©ò"íTa’;sÐ{×ê^èì§I&Šº³wpsµ ’:žOúš¦ðn>l )Q…QØz}jüÑy“4Œ£²ÿõë>ùÍÃ`"õôª¦ôHŠ»Ý™:‹Â@Èx8ëôçÿ­.Ÿ¡JË"sòÇççÖµ,´€d• =:ÿ“W%_°pâAŽOosZJ¶œ¨Î4oïH͸C§) ‰.åžÊ==…aß‰‘ù’Lr?Èè;uôÎÅé*̈ۤc—ltÿ=‡ãYòÚ†BªŒpÄucè?Æ´¦í¹E}5’²PD*pqÒŸîꙬO]µ™B¾eÔŸ*ªtOöGùãòÏGâß°(Šßrÿ"*¹ì¯ÿ¯ëÎ6ƒ*ï #q<£œ ýÅ?Ì÷?¯¡EßVqÍtG:t®$PùÝÄóŽwÓ4öõ=ÿž.«›÷ÂvééÓçüãéµ47Ÿ¸…v@œíþÎ:âêp—”ÚÛ…@ó$íÿâ½»u>ÝÔäs³—Ôbk§kKS±SýlƒžÃý£ŸÂ´ôOǦ[¬¯EQû´<‘î}ë¤Ð<#„i$ˆT/(‡¯ûÇÔÔšì±é–2Ï!WÓ¯'üþ½*U~Ê”×nSI¶i$ÀýÕ=¿ùÿõrK}VS{{½aìBF\ÿž½»}zS¦¾¹p×—y[t9U<>Ÿç ¬]zvÕ¦1C„…G$pª?Ãüú×E7mg9­Ü>«9D!!N§(ç<úéúg†`’U)t“þ9?ýo§C¥x`H8SæËuúýjÅÜ Yc¸Px }æ÷þ_ZÓŸ¢g7ylæ@ˆp8ì!§ßùtØšÕÄZu©£ <4‡Ô×G­O™jÜV?ð)OøWqi.·tòHvÆŸy¹ ô皤îTY%Œš½ËÉ)"0y?МŸå%Ü `˜ÀV^1ýÏo÷½On‚·î­—M„€»º}Úþ]+5tÏ4¦ù9À¤Ñ¢‘“h¢ß3Ïmi"'A,e€ýk£ðÄuðŠ4í~xrê-&ánb·’Ñ·\•9ÛÜg×èx.k#xêì„F?ÕÆGÞçïÌñ¬Uí¢%¥e*ÍÙG ¨©F\²Ù›S¯(»Çtz—í¥ûBCñ‹ãf±eá Ù=±’¡¶.åPÞ  õ9㯠œy…íOˆ|O§À–t÷Q‡há(XsÔÿŸÂµ5‹FÕüa¨J»ŠM;Hîçïg¶=ÿ¶\X9å˜÷÷?áþOQ} =έ~¨JÁÉe# Íî}ôɨ“LQµ#\äÉoö‰ôþJëQæ9ܹQÒëZÇÃûŸÙãÃÚ6™á›ûoÚÞÉ6§¬I>è/ %¶¹ÿwO8¯:¼oŽ6%GúÇîO ÿ?ým{åòƒ$E€$‰&Ç@>¾ß…eK‘@UÄKÓÔŸóùTB‚¦š‹ní½]÷ý<º*®m7ÒËk’Zùø‰8wÿ?玮[5‰Kƒ²óþzšÑò<¼0; !°k™A ~žô8•} ø4渓‘€99íZiÁ€TQ9$ôúŸojзÓwáaG$ž=O «–‘v…ç$r}Ïô_¨¥eS¢3fT¶‡'*«Î8É>§ßÚ°5{ó3’HP¾ŸÃÿ×­ kQ' ¡z³ïõÿ>ÕŸ§éR_ΣœÜñþUœßDimYWOÒ¤ÔnUU là›}¾¾§µ{‰à?èާ&»¨ OÉ:X´Å ²ÙŸ4KÙ·vÏáÜah>‹B¶.áÀùŽ8Qè?Ïÿ[BÞÂKÉ‘Ìg$&-¿øóä*]+ÚͯOËÐN¶ú\Ï·Óä¼™—?ê£þèþñ¾ƒùv½o§5ô­mnÄ©8ž`N\ÿuÇúUè4缕­mË1'Î9?î¯ùý*æ­y…­ ­®Õ¹㟠z¼JÔÁÈÏÖobðÕ¡´´*“¨Û$‹ÒöGûGô®v ò dP•O;©÷ÿ>¸Ð†Å¤"GÊ©íÏÞ>ùÿ=H׋H6f6ti$•TÅ2ÎHëŠÓ±—k¥˜1žiN#Œ ³SïþzWcá¿ ÿÂ943H‚}VáUê"ëþzþB¯hþÀ q: Nä~î.¢1þÏéÖ]kPO DÀIçjžAÉÏ÷Gùýi7} å&ô"ø“­G¤kºŒ÷·r’ì9bxùGùýzr6úSDï4íºåÇÌp Æ=ùöé[X»êÝOµ®$$ûD=¿¿áêjÆ™ ¶±)á’ÝÌz}¿òúôp\±DÎZ»6 j“À¤yìXÿonƒŸ»©ö#uˆbaO“)ÁoöWúžÕ°lEÓ}žÝJ@Ÿ+2w=•}ñßµtG†Æœ"ÄQ½Ô‹û¨ÿ‚5þñö¯ó©M#6ʞё¢ÝB±Æ×W …P’ï@?_ææ³M2Ý€%ÙŽæfûÒŸSíè+tZ&›e0,dyHi¾ô¤wöQØRØèþV.îWæëÓÜÿOO¯L}¦­­‘g£ý—ý*ä~ôòˆÃî´}ÿ•dëIpÑDH#ï°==ì}OjÚÖï%¼¸hb,XŸ˜Ž ûåY†Åe_*53ù?ÿb?Z¸ÉîÁ#lUX£P"Ø{ŸE¯Z·k£ ‰$(’x2è+bÃAkÖà ˆžK0]ÿŸ@+V?Üê·†ÞÞK4E8fk„\~ý*gU-Ù¤`ÞÈç ÒŸ_s¿ÊÉË`¬Þøíéúõ¿ô40kHŠ(´©˜ŸSòÖ®•ðžìF© Ö•¡És¶>µï³—옟|7®_ÞjVVþm¤¶Em.T“v>rW¡ùyõ¯'0ÌèФç9hz8ZÕaOËã ê“ùJH…OÌ{¹ïøWU ø|[*–P €GÜ÷>ÿçésDðºÙFŒÊ¥ À÷«w÷ cUÚK ëîÏÿ_éîy•ôC.5ˆôHꬒ¯(¬2þñõö=xàêYK$?,îî¤Üfâá b]˜ÁÉ>øçëŠÇÓôŒfîï''åBpÌÏùÍlAÝéq ‚Í"©û¨ ¨éøp;þyÎqM¡ÆVL®‹éÔŠ±6ØÙ@ôô_éSÅ]²œ)~êž­îÏ?Jp·7LTˆ8ç—9äŸëùV¦•£¶£)D%bSûÉ? ª¹›bé[êr•\ˆTáß»A^‡á/ 6¡#AÆz(õ?çÿ¯³ð ÇBÐ|w§]ø‹G}_B¶Üg³V ¼m ÈÎ8©¼wâ}>ÛR¼M"ݬìç™ÞY·P“´ì+Š¥y:žÉEí{ôôï‘nšäSºßn¾½Šþ!ñze¿Ù­ˆy'úŸjÊÑôǺ¸Yd\»üÈ®3öÛú ‹IÒÞöešU.íó"·öÛÛÐw®ãÀ_u?jM§èÖW:„ê†I<¥ÜÌR ¥R¤)E¶ímÛ"0”šŒUÙKL°YA™aCºIW?ÔÿŸJ¥â?›¶V–ùNÓÉ>ƒßÔö««_jºÔz—ew5óJ`ðÆÏ3IÝŽKpséÍT°ðô¶w/nèÑ\DJM¹J˜H'+ƒÐƒ×?ýjˆ¸Þíÿ]Æâí{ £iœ¨ 0ÿY'eƒüþ¼¯IÓDŠª $IÏ#§¹÷ÇAþLF’$ `$j9}Oô½bÝG<ÿ3ïXÕ©pHrí·@Š6íçžÞçÞ­ØY»Ìª‰™[;Ú?犊ÊÕÚETRÒ· æϽl[[­´md1oõ’Ûéüÿ—,çm¬#ÔšÞ$¶ŒÅõ’ùiíþïó­M#I7N”„€™¦hú;ܺ–RtÄ×AKaTæk†­[hŽºtï«E†0«ÓÞ¡—9 Ô® ä‘€²ÍÂŽþµÎi!F7¾BŽƒÖ¢ŽÖM^àªåc_¼ßÝÿëÔ°Û¾©9T(ïÙEnÙééi¢ŒÓ¹úšS¨£êU:NoÈŠËNKhU#]ª£þ{Õ¤· ‘ÆÁÔúÔË8äÔÿJ‘P¤*Ž:t®9ͳ¶0Hˆ¦8 «Ôú{zbÂ\† (_º¾ŸýzŸa™ÁUéïõ¦\àªð£½J‘M®ÏœH…ïíKk¦…Ä’÷W¾Æ®ÛØÁÚ ßÿ×V ˆ>vÈxQéU*¶V‰*ß3*º}d€Ó?‹Y÷LÊHBGêÞŸçÓñ5z励ÆFêqÓÿ­TÚóqýãý>µtßVMNÈÎx@ÈRB¼ÙÉ'Ð{Ö~¯uö¢TAÎßÃÖµõ+g!áTrGÿ^±ÞͼÆÉÌÄïÔD=¹îk²›êÎ*ŠÚ# ´Ù Ž7“3q4¹Ï–T_R{šÊÔ±1û=º…‰8$tÿ?çÔž‹PS"ýžÛžp0?Ïùõ¬{ø¶mlŒ»ž‘SýwS•ÎIÄç5%`ÆÖÜ…~¯'hÇ©÷ôÒî‹áìáY$Œª/*§ï9þñ÷Ïùèö‹áD‚1,¶¸nûμÏôÅM£µ„É PNv)àðÿ?Ž’¯v$F—Vs:¬‰§ÀÒÊ@eAà}MsÑéoâ *îöçz[Å::<ÿŸj׺±—]¹in Çmt#øÿ/¯G_“¨xQŽÝU+˜Pã…µO•/Uù“ó7èÿ#€ñÓjRùa"AŽ/ø:f—áea½ÀHcä–àŸsïü³ë]&›á'ÌãlIÉ-Õ©þƒ·ó»h`ÙGó‘˜ã#Úoè;}k©Õ·ºŒRês7U#@}ÄžÕÒëG¦ÛHYË˾>iO ö®&ú ¼AxÄ‘ 99 úÿŸñÖš¾ûÑÍÜ[˯ݳ»‰z·ð¨ô©n­K€¡ʧª{Ÿö¿ô­t·‘éVêv”å¯ûGßÐvÎzÖAÒÚúC,¿,IÈÏsþúÝ*WÎwû4Ü“4˜XÓžxÞ žÌÞ…fSäƒû´ï!õ>ÕÐÏho˜Œ¶ê~Dèe>§ÐŸ¦n³)·c 5ÃðJŽØž*“ÎX˜Äæ y߆aü>ÃÓúU}ö·rye®ŽywUSŸ|“ÐõëZÇÃïu1Š0Ÿï¹è}ý=+¯ø¿àýáˆIðïˆ,üU–ÑMöÛhŒh]—s+ýßþ¹Æ)¥%®ÿ…ºí×ü¢œ—OëmúÍÊøjÅE¿›¯d9&8a$ÿ´w7uýO5ëÿ°–‡ðÂçã=¬:ÜúÔöáÒH?´¡… k ß!Xþƒ¸ÏááŸÙ»¦1«yd“©o§·ùút¿"¾<ððTÛ :„%ï'>2~€zW? êÐ5&®žÇ^ ©ÕŒÜS³ëÔíjï ü3´ø»‡e×’îÍXÅ Z<™>a°?{†Ï9Àé^;®'‡ i ³¹×Z^²I$0€¾Ü7òéZšî¤m/ïíTù©<ÎÒ¶@ò¾có/¡ôëšånì%Q‰I;ñÌžçßÛ·ò× †t©Æ›“v[¾¤b1*¥G>T®öìtþ/øñqâ€zõÓôøtoÞ½ä7‚ÑRövbß+°=2ǶOé^pÖèƒpí°­i­B(b«÷Pô_ë]¿ÇïŠvüW¦_ižÒ<# †Ÿ“Ûéàm¸uë[€2zAÔšp¤©IBœ4“m»­ûnïäi*¾Ò.s–ªÉ.ëþåðiÏw&=ÏùíZ6úVð#Œ‡’O±ßØ ÖµÒpq¨ õ=7~>žõjhÆ#ÏÊ9$޾çÛ=ÿ[ )Ò«ÐË’´· a@ä“Á'ÔÿAþG7­jòK£œÃÔûÿ‡¦+K]ÔKîä>îz}Oùý:ä[iÒjwb ÈÉ÷úû~5} ©¯´Ìë=*]Vép¬ <ãŸýþkÞ5-GÁàG…t7Â_Ù~/Ò¤‘õmhϹoщ* gÝ{ c¾k‘ð×…£Ñàó(/'¨Aþ?ç뢖fù•™ DOîãÿž‡Ôû:Âtœ[oG}^Z÷^L¯¬´œVÏO뱟ob×óG#!d'1D‹ý£ííÞ®¥ƒÏ#[@ÄÈÿë¦íÿeqßüýtÎG¹kxX›–8šAÈŒt{öý>·¯^/Ùˆa öÖ\äò ø«óï«ÐçrlÎÔ®!𘶷.ÊüÍÔ[ƒÜú±ÿ>üä6Mw(w,I@ǯûMþ^š h׎%“sI Äå÷š´-l$I–~QŒ—=¿jE§b¶•öp$‘˜Ÿ•1ó;}?¥wÏáðä¶7W1 õ«(z„ÊÓÔ÷éÓ¬þðš!‚[ÄI5{“²Ê¡³ÀCïÛ?‡Nk¼øÝà­Cá?öeî¿gqesy¥Û"oiGóFž„w=½ÉòT¯R0¾®ÿ?CHÂRƒ’Z+k¬^§†-ÝÙÄ×÷‡qÕO÷Wóÿ9ç×K‘æ77‰Îp â!þ>ýºuÉ­K{)/ï åÙQ3}ÈúGô?¨÷&®YhíªM±HPïŒvéõô³“ؘ´·9ÛèŒÍ;B“W¸9Ý~gÆÓëü¾µ²,C…¶¶SQ¬Ê9ì¯ûG?†=Hôð@µ·4åfìö¬úçß Ñ|6šlQ;Dgâsù“íê{þuª&V‘ᱦǬ— Cè£ûÇØu'¿çZ±éɧÃ#3y²IÌ’®¢ŠÖK²ÝØI,¼¼7ûEë]$K‹™ÀÙÕ½î}½«žU.R‰‘g£îaup8ëÿü‡õÅP×.丠€“!?3àöúÿ*émtGƾ#µÑtx$»ÔïœEkŒäŒãž3Œžzu¬ø>óÂZÕÞ{k-¥õœ†˜Ÿ–Ý~ž§¿ÒˆÕ7+jûÛ˹^Î\¼ÖÓkô¹Í*"ˆCÃ0?سê{ý*{Mí Ž±ó7MçÐ{VÕžŠn˜¨oGlcwû#ØTÏh×RýšÜ Á `/·ùÿõ[©ÐJ&DvM¨^%µº€¡€f[wZZjF¢9ÞÇüõÿ?]=BHn †5PÌ~µ'“ÌñEõ¤¤QJDŽ8-ÀùAþf°•[Ï•v6P÷/æsÍhº¬­ œ_ë$þ÷°õÿ#Þ»…~?Õ<-i®[éW“éÖCK˜¤Qq· þ÷èr¦JŠ»#Nòj΂ÿe£1 O•=†qÇùëYb#ÁÆZ£l4å §cçÛ£± g õïŸóþ}ëC¤MÍÎp:/rÇù}kvM9býì¹r£¿ÿ¯ù~B¡[½˜I ùS¢¨õ>ßçéïóžr‰B ½”K"¨U*‘…QëôþXòšïä@Æ0OÕÏsþztÖÞ8ùq‚OBÇüþ_ÊÕŽ”÷r˜¢Â¨ÿY à/°¡È Ót¦»”ÇIÆ?Ùç­vþð¸“ËHã r0õ4¾ð¯™å¢F5èêkTÔcÑ->ÏÏSëïôÿ?NyÕÖÑ'”f±¬E¢Ú‹{|N9>çÚ²4Ý6KùÖIrç(­ü_í7·óüél´ù5 „’ƒ!s•^›Ï©öÐéÚarÑ¡<Ë!}µC—"ÐJ"éÖLªTó$§ø¿úÞÕ­á¯Ï­xÜx^í¬o fp¡ò§¶Vþ_ Ä×u‘n¿d´$c«N©ªÚN’âM«<ŽOQú÷'üñ×ÓŒâÕUtú?Ô¸JP’”šê? ëz¶ƒâØõ«+Ù­µÈåkƒx„o…Û%ˆ'ŒÇ9Çë½öIõ[Ó<®óMtZy¥““#3ÎÇÜäûÕ-'I,Q(Û×'¿¹öþu×_Y >ÂÀ(,Ò@d}ã“Éöö¬*Î*I¥«ÓäTyœZoMʰB-#€’yç©ÿhÔö–­#(P^I9}ÏøSm­ÚW#Èr]ÞçÛÐw­‹[alŒŠÛä|ùœçØJÂsaqm­Å²ƒ;gÌ“×ØOzØÑt†¸u$ ÄÿAڣѴƒ;¯ËÔ c>çÛÓó®¢ÒÑ`Œ*sŸ¼}kе[hŽštÂݯu>´öÚ‡'‘ÛÒ¤`#RO#°õªÌÆá‰c…Iâ¹¹ÐÕ´BæÄ¢›/©ÜãQëÓëNŽ¿G%Ï_jݳÓÖÆŠ73rOsJ¥NUæU:\þƒ,ìÊ ˆ¤žç¹÷«QÂrHõ>Ÿýz|P•98ÏséR,e÷Tsô®;êÎèÁ-¬JüœªÈõÍ(‹Ï BŽ€ÿ3Og BŽƒúša(¸>µ.E¨<` ªp=hŠË£0ÂŽƒü÷« ?3pj$tè=*]N…(6E°G‚FXô•Z|®q†vý?ÏëVf%y<±ý*#$ç!»“ÚœXš)Ï ÷‰íUïXZ À¿„u#ÿ¯Z7$[Gœàþµœð;JI'Ì=û'ÿ_ùVБ”Óèf5«X“™ˆåºùCü•T¸„80Ä0rkRâ2— I¨£·*&Ž0O(·=¿ÒºãSKœR¦ïcž½…¢ýÄL®3žÈ=Oôý/ÃqÀ…˜3);‰o½!õ5±§h€!f$«|ÌOW>þßçënDåßœƒ#šÑ×¶ˆˆÐ¾¬Ä¾Ùov!UGLõÿ럯+sg'ˆ®Œ²1KHÏ'¡ooóø×U,úÔÄÊ·"98 nªú•Æ’Ûm’ ð cäuOÿ®¶¥S—e©”é©uV9=Q×["ʱHƒ¶p¤tŸ_´ü9à™Ã]Wu¼¡ò"ÌÈFp&¶´¯ønQóÛjÅ3’|Åù¿úÕôŸ‡fðÒ|8Ú©Œ _nüãåϿּüÏ6xxÅB ݯÁ£ÑË2µˆ”¹¦•“üQòB"*ºp q‘þ¬y½ýâkŸÕ XÃ#»“»ï¾yséšô¿¿…ìµ ç1jùi{—QžzjàutÑ5Û½‘A«"§¬‰„ÿëÿ*öpÕœ—3‹<šô]”‘皤Þ"¼#!#NI<*óßü™dÓ"ÒíÔ*…+Ê©Ç}Ì~à~'ší.4Ý/LµÌPÞ*ŽT;.[Ñ=â{V ºRê“4„J"'9s÷½ÍzP­u¶‡¡c’:CjR™dÊļŒ÷÷9ªÓéÂÿµCòކb?¥uW6+z ¨al‡†Séô¬ÝnO°b8”5Ëüªp•´fɱÊkÌlɆ ­u'tÛüôúÖ]—†žîo*0d•ÏÌÝsôý~¿Lšê-<5-Ìâ4V–iOÌAÏà?Ï?h_YÃáû5† &¸˜cŽ|ÏþÇÿBÇ ­Kh+¶¡oƒh¶öê%žoÍûäÿ²:ûã'Œ ›O4¢“4ó¹³÷½½€îÈêgÓÝf#™îç8fÎrº§©ÿëT¶Þ[T%ƒHîv±N²Ïo­Rš°%c—·ÐªAwsÉ ôQÜÿZ–Æc¤øŠÇË*nVxÙßXÔ08œtöçë·ªÆl‰6½Ó.X—ÓÛéø×>ÖƒÎKyhÁÎrç9þuMó!ÅësœÔm¾Ñ4ÁC‹–f=\äŸóùŸjWþR`@_º¾žçüÿA]Õºª’À…Yí¦5ôÀI=¥REÃÂ7¿ µ„½‹^>8kØN–ÑþÏßò×Íæßׇ½eÚè½#A»' ½øú{ÿ‘¹g¡ÂF¥‹:“éÿ×ÿ"ëØ%Œ=²G'¶?Ãùÿ8„9[Õ»»ëÓÉy:œÉ+mýj`Ij¶QAÈäôÿ­\Ö½¨™ þà÷÷?çúÖö½yæî‹ÈÏV÷>ßçÔ×=ý›&­sЕ<€Fsî þiÈ)Ç«1aÓåÕ®†ÐØ=3øŸsØN½§‡¼(šL"GU2ã<òß>§×úuØð烗L…du&R3Ï;}Iõ5|içP •clÐÌÃÞ¢è©NæTvfô©(L$ü‹Îe>§Ûüý{(>[…RkñxHÀÔEƒèü›Èã+»Î¦ÞÞ޹⨮›"J!„)»aó68Çù}jôÐÃàÛTE{ÇPÜíÿm¿ ¬ª]Û•Û_½vdµº¿õ¹“raðuŠÇ«^¸È Ï–?¾Þþ‚¹³n÷Ò™$ÜÁÎỬ‡¹?çú Ô6o¨Ìe›{‡9ËšSëôÿ>Õ~ÓHTΛ„_loöÕOMX£¡Ÿefm“ÎrBös!ÿóë]Ï…~ßáø–þêW72qomµI_×çNðÿ…VÁSRÔ#-)?èÖøä_¯òúôÕ¿•4žê膾q…^¢Øë\õ%¥®Z”–ÌÕ³ø±¬ø ¦§w©³]ÂáÖ?.\x2Ç}ƒ×üÿª²BÈ›‹±!Üœž {úžÝ=j£.¬RDCàý'XŸÄ¶Ñøv;éux˜ÉYî3†¤sÇvü*=F+½gWºžþ[‰ï&‘Ô²’dgÏ çœúæº?ëÚ·€|C¥¢]½ô có‘AÚ¬0T0jµô:¥ä„ fžwi%r É'$Ÿ©¨s—´riZÛõóùmcNUìÒMÞûtòù˜OlÓ0·Bö$ ké~YãÆÎ:±èÿ_zÓÓ¼#qŠÚrÇ–m‡Š/ô=BVö¶w€^A d}8ëüªeU=i>ÆD›[µ´ƒ(«:‰¡pãëüªßÄ{´ñ¦¦ U›°ç â½áÁ=CâV¹moqe%œˆÍ+D@˜œsüC{Ö—í ð+Pð‰.u8àšø]É˜ÂÆY`à|Ç“í^|³+¨ó{Öz}Ç¡W‡uT}Ûîx…Õ°±Bòád#!HÇ©÷ªZe´šŒó”ƒËecÜç¯ò­¹<ªj·$=•òF]Þ&É?—'ùV„^žÚ0¢Òá"Q€¾[ÕèûXÛsBIì|ý-£]Ë–€8÷úŸ£&„»yQîÀ?1èIÿ?•k]Ãå7•%ß>ÿçòëQ[é4¢€ Ìýz}kÚSÐáå)Zéq'“ÚGß|pƒÐŸ­u~ðÈp‘Æ„ è1×ÜÿõêxiHDT">û{šß»ž=ÛÊŒ”õ#©öúV3«Ñ‰ ýäz-©† ©îúÕ‹mfú„ÂG áÏ ÐÉþ¬Eh÷Ó $•»Ÿð®ŸKðV¥q¢Ë¨Çcrö18†kµˆù7dÝÐõýë7R0Z°6öFvŸ¥—}‹‚Í÷ß Ðz n·«­¬BÖÓ Ž±ÉÿëûTÚÆ¤¶0ýžß?y½Ï¥RÓ´ÇyÊZfõçg¹÷4EßV&º"=3Kc(™›®yòýýÏùéœôÚ>‹æ¨Š,ýOs'©ÿ=“4Í0 Æ nê{±ÿç[vÑ-’€¿3‡×Óð¬êUì Û¶q…P¿=>ÿ¹öÿ=+§×´Òú™ S#½¼xÀûÙgý8ük;OÓÆ¼À$m%ãðcQÌþê=»Žý«Óuï‡:‚¬KZȬ €I9_’1™sÏn£é^V+J »6Îì>RŒšWV8 nT—”ŒÉ'eöüÿŽ–—¥›™*å{µïô©¡²I™`· S˳_÷}?:ÞÓ¬Õ6–=Iÿ=*jVÐQ¤Kad¶Ñ€¤<–õÿëUÛx³ExÓÌ`¡˜íUÏr{Ԟ˜„±Ïéš©,Íu1UÈ^çµr6ßSeüM¤¶‹¯ÜØ››k¯³0kwÝðÛ5F(ZòQjH=½úÔÄ×L°Ä Rpqü_ýjÞ°±M6`4Ž9>¿à*ù"“weª|óvVAc§¦ÕÈÝO¯ÿZ­Å,Ćî}(†2€»à±çžÕ,q™˜“ƒÔò}ë’R»»;#²#/Ž0£šx_5‚¨ù}sRóHUÎßO_zµ ®Ôë’zœVR# ‘G Ƹê{šxˆz`zTÂy=)Jnç¹÷¬\ÍT¾@QØÓwc“õéV „Á9ã ¨Ö`IåéM0h€BI$‘“íœRJD1’péV0€0â.Ù,:³ïU_rlRx™¤$Þߢ_­A:íÂ&Iî{šÐ–"£jX÷ëUæÈÀPK¿JÞ22q3®b6à"(g|ãÓëVü;£‡[Æl°1,G-Óô«Væñ¹ùBOµnè: ÒÅ|ÑÆòÅöfÚʹ S[£®UÒLå&EInéT¬¬ßS×-ão–=ã>„V½ÍŒfR³LñÈ:©‹;>¼õöÿëV×Ã#GÔ¼M½Ýû¤QåÓ1˜þltÝžýqÿת©ˆTéÊzè»2a‡u*FK^èókÒLb8j¨Á>ŸýsU¬ô Ä€S޽ÿ/óôì5¯ i¶º´ðZ_I%¬LDmä}wgŸ¯|UIí­íÐägð<¼n?ŸJî†%8®[ëäÎad›æ¶žhËò“N„PÓ¸:ãÜÔ¦skà PI3×™qÁö]F!ÜÌÀ±ûÍéì+:åäÕ¼9woÀ3Æ@ì:óõÿ?GËÌ“}׿L]›^Oò9-IßÅrˆŽRXøF=ôo|t?ä@úDzdÏ Gß>§ÛнzWDšLV6ø ‘žå§×ýŸçôNãO}^+($ÆãÕ¸èÆªZ-ÆéßW¹ÊO§6§3Ï–9Ïv÷úT2éÂÿr(+lƒ,@Á”újé.,ÀdŒn‡ ëŸAHöÂÚÒvT (¶¢ã…¯øþ5»­c%J笑§¢¢*ùíÂ*Ž#çükßÃÒÏ>ÕV’yN ÇOoóôúu0x~Yî:<—žO$Žz w÷üµùì"ðå™UQ,òqòòXôÚ1Û±#¯AÆkuZÚ-ÌU>§1we‡ìü´Q,ó p9sÓýŸçÐqX7:{¤¬Í™®§8$ŸìŽßSÿÖÏUu§ºÊ]Ç›u)ÁÇ;xû«øwôöêû_- ,ùi[†+É®Å÷÷íÖ´[!8µ®€¶hÎÀ´ò’8'ý…ÿÆ«êHl$h¯w À 2±/ø3ÍuZ¤GO*«]¸Â åbõþ¤þœÝÖžf2v*ÜË)ä¿ÿ[ùþ@é ßRd¬r—6FmêršY;Ïø?ʨÞÛ,kœEè8ÏOç]=ýªª`¨¯¹÷ÿ>¦²Áï¦T°=Ïùýk¢5$sm`÷ó Äžƒ·ùþu¥g ù`".æn­Üû èlü=³äPYÏÞ=óéõ«ï¥¦›%Ar1þ}¿ŸÒ‡T9·°N‡™#è1þÎk—>vâ œõoþ·_ÿ_N]¹7€$ äžìÏùôæ®,ŸT›h»cÿÖþ}*”ŠŒNuì_Tœ2žý¹žÝë¬ðïƒ×OE’Týéä>ï¹÷­¿ø=lcY¤B\üÀÈ÷>ÿËùh}€Þ¹Q¸@§æaÁúoóô‰Ô苵цl ÷@|×Híô÷­ÓV8”¦ÆN0°/¯×ÐZÙLh$DÜ0ùF>XW=M\{H|3i¸-Ìœ¨=\ÿy½«71XÆ{X|'d0¢[©~eVä“ýööÿ?NnKY5YšiYÝ$;ŽzÌÀ~X­©­¤Õ§y¦,èÇ–=d>ƒÚ®[há–R%ëŽöÙÿ=ƒS¶¬i¶ÚB•2Ê@Œ~ößçéÓxÂËn©¨ßÆ@Sþ|úã×ù}zjh>]‹}ØSýD8ÁcëŠØºÆš¦öì/ÚýÔ}D#×ëXN·DZ—{"èѵåÑOµ°ù°§¯ùúaZérkwBî䄿8ÛŸ£ü‡âxÀ­h4éu믴܆òó”CÎïr;ôéßéZQé¯w(Š%É<³BSþyö‘ö‰“•&¡8† ?ÚnHQê}~ϵnµ#·€|ë†fä¯dú“úÿ-tıQ¸ #rÌyÇûGüút­ÝÑØÂ³J¬wøäoñþB¹êWêk ff‰á˜ì IeGbOÈ^FÿåùW]câ ô¿ßhïk§Èš„é;ÜAž½#»/¯ÔúÔqiæ ÒK&6ñÒ1ýÕ÷õ56Ÿ`.¼Ë‹aÆÑü_OO¯zá«5=e­µ:©ÅÇáëú™VšHºÌÓ °'@?ÛéüêߜÞ±ªî–ÕYGe<ŸÊ­xƒ6È¡t~ïwþ˜ô©|i`b‹G°w²MÉ?›*‡Sß‹~eªv„¾Gm PX»óÈ>ƒý¯åÒŸŒKlQ´Žމì=ë´ñ„´¿ëÏm£ê2j–ʈVg‡Ë1’ °*{ç5‘%¡B"‰C1ê}=Ïùÿëë B’R_‘¢âÚ}>fKÂÈDàƒŽ¹è=Ïÿ¯CO³šÍBÅ,Ï%²F=ë¥ð†­wá NÒÒ;gÌg¸i¡ʹ'*OÝ<ÖF¢þQ6öüÈ~óÿwüö¬ý«”š¶…û$’wÔ¥âKûb-­nî‡ß}Çþ½6/êÖ‹…Ô®†?é¡§¦œ¶È@Îz’y&š[8mªf¨#åý£ïM(vLŸvvÿ¾6jŸÿ?uÂŒz~oüÎ)Ô—ô‘bîù/$!`UÌqQÚFon£‚$3`àòÞ¢XšWD ÝÁ#¹ô®ŸÃ:BØ]@†‘˜ŽÞ´©5²)ÁÎHŠÂÁ4¸°6´HéôÕnŠæG庌ñŠÙÊNìø-¸àtåC)ªç<÷®9T¾¬êŒÐV’~0ÁùTp ÓFxuàW¬¬ü±¹ˆ-ßÚ³”Íc ޵²òÔÉõ©¶’@ ã°§tÎÁè“*Ïsý+îl£aNeÈÔÒœ"“Æ(PŠùŒ ½õ¤;25Œ¹ÜÀŒt!!rqÓÚ¤Ü1×5¤ž¦&š |»ôÎ}©…qÇR*Ç–QxûÇžidŒ’j”ŒÜYåˆgÊWvõ'š|%;šÖ'-Ô’Ã>Ôå„’I “ßü)Ì€F¦ä¶™0Ô­ã:}¹ý¦®ãá×´Û *x%‚+y"C# 9ÀõçÖ¼ñÜ®vŒ±ü–¤Òß˪¥‹=»dç’k—„…XrËó:°¸©Ò©Ì­÷ñv¿gq«Lðé–ïÍ•}Íóûýk?Gº·:¥¾Û+ç†cŽ*8-ÎÓ èÜŸP}¿Ï4øà³) wÅ]±§Ç‘vîÎ9T”¥Îÿ$Tyb0* xÕLŸÃÚ©Î79H»íWž-£'#þù›|­<Æ$âºan‡,ö2oÕï¤òÐaGN3øššÚÉ-´™cûÁÝXÿ¶pOçô«éd ˆ’ÏSýïo¥W’'¹Ü ¤lûWC©}Ì©ÛW»1&²{ùH9ÙßßÚ¥ºÓDþUŒí‰n »÷¾QÀ­cgöÅ1Fvºõ#øý‡¿ó©îÙôïDè®íeQG쪕gt—qFŽíö8½A“LE ¨ÎF>£þ¿Ö¶¼#ðÓQñ.uqak5Û5¬êä`˜˜²|§ß¯>Þ¼U˜[QF!.¥kó÷‘NBoö½}>µßxCâ>¥à/ŽE¾šxgŸ’]Y@UÇny¬±˜š±‚ö)9_«ÿ€oƒÃÒ•Gí[I.‹þ ãWšt>¶1€é²®G\ôؿȟÀzÖÅ› I{‡ù@î²=ÿ—óﵿjm4“½ôòÍ;|Ê"€c¿¿ÿ^³„W%Yî'v~ýög°õc^…Òµä·óÿ€pU¥Ù7÷Á9;m Zî’CûÃÁ#¹þõ'ÿ¯Pê*,îb4„¿ý~çôéµ%6H†foõqõ î}ýOzçî­wq».ÿëdþƒÓüŠé…Fõg<¡m^òɧ–EV.Íþ¶Sߨ{úºqY·*)mEöäûÿŸñ®ÛJð…÷‹5xt½*ÒK»¹ÉòâŒ|Ò¤“Ï É®ZÿN–K·†Hž6ÊÈÁ~†º©Õùoª2•7kÛC•»±“Pœ¤©û«ýkFÇÃÂÝHQºCÁlda]—‡ŒXÀÜç›°ÿ?çÞúéiab ±èùýÈÒUÖÈJ8t݈ ôŸç½szåÁ¸g€òÃÞßOþ·°®›[˜Î\¾ޞÃüÿ@y{èúPˆ Æ8wÿëžµ¥7Õ‹”æ®íßQ—j(òÁÀíŸþ·ùõ5¿ x=l£̹ò Ôú};Vîá%· ,±îvÆÔ#©íÿÖ~kžFŒ]¼Hqƒþè÷§*ÝùL6²7‡bƒåç À`±þèÿ?ýkqifÜ*Fªn|‹ü1S[qieUTŒO ½”zŸoçV~Åne&~@þ)©>•“ªº DÇû^´ó '› =\úŸ@+Ÿ¸·“UºyefpÇ {¿°öãüó[wI«\<²±*~ñ¯û+íRC¥‰AbcONƒØSS¶ì9L{m$:–p«útúóþ»¢øi%U½¼R¶Ñb‹¼‡±Çô­=ÃËr¢æåvZ§ÜŒŽ_ÜOçüö'U·Aurª»bˆòÜûÖ+tF‘§Ô‡Dðå߈5Ë;x Yõù6vÛ€ OBk'ÅžÕ4O^éúÜ" ­:_.H³¼ÆrHàŒc¿ASY­Ö§ªGx²M’âH«nÈçÓükJín5kçye–æærYä•‹³ìÄòýC郔Ô÷V·Îÿב²Œ5N÷ùXËEžâÃm.ÂcSè[ >ÙÉè=´-ôÕ°a„#rÌzÿ¼ÃéŽÕÒXkÚ†•àé|= Ë>îuº–£  N2ÀàqÀüfѼ<°'0$pG,~ŸÓüœ^"Zó|U$íËó(hž[X„ó‚A9ýéùè?ÉÛ·ÒÜÉ!ŒHæŒzSV£¶;÷¸ÃÀ?Ƨ‚ÈË’Ãj/çô®YÖmÜè….ˆŠÓ²ߜ³Û¬KÇúÑ“íVî¼-rÑíŽKHùΠ¥Evâ0ʽÿª©›B±!¥nK÷úþ‚±NO[þÖŠéø‚>]jºìVw76/Ë~÷ Y}ônŸAøW¥üWýŸm4Z]XI ÝY@!¦|(¿=My> ørê;˜¾[äù£Ï" ÿõcé]Ĉ†­§i¶—,g†{U2(êNzçÖ¼¬T12ÄBTç§]O <Ì"BÄîÝ÷›»AíIöc)óǯ‹##uÂŽ{Q䛉ò÷ô¦æ%ÊÚ4Ó`ÚdaƒŽÕžÑ5ä¥ß%AÇ~‚º›ÏéRøßSÉ“[’í¡—Lòò¡å?C“Ž=ë:ÚÀ£óЋÿׯ^S»^Ÿ×ùœ¤Õ¯Ô«i§0`!; ô©/.Æ#x.zñVî¤0²& ‘ɪÙ=Ä…ØXäg¿½RwÕ’àR·²k‰C0,íÈÔÖµ–³  ³ÿOóÒ­ZiÞJíQ—=Hëô­ {U·Nsžœ!S*¡ÈGoh¶±Œòǃä*U„Ÿ™€$ñÇòãR,[Žâ1Ž8íì+BÎÌÛÌ™º( õúÖ2¨5NâZY›l3ga€?ç˜íǯµhYY™È@ RyõcShZdWzŒ)pòÇlòšDTŸ˜Üãü+ªÔôm?IÖ®bÓ.&»²WÄJ›—ÇcþÉS“·SxPmstüJ~ž-c€\úvö×éþ'»ðŒö¶R$s¥¯—“qƒ‘Œ­`EA¹Žïý)5;³x"ã =@ä×Xª®ÒW]NªRtõŽŒ‚æé®¤Â“Œž”Š­+„@Y˜áˆïì)¡Io.1’z2~‚º-G]2$ HàwÛëZN¢Š3Œ˜ºnŒºdGùûÿwÚ¶<9l_Y¶fÜøðªö„£p[ø:+kÂúD×úõ«[£K|–îðx5çb*û²rgu W”yWS*å ·r¨ÁPçñ朱|£ƒ´ð1Õ«GQÒÞÂúapù…èd9<ozŽYßs`ƒ°Qè+5RéXÑÓ³i³²Øw67ÈU–b Ï  dgÐzÔd™('qê}*o}M°¬Yب<ž§ÓÚœ‰…ÀÀQÖ„Œ …ÀriÑ!” ä ýi\~a yAøæ¤ žJŒžÔª 8žÞ‚•ÈUëÜö-ê;8 ïéJ±Œd‚=1RG° Ýéà ‚3ŸzNB·ry –¤ÜàžçúTÌ7`õÍ!ŒƒÛÖÄâBcUç®{zÔRŽp§óÎ 4Õ€Iª‹%¢¬ Gòã-ëOÓ£ öޤ¼DZ{F$òM,K³WNZXˆ§{•<°<éM(yÎ8ü…Zh³ÈÁ¨dì2`úV¤K‰sLê¨2ã>¿Z–ïNK{Ë‘ƒ…‘>¿1â¶ü?c¦¦¡»k¡nXy§jãÏ_J“ÆÐé¯â ¡g%Ѷ«ßÅÉ9ëúRX•í{õq͵¾Ç*ð%Ä„0(àãï&Ç Ý€>ñR¼U¹`‹…ŒÈ’­Wš5·@8ì;ýk¥Jç3†ãFP¼Z›à*2f½Rá¼4ÿ@d,Ç€ß8>=znÅy:BÑ1|nºùæ?ÇùV’,ü,›¾ð¹,1Ô£õ®L^Ú8ûÍY÷:ð˜—IKÝNë±0øoN*ÂtHÄ$x9è8ëþz× øº Ÿ‡È`Ì­ ¬b ¾wmÀvÏ­y¤ìdFnHÁ#¦=½O,= Äò®†^¹–_ÖŠø_i(IÉèûù †+ÙÆqQZ®ÞfHÓôhXȱêañÐ…€äÕElíYcºg¼×©K]ÛûÏ2¢¶É}Ç=}Ÿ;í,Ò·ßbFÛüôüë:îŽ2ªqõ8ä×C{ErOLÿŸóÚ°î¡7o€ \ôZ»éÈâœL8îníµ®,§¸´ž"LrC!IèH#‘ÁýMKg Y™¾yŸ–sÉÉ­Û]Ç“´—#“Ø ººbÚǽÔç°îkYVWЕM´bÛY¦šÉ)ErŒQÆCzP{Õ‰Þ,ox’êÿì–V >ÝÑZ&È“ {ãŸ\úuÐÕ¥iÙ•H™»è?óŠæµ(ÍØ£ =ºµU8§.w¿ùÿà Mòò-ŽgQ…¯d >Xãëøÿ3ïë×CHð²Ú –UÉ?tŒþ‡µt_†VL çî®>÷ÿZ§žÑ¥“j‚YºŸîû}k¡×èŒÕ>å? j÷ñMŽ£iÜió,ª%@ñ’?„Žõ{Åú´þ1ñMî­sº^êRy¦(SdiÀǧ‰«i"Ñ*ŽõúU‡³L€É!ÞííËJær‡?´K[[幯4¹9/¥ïo3¬#ÑíÚYrò¿¿.±/!“U¸v‘ŽÎŒGB?º+næ)5IÙÜ€ƒ†#ŒAMM?Í;@ qôÿëÖÑ·!ÀÇJc $H? zVŽ™ -àL¡mcû«ÿ=¿¨þu©§hbð‰$-£ç£ÿõ«JH‘I Û‘‰¨nˆ¥LÎ’5󀨜ǧ¹¬—µ“_¹ó%$[©áH9þ·ÿ«ÔÖ¤–òk—Ÿ+÷Æóþu,öˆ¹sÀóý+>~_RÔ/©š¶M•Ž$NÃÿ¬?úÀV…¶œ,T*.ù_“žüu>€œ÷½o§­šùŸüçØñ÷­M/F/›'$òsßÿ­éXT­e©¼)ô bS,¹b~nG-þ}+Qm‹6æJôûžÿZ´°–;ˆ Žƒû¿ýzž 8’FÔ^¹®9Ö¾çTiÛDV·°3òF#Z}Á@PöµnbPBõ¨…¹ÜY¾ñçØV|×5qèŠ?gÛ’N\òOaþ{ žÞÐ@T…Ç+žvûŸz· ™ 8!<ÿ3ïS aÀ±¤æ8ÓêRh6,ÍÏÔúÖ¾±mº;Œ¸¶QQAc´ä‚XÕ½V@±Ûª€Î" ŠÂr¼•¡ EÜÉšsj†$ÚNßÖ«®ž-÷9;™¹,kF;1Y†]¹&™,$œ–=Z™›Ì™á,û@AéïPS!(„s÷˜ô­Wµ%Š&žY»ú©ëb@q×'Œûš¿h/gve­Šª…A€9Éïîid·Û~êÿ|ÿ…i=º…' S°îçü*'·ÆâÄ<3áݹÊTÌão³s9;ßaÿ ŠkZ™L®6 ?*ŠÑŽÄÊC:áÝOZ‹R“Ê“ÇÊ…=GÊfÝ[jà“è8$-ªaÉè)ÐÁóo` ¨çf™À ð;gÿ­MË (õ<º+bp sÐv¥”-œd/2¤Õµ„B-üDôXÛ™Ø QÛ¹¯eNûžw-Š+nn3 ÄôsZÖ_ˤv«6Ö&1>cúUø,„J #ôÿëÑ*½@«  ·\œg§¸öõ €g'NÞÕemÉ9<úõêÕ½˜„‡uù‡ÝSÛÜÖNcä¹µŸ‘µØ!û«Ù}Í]±ÓÌ­¸äsÉê~Ÿ_åR[Yœ“‘ê{ý>µ½§éÂ2 0àOþ½cR­#NâiÚp¶ÁÀ: }Ú¼‘2pïREn u=@¨.® Š1ý+ɶj¢Ë‰ŒÌFò¤få#U,ØÁ þŸZLþDÉsÔâ·4m!tôÊ“°ë·ÿ¯D¦¢5Ù.‰¦[éq f€4§ Ü~_o­kÛÜZ±-˜`:0óU!€ÊÁß%GAëRíóÛjOÿWó®*™êΨFËCB=JÆV éûëûÓ]ÿÂ]sMµfŒ[%«Èß.[qsíšó˜#X—s”v5­á¸Ýµ»id0l(…•çâèF¥'ßÞÎì%wN¢•—ÜŽ¯â.§§^jJéj³•È,}½«œ{Û">[ ¹ÿ¦‡š†y|«©‡ÞVc¸ÍC(Cz:}iP ¡~öUzîsr²û‘,—P»[`¬Û'5õå­Í¥¬pYGlð¡È“1õªŠ€ ¾´¡|ÌŽˆ;úÖÜ‹Fb¦ì×$ Q?@Dcõ©–<à` I`à~•!>_Ê0\õ>Ÿýzi’¢!ùPîæ’8†7”ä€O ~µaHâ“v)E² €ò@w¤vŠ’FP 3Þ£Á8”’¸>ÃH ÉúÒ;y`“×§Êœß $“šj¡wÜ@'ùU"ŒòN ÒšÀ&K`ŸJ–V ¶ó¨p\䌓T‰h`R[Oµ^ðõ…¶­©$7—BÎÝ”“.3ÏaRëv6¿f7OsæGºRÃÐUQÁ€ 'µG7H<6yíÇZ¶¸rîŒä³Æ]ŽtÏosïRÞátøù íÉ8ëSÊ€ÄAГPL…ƒ‚Ã?E«æ»FnM#*hZI É.Øä Tº‰cB€½Iõ­[ˆÄjT`g©ìk.ñ ìTnÙŸÅ«¢ ç”L;ØÍÛmPvÀîÆ¤³Ñ<¼P\úôQ[Vº@ˆ†* ‘Ç¢Õ´²X”±éúšÚUúDÉR[³!4Ôµsg#·sþÏ¥dj²ܪ•¹ì¿çü÷5¹©³LÅW÷=”ŸóÔŒ;ä, q‚ê{“ZRwÕ“R:Yþ£›÷Q+m’:“þ?çÒ§x}aE–Uè×ÿ­[–º*¢$Q·°õ©&€»`){c[ûnˆÁRêÌyíÚG £.Ýû/ÿ^¦¶Ò…ª€tÐw­xtÁ Œ.]¿?ΤkEµ‰ÏÌ}ºûT:½js(Ú%œFG!˜þgÚ²n “S¸bΝR:/°÷®·ÄúÒø¥,#K =?ìâ{uÁŸý¶õcþ5ÖAñk¶5ëéÿë§J£µä¬ÅRš½¢îŒo°ÈTP‘§?Ï55žŠ/[$m·Oü{ÿ­ZÐébãälIÿU³n±Ä6ÆLÕJ·`.¬ Ð"F†ÈÓî¯LûÖTÈú´Ç$ˆúnöúV¥Äm©IŽDKø©c´¡A=€â—=ŠP¹AlÂíE\ž€?È«¶ÖÑA 4¯þ*¹€¶ˆß#vþŸJ»c§òd|±?çJÆuQ´i•´í( É)Ëþ¿ýj¼°—`Ø=ªa`0«Zð Ö¹gRú³¢0èGk¦I:»¢HÑÆ2ìªH_¯¥HÀpï]†¼guáþÊÞ+wŠýv±uË/n+aä9¥sƤ›|ÊË¡ÐéÅEr½z•D– >Ü š;Là‘–<óüÍZŠÔõ#$ôÿSÇŒå»ã­¨5L«öa“Ϲ§ÃdW“Éj;|’y'¹ô§¸€p3Ú³u  Ò á@,zSL9ÚÏË…§‘—lü©Z2Ç¡'T© Ħñt8É=¨KBKªŒ¶ÒIÍ\ç€IïÚ§Óí|Áp$X~”:–@©ÝØÉ[PªA9ïÓw¿Ò’H•Sœ”}µ]t§9ÛÜŽ­ì*)c!8áôúÓS}A@£$Gq,B¸êz„ƒÞ’;3 ÊUü«ëWRÌ8ÜÀ„^€õ&’òAj¤œn`saB›è†}üËl‡=zqÛØV0F»˜‘‚}{óëVîê%W'ÔöQþÎ)ÏA3Ô÷cZ©YËrœà*¼/CÛ4ÛkF™É“Þ¬Ãd×O’>^ñÿëV”6+e›GSëJU,Zä’ÛùÇj‚~¾õ$6Š`tý*çـ®Bާֻ‡¾ Ðu­X¸Õõc§]ÙźÒ?zqúŸjõ*â8ó?ÃSϧAÎ\«üŽ>Aƒ€òÿëÓÄyçô«>_‘Ê¥‚ÛfáÖ›™ 6ö»0ì…OAîjÔ…äÉÉÇSßÿ×SAhÎÙ'×Òµì4áV*AíYJ­‹;‘éúp‰U˜`ŽƒÓÿ¯ZvöÁ~f8 9=€§ÛZg’T×'SÞÞYX,Mn¡znž5?ŽOÿª¹¥Rïshò!¹”Ëc#&@I0߯UcòÆ|ç©ô®ÓOøeq?Ãû½Un,–8çBcûBm ÝœXc>õ›àVµÑ©=Öže-¸ZEã;° s¬]=lövù›K =.º_äeèÚ2Ù¨šQ‰ ÷}þµ£FvÞã:/­9a2¹Ѓšvæ”ìQÇèD¦Þ¬p‚Bó3mP1Üö©•`Î:úšV 3“ÔÕ»2̇^ƒÒ³r4ŒEµ³,ÁÜ ö•£¥b=F@o΢ÀU­-³”¼ˆ€7–éØVwLÚ³Le˹r9bÇÜÒ"”Èó×Ò°ïlrÄœþtªžf@ÀQÔÓ¾‚qÔ@¡²2vúô§¢€sÒ¤X†J“!…åÛ×µK’ˆÏî@ÏéïDQäŒ(õþ*tPrXœg?Z³å‚€8¦å`Q#XËà@餮¥w01ƒPœ±,ÄñíÍJw)¡½y iqåÍ×·µI°F¥œã½* “{óÞ©2$¬4üç'ƒ×”3ìRIŸƜÌI'" Úd;ˆªÓ3jÁÌŽY¹>”¡w¶1ÜÒí-ÀÀ#‚jxa¨$aM»W#€HžƒÒ—iíŽõ ^I dúÓÁÏ\µ+”d™ÁÂΡe _J‘†â àÖšAwÀ<Ÿ¥Zd$G´€Š<‚y ‘SGU#ó4ž@ä¢#\’M7Ë$píSªzØý( dñÈ9DHbXþUŽ1‚@çëV$Ëñœ ¡$õúU&+dB힬z{T2D1“ÔÕædŸZ¯,FHÉŒ‘Ö­HÎHʸV“€QÆ{šXtð9 dôö­lÂH$ö…H @­=­´FJ÷(-¨A’8ª—¥¤mªãøZw ]ЍþUBé>Bª'©õª§-Hœm¢0ïÀÁŽ<àý㎵¶wÈÑÐzÖÔ:j¨,ãÛ¹¦MfeZéUz#?gÕ™3BY‡ËóvZ|g•ÎÝÎßjÁ§ùGZFý)Ï Â¤‚ þµ.§@TÌÆ·[u%°Iïý*:éìµ›k¥Š¬‹&É—tg8#¾jäÖíq!Œu'µG%°9HÁzš«­˜YÝX«­ÎuÝVêèC °¸”ÈÉ í ìaUÇÍrª0ƒ¯lÖÂiûì¤ ÕuçƒM6â 'ò§–÷WA:m¾gÔ¢mÕ ¢©\Fo_o"!ÔŽ ö­¢3äBÌÓ~Êöª£;jKÊ+n#UFOL ž+? `KÇð«±Yˆ€$ncSCh7n`AçBãL­maÉw?çŠÒ·Ðnï4É•ìíYVIùc' 4ÕAŒc‘úU˜'š+G„K*[ÊAxòx$t8®z“}Šp]J±[¸8L–“ÅKÉÉâ¦íÀŠÊU54ŒRxÀϧj• “ÿë÷©Vy祎ÎsÀF‘q¼Œƒ×Ö—o'b¦* 8>Ôå€r>QQÌh¢Y×|3yᦅnã ˆüăd§z¢¶å‰f?Ê®K$·l4’I±v®ö-´z Ò‰ yè*#&—½¹¤¢¯îìUòG‚sÒž-öäã“ÔÕ¸áÙÉPIý)UÔ0÷ÎOëIÈ9 HŠ R¥õÇý+KHÒ$‘/ #˶s½ ôãëJ·±E’líˆxüßæºÿxÚËDÓî`žÒ(¥TivƤá}óßÚ¹±5§^1¹Ñ‡¡ I)JÇO ¶#plp½¡§ßùTQXï!›!ß–5Ðê¶÷W²Î4ûAÎ\6/ŸÇ­T½½Ž,mmÔŽ€gõ­aUµ±”©¤÷2¯]m",x qþÍ`Ü´š…ÆÔ“ø…£}3ê7#Ì–±”N ûÍÜû 茬Œ¥ ³<Û­´{‘Ý»µG‹]0à„}jüvfå‡OçZiâ I@ëÚ‡P¥•½‚Ä„œ½ME8ûDpU®Ý±•‚¨GAýMW?) ¿3œ~µ õ)DZçYó0?Z‘u=:Ö§e8ïì)ÑÀr²Oa^»›<µ­GÀg°ô÷«PÛo$œ{t©`²2Oý…iYX‚Fr3üÍg)@ŽÂÀ*‡a€:OsZ0Ûž­€=ûT–öøäöéIs0Qµs§ZÅÎìÕ@Šêà\àþf£H‚rrÌjDŒ ò矧ִ4Ý4(ÊsIÍ$ ع£Å$:,Í#2«M,y;xWÇ¥9Wín#jÝiPµÌn Ú›ƒ{ñŸñ¥f.ÁJç¾­›%¢E¥Ño.4™/bœ2žL€n¹üj8ÐB¤ õ5$.ÖÖÆ%‘Älw2ç O®:U‹ #3`@Ÿ3Ö娧k abf`ì0; ÐÚ#C’0;Õ¥Ó¡M ®¾×‘eòüùhF>÷Ò¨K9ãåÝ_êk>w¡£‡(K) ¹vû£ÓÞŸo”ã—'$ÒC C’KHÝML¨[*¤ûšè5w– Âç“ëíR….§*  (_(,ÝK‘J# „QÆ\þ”‹fää§Öœ‘ïcƒœõ'½Ke˜¼ ž`å¸ÔR@ça* $Ó¤"<Žj2€Ž¼úФ6¬F~cóýiÁBÌ@¥8ª¨,~P*&-+F<ßZ¤îKC[3¾â8¥+ IÇó§—®H þµY‹LrAÀè*Ó2Ö&W'Ž:Rí<3ëéK³ ~•fÞØF 0ÆGNv%Fâ[Û„°úRí$sÖœ«r2*d®9ÁïYó]š¨Ù ‘‡nêjwdž~4®|ÓŸº¢šäÈÁ@ vÅic91 ,ħ ô«vùŽI ÄŸÀÒAQÏ$õ=êÅŠÿ¥•crïòšš’Ñ•N¦ÊNq ÀüÅ*¡ÏLåREo±7º Gm¹¨ëíU~Äòõc*01שN?;’p8?Êœ©ŽqëM;!8ÜŒcвºEÃèï|±³#ˆ™· †>Ýj&{p)bC#„ÜÁO8ÆGJ™IÛB£ԨїàdO‚Ð9ÛÚSðäÕ„·€ýédzGŸë]‘¤iW¼–k§ Œ¸'íùsÎZŠÕÔv{®…Ñ æúuêrf>•¨=½*ü@ä‘<¬IÿžXþµ ¨€ŒXžäbµŒÌe ·íTœž§¥@,‚͜Õ¤mÂ’[$ ‚E Ëè=kU= \ ùc$î `ýÕ±Ù9#t‡òZ¾–¤6H%ÏAØRJ@*ÎÝO¯ÿZ«ô'£$B% 2ÌZ®ÖæLœ÷>• -‹È,zžÔÉ# )Àî}*£;Ÿ, Š0£©¨¥¶ uèG9«Ò¢Ä˜gÛ­$J°®îíÝ=êùí¨•28mh7$¼ÈƒØpjç‹|Xµ46Ùäã“ü~f³s)D‚@ Àê{šiPªI8#©ì=ªqS’aù(¨. (±û«ýM.k”ŽI L¥@.>èì¾ÿZ·¡ÚìK¶bHxz·Je€P^C’zŸ_j» d•œ€ gÒ¦rÒÅF=JðA$²$II$¤*F¼œû{Öf­¡j/-Àk;…­¶S°â#îÎ3S›û‘|“[4‰4,zÇþÑôÿ=ê÷ü%ú¾›{j×&Q~Û®ÆXœv?€¢ó‹÷l 1z;œà¶[8Ê)Þj‰- 팿^µt[Û£üâ®ÛXˆÈ~•¬ªØ•L«m`#í€?*+§.B({Z»tÛ€UŽ˜õªŽ"BåSý*»—ÈR¹G•R 7ëQÅ 1 YºšžV™·yíW¡³[x÷0Ë”ÜÆ 8û8 œMM ®÷$ã×&¬Gk¸ö?Zµols°sþ÷½z²¨yj-­à‘…SîkB ^#ÈúÓ­íƒ`àc°<~4³ÌQ‘Ó>µ“•ÊPs(PUG΢Ž"H$cÐæié$1' þµzÃOûÉ>çå»ÿ­KšÈj-Ó´á´K!ùzŒÿ¹ö«j Ô„à¬j~™§mk—!cúS‹dˆãǧùþ•“‘j"1.Dq‚íéSG‰ã'©íÿꥆ`œ’9>¿ýj³gf×. h펵.VE(•‘¸“s”tÖ´€§<ÔЪ°¡ÆާúT3Î8$p~âúÖ.NLÕFÁ<ü† ’~êÿZt1Ë6ZWý) €£|4­úUˆÐî*¼±ûÍéIÈ|º‚FyUÿ"Àû¿Îˆã ¡@!XQäà ·@+"Ômò@$íÐu¦Ç•ˆëŸ¼}iê†FÁ$çïè*uR¼-+Øj¨1€µ9€‹#ùU½Vê ‹€ð[­² QNyîj“e8Çò¨Nêì§hµFç$ôè îl€=H¨0YŽr3P»ØHAÐzûÕ¢°ÆÌÄ0£ ¤,±©c€*G0Kõª¬LäQÐzÖ±fli&V xQÐtÍ8)Ý´dúS†rzÿ*žÚØ*‚À‘ŸÄÕ9ØÍBã`·¨f§©©‚rAúS–2ÄÉö¦ÊÃGOóÅdåsU!ŽÀŒ ÜÔ ûÂ@8EêiÌÆ\¨ *ýæ¨d›%U=ke& û˜*‚@è*żQÄ~e,{üØÅ%½¸„ycÔÑ4»FsùÓnú!F6Õ’›‹t!L21ö…t~¾Ól^aq+:’»Ûç·Ö¹x¡äŒ±üjÕŒæ;–$òQÿ”Öé©ÁÆìè¡UÂjVDúÅÝ“_Êñ[ɱÎT‰p1ùqô¬çx[a‘O»ç¥09á,O8î=êHãÛÀçÔÖŠŠ±”¤äÄX”`#=Ni|±ÓŸ´•à(Dç,)óˆøô‹‰t÷º¹¶FÚÏØK¹@9äjEÔ%ŠÕ턎-Ü壂}j]"Ù¿´‘TVV ÁùMdäÔ]ÍjÆp€qRÂØîÉ.Sêy4èíö¦÷ÀÍ9r#pp3aVåØ˜Ä¯"qÉSëQ¥«Í*¢#<Žpª£% ;ü¹þ”¶óiš„WP°I mÊHÈÏLUs;;⮹Šw6ÒA3Ç2žÕbB¹fåÛ¿aíK Ø00ò­9‰p*È»2ª1êzÔHm㠞ÓV'u7G õª®pî7Hßu}*“&ÌþX0Åbi[ òÁÅO«t·bzŸ%Ã¥E¾Ü³’Xõ4ÙX¸*¼úÐÒ} R—sºÓ>+­·ƒæ ð•‹*€)$@ô®&ï[ºóI"ÙƒüÀˆWô§Ä¿ñ#¹AÔÊŸÈÕ)eKh ¿(?°£†§'»:+W©5'²ãU”),"Ï´j3úUIg|嶇?ìŒ ÿY\³\òd§ßÚ…‰cBòª¼ûçúšêI-Žv›ÝˆŠ±Çæ>BŽG®Æ›mu*± ü v§G ^º³) >âÿžõ£ ¸‰@,zúRr°( ŠÔ¨ ªKAÅX‹MÎ)?Ù4,{pry?ãFæf …°{ç“YÊO¡¬`‹vºÝÜ«µœ«œØ~Sëô­¿øûB´´Äg%Œ„RNFO>Õ‚—-bU•Üȧ*¾§Úµ|Câ[Íz+8.&fA ¹#Œ7<ý+Ž£«Ï5n§U5O‘ÝkÐÈþȺv! ˜z±B)âÑ׎Š=A÷§me1QÎs÷½þ”øã.A$‘ÛÞ´sd(!‘A¸À€: u«QB Žž½éðÂXûzÓfªð«ÔúÔ9£ Ùdݼ ê}i»Brt–”&1ÆèAîj‹…Ee‰?Ri]• ¸œ&ù‰è=}êK-<€dòzŸè*K ?¬²žOùÅ^à :/õ¤çm£r ;á@û£¦=ë>êwÈ\’Ýõ«7“5ĘQ’zëLò…²Þ~ñô¡0°–:œú-•Ý´KÔ >TÛŸÆ©y&c€0¾Ÿç½X—8äùÿúêÝ¥ŽÖP@1éJöÔ¤›²+[ÙÔþžÔO¥TdÖ­Íòð >µ‹åC!°ëþ) D¡?î•€9`2MQŠÍ®ä Ê@ÏÖ´ì,šöi‚TFÄ^*ݦži`H=­öF %…7°ì;škDe`Ädž;ÿõªä‘X±öïì*U¶ë¹€2ƒ²Ô¹”¢yÌVÆVãô*»md[OZž Mø ¾3RNáÐy=NkÔsló.$ÆUH#½A¹s¹9û¢¬,%Èfç õ«v¶^a,Ä•îzgØQÍaò܆ÏNó>wå;öÝíô«X7 6 ëéOe7 @?ÿê¥sµBF?Z‡!¨ ‘ñ„Œö©a€B ã'©þ”ë{q$ýãÔÿJ±kj×OÓ? ™Hj#m,ÚåÁ ì­j$kÂÔÑK `¸ëíPÜÌýÁ÷W»ÁÊæŠ6<ã©/E_ZX`*Áß #t”°ÀIó$åÏAØU˜ã ŽîÝOqC––CQê$q‘ÀåÏSéS"*€ w÷¡# ÿZµBÁ,xUïYJE¨ˆ‘ˆffû«ëH‘4®y˧·ÐS‘g<Ç©ØU”Œ'È£RÙCR`(À§¶!SŒgÚŸ/<Ô ÅòN5-ƒDd—ëŒ rGÀfÀQÍ>8·Œœ­E4¦á€üz©0c$cpÀ ìëïJvĤ’0;šw¥‰>ÕVG7 ÎÁÐZ¤KDSHnŸ<„ì?­. ªcú{ÓÊ•À’jÍ­—ؾ§«Us¤G#if77Cùšœ!'$ŽÀT«™– €: S'“U<÷ö¨r»-FÄR°ªõOaUe“ÌbŠHQÕ³NšC!(„€>ñÍW–P@E¨éÇ&µ‚2“¾âO1ÀTÐzÔö¶¦K`¹ê{ K[?,nl¯E÷§Í/—À<õçùš¦ú"T{‰,¡ªõþTØ£ä>cëÛÜûÑ D¸$džžÞ楑„ …sÏ?ÌÒ¿D \GqÀ 1çžÕS•›€w zô5¹Ü˜ô÷÷©mâ1±ç.G'®)´¬Ô!„ À$·sS ëHÀ|£­I[ €*\†¢ î \S·Ä¤ƒ±ÿz’YBœ ?¥W‘ð0 ɨI½Ê½NM2Þà%²ÍqÐK3m ÷+¡ø{wandW„Äï’»Ûvxä¹çs‚WÐõ5©¤dß+0­í”ÖŠIÓp»:(Tq¨¥dYñö7œ’%»º7F`¥f\Ml€ ƒ=¼ÌŸåK$â(ˆa݇\ûUGFy $Œç°«§ $¯·™J—mØk´rB2×'8¨ØŒ€Ëté  yè=}ê)d‚YÏSýobÐÙ¥ä)Üìy㯵-µ§—ó¾ ‘ùJ–ÖÌÇûÇûǯû?ýz“lñTåØJ$l8vª÷,1—l:æ­LU4ó+‚“wõ¥ ·•À¹ÿÇh”ì !· ¥Èäö"®Î_çR,XÀ%¹úÿõ©¬ ¶Å$“ÔúÖNe¨Œ9r2s×ÔÓ„b\õ=…:B-FÄù¥n¤ö¦G cµrXõj—"¹FÅLûT’OSZ 8H*±('»`ŸÒ¡DP6'+Üÿ{ÿ­S¢ÊðH_þµg)\Ò1°ÔMàw\ñžÿýjµúŒO‚رÁéEÄÜã (ûÍéPårÔF\L9E!Q~óJG´’Ü!’'zîXþõ"¨À8u©§júÔ÷‹žg˜Â¢4ÏP=&ÝÐÔUµ*ÝÜÁ’OâI©4ý8±3K×ôí/K29–c€ûµ§AÀf‰~êúûÔÊv`F‘¡ÜmAÑ}jµÔ¦bƒÐzÕ‹© ¬É€=úÕ#ƒ#O¥Jer•Ê3‚ žI=ª#cÜ(üÿýu>ÂüŒà~ZžÞÔ& ØzõêœÆ¢Emh€éßrÎÜÏw F¥œ¸ù@É<ö§$Œ„m8=: ¹¤ëizŒS&à*0ⱜåfi««™–ík+«+ 2r0r*M.{¸'a ¸R¸Âžy­ OUºÕµ fwÚÌß2…ü*Í‚HúuË3œ ¸íÞ“œ¹u)A_AÞðmÍøã„ X™H`@ɪŸöLÿlXÚ @VÚÇiûoçZz·s§¼Ë ®ªbl“Ï8íQÙDÿÚQI#1‘Û;w½cÏ+»šòÆË¹,d¶š7z §¡òZbÌAÀõïW^7™™‹1Py$æ–( ŠB6üëGP•„“¡ã?ç [ï;#·½lx~õt]j ¹-¢»H&'+qŠmÒ®¡¨M:Ä$®[bp©“÷Ezª­¬y¾Í[r•½–ü±çú ›i™‚¨ÂË;FdùTaG倿îáFsŒ “IÌ\…f¨MI ¾ÎNw§Ò¥†Ü''–=O§ÿ^¦ŽßÏ`;i9‹ŠÞÕ®[ëZQİ&ëíNŠ``c¿¥E<€Œœˆ×ócYJW-FÃg˜l³°t«Sa„–ó$Ác÷@è>(w#áZ±Eq‘—?¥&Ça2­À̇¯µJ‘ˆòõ?ÒŸ!’OSVa€( ÊOeQÔûT¹Èaî?£ùS‘IOÍŒ:(ônÿGºÓeAqå]Ëèµ"@"@äT*‰ê‹pkF†¤B$ £ëR•)'ïÒž„yoåU¤&c€N=jopjÃ]Ì„äàtqnvÖŸhÎ0ŸÎ›3™þUF=;Õ_°4G4†|ªœ ü7õ¨Øp8§ù{ÈÀª×›“´dGúši’ÑÎn_!Oz,{v©6mÀq=õ«Öyœäw>µM¡XŽÖÈ0Üç ž}êÖÐäUè)ê»ÎpBŠdìS!@Ýüª®Ã”dòíʯÞõôª2Êd;Pžzš˜É8‰9$ò}*œ²×jò£¿÷ªâKØŽâP©±9_çRÚYì;Üíù u­©\; ¹è==êYd.8$þµ|ÚY¡Üd²ÁÉ?ç&¢Žî€IäüÍ9ÈA9bzvüjfźŒÌÜëBv #‘W9v?äÕ9d;˜þ¾õjÄ™5—ï30üúÕpùlI¹ïØRR³‹hH`(H9.zŸJ™TchȾ´ª€GSO†2@$)¹‰bßI–m6KÀ#ò!`‡æ²z`TÉ·Ôþ”K&Ð<úzT.3Üš•~¥8®#…÷&– c#|ÝÿJX 26yÏ©íWíàBŠnD¨ßq!·ã$ ––Úe<ç•$ó¬)ÎÞ©ÆÍ$ûŽAðTZå¦G̬I8 ~RHà(UƒÐzÒÉ PAéêj)dò23™SéV‰hdò q€I‘¸>¿ARYÙl%ß¿EÿëÔÖÚDÉn·RÆËªÄ| ÿ9°Ã…ç4svâH!E1å·XËʲìƒJ$p»¨¾§5FYÍà \ƒî/÷¨Jì†ä׺T¾ ð\ï;äù†IÇ®1÷}¿ZÈ‚ÎL®“{3ƒn•%¥±kBòá~|û: YXÌÞ€TÁrÞÌ©>k]K¬\˦ +‹MûÂq×ëYò–X÷ô«¸L(8=ñŠc5½ª±c0näcaU–È–›ÜŽ4[X®w™b$þb²dÜÁd‘A-þ­öµuþm{K·ÔÙh”²`er2F;gk¹ŠÐË#³]ú³>ÜÛ§j!WÞi¢åFÑNå@ÛåêÌ{Ô ¨J "Sò¯v>µb`š›¢Uz-ïWíí…¾>\·@=+gPÉ@Ž AŽ>sïÒ¥„àa˜þ¿ýj“fÌàeëÿÖ¨æb¢ÎO'×ÿ­Pçr”PÉ«Én§Ö‡ah¥Wæ•¿J»ª=•¤¢Í'&?ßù„_Ôz ¯¢éƒTÔá·iã·óÛ ,Ÿuj9Õ®ËPÖÈ­Eßjå™'¹« €.ÅÁ©ý‡·ó§Él¶ÒÉ :È•2/Ý|qíüéñCæ`º88ϵWˆØ¡óz”~¾ÕzÚÔ¹qïÓð§[Z–8ÇÓ §Ý\Sx}æÏJÍË¡J#'”–B '©5@1BŽŠz“êjÖ‘¨Ë£_Eu]Ñ aÜc&«êº‹K<³HA’f,Ä O ©»½‹QV$´’ÉZa{,ñ¨Œ”1®I~ÃéUô­5®O0Ú:éF›§äJUä/§¿Öµà„N7`¬iÛ»Rr·R”zX[HÛ˜€±"œZ†i ¸8è­[µc<’€>_)°~*¡R‡CÉôZÉKRœtDoˆ#Ïä)mô‹‹Û)î’2Ð[ÿ¬lã£(I¹ïïV-^hátÈ‘I‚Èê)¹>ƒŒR <*ÀŒúdóŠ–(à9É5) ' Oò©s‰UÀzÇñÅEm$èÇî«îy«Ab˜å–LCW-í­TVaqÅC‹PîU·´YB‘ÐÿJ½id_Nº]Tc¢Ó±fØÊN÷Øi-fºN@@èÝ}«ž­k#zT®õgii ¦ç’Bávtêy­ØÙ^j e™¤(r»—o5¡öI/¥;&êrsÁ¦Ù-¸½‡bÊ¡OŽ8¢mÊ/qÁ%"=I´‡Qd†gX‡ ÈëP[ØÃöiöÊì0:¦;ýjtä’2Ÿ^kBÇÃÒϧÌñƒµ€Ûž Á¡Ë•jÁG™Ý#ËRÔ±#SÞžcÜ6ªàU¶ˆžg4‚.5ë¹W!U£òÁœÕïë>¼yíŒbGCÞ¡† 1-¶äŸ¼åRElf”(JM4ÓSNè«»\188''¶jôvÂP88ÏÒ¥ŽÜF€ô¢ñ~HÎHR™>üšN` T™÷®2BÌÒ›bâ)pW…üMJ- ì>A÷G­\žÛd6ÌFY£ééɤçªR¢DW’vý*dˆ¦prÝÍJ';SéSA¨ß !wÿõÔ¹E†Ü"y£ îiáYä£öÇDÿëÕÝaín/¬£’4 ×繨ã„Ä$Öj¥ÕÍ;;]^O}°Ï+ÊÈ6‚OAM "8'{S‚yK’AcÓ=½êbÎA$ûÔ®ÈmuceÌÔK‰Â?Ztp™:sD¤9(¼ÔúûSæè%’±›ä\„HïíBôgüªEB¸ÎôéPK!›(¿w¹¦ŸA8ÌÆà•\íýi<¬`z ˜ AÇáïRÛZ–%˜p:Ÿðªæ°”­l‹ÌpSëV¼°äq„©û =>´JÛ8{üóPäÙJ#šMƒ ÷ÏOQT¦–(‡æ=O¥O3òQNºœT$Q!_=Pž§i9«‹%Æävà%ô1/Fq“œ–¨l¬ |î' ô®‡Á^·¾Õ§¹VòþdJ‘ùö¨µ› {¹!Žé )ãå$ŸÇ½ºçq`ùTŒ¹XF¸ Ô •òA ô÷ÿëU–·I>r¸>ŠÃ?ýj—ºå‹1<`¿ýjÕLÏ]1­m.‘®â’xX¢¬Ç·áTaæÙ`çמ¿çëSÈðïiIo@9© ·² šà»{)s$î­è&‹hÑjöûŽæfàŽ˜Å0[îI*ªÇqîO§ÖºßÁ§‰Ÿ-#°à ÝJç;ƒ+ÈÛ«X-Œ­œqOŠ#dn$úâ®Ám‘€0¢©ÈJ,l0 wõ©%•`C“Óó§LËõ ΪÌù8>ƒÒ¥;”fwÉëÛýšId»W6§I EÀ'ŸÌÔR,Á”ŽžŸýz¥ åpM´`’ žzãÛëN±²$ù’»¨ø}ê{}=¤··‘Ôî%ˆ·#š‘ù8*'Ö’rŽk¹eµX<Ç6èÛ• ùsëU¥pU™‰X׿sO‚ $ˆ×¯©ª2ý­·>Vè?½DW`i‘ÜNnŽ÷À‰~â÷5=‰™¼Ù†è=)ÖvvóeùUz¬ÈL„¨à n](‘ÊÆ\.6¨è*ä0å–è}ªiŸÊG zûT°,Änÿ»ÿס0å"“m¤lIùÇSÝúõœïç0‘Ô”q:oÿë:švóÈwÇœ"ÿÿ­ïþKD&F,Ç9êz z}*“°(—¼+im¨j#P»û,/n—èF°¬Y3¨ÊPûMë2.D`ž›úUë[1‚W ~êúõé^Í»–Ö‰Xváù¼4È»¶¨ ž^ÀIcÇý¾•nÆö}*F’ÞW‰Ül%OÞ·ÓÞªLĹۯøT©;êŠÚ³vŽYÎ éŸþµ-Ê äÝ)béŽjÍ–žóMqÆÒ]È@U–ÿ ]kK›OÕîRdq3HHgž O´ÖÅ*n×+é—[ÛÝÇ5ªÝOr›c±õ´ÅˆF . <3ŸAþ5(‹Ê†<1§¨ÔÓ’Ä((êqú •î>^„qAæp '½_¶´ µ@-­±8  ?*–âqn¢(ð\õ>•2—A¨ ¹¸¯•ˆäÿvªª.ÐH%GOW4å‹#œì'ñsI4‚ Ia»ô7±J.n IûÇô¤Ó´É/K"¶ÁÐSNÓôãxâI:üëVDÃm‰zŸïRs¶Å( %ÈF/·Þ©ÚÆáÈÙ€½1LwÝ€ ½©¤²ð\û𵓓-E¾ðŒ·±Ë)S²ÇkûB¹µâ3"[Œ¿¿Ò®hüúx!rc³dõ'~•EÙõ Zff ܰÏßÿ­XÅÏ™ÝèlãUdFºTÀ‚ñ²Ú¦[9©ö¥ŠÝ›Î=*ÊÆ!'“Z9ʈá‡Ë‘A“U™LÌxàUÛxÌ—‘v—Ο˜Q½°éSÌ5-0¡˜c½*B›~•1#S£‹1ô¤ä52(DJ€Ýü+SG+€óŒóïQ¸.pG_J’Þ<Ṳ̀N*$ô.+R˨RpGCëíRÙ´‘Ü àÍ9 8ÀTÑEµ—8ÈüéI"$šc€¿JØÓ¼A$|‰ƒ!LÝ3Y«##± [m$À#'~œÒ{¢àÚêp?g ÀàšÔdœdþ•wÈ?Ý?f$àùשÎyÜ…1lÓùÕË @·0€ úô©á†44e‰÷5£ ÜÙÚjP¼¶Î鸽OcjÎu´.4îìÙˆÖæHË…_½Ï&¥¸ÒÞà[UÇ”€î}ëRI,/55-§HÙø°zbµ|S–tø<„$…G€vç¿¶k'Y¦•‹TU›¹ÎC£H$TÄL1}zÖÖ»àçÒì-¥$¬o$(êNyëÖ²Ö h˜8Y‹Fqǽ]½ºk«kq4’ÉNƒÎO?Z%)]Y„c;£R"‚ÝK1ùîÿõë>bnNöȈ*ƒËšžv7<°" >”Ï)¤9aùpØUs @a2±f#=`=‡µA 7„¢!O÷¿úÕjT7gËBDCïZ·kd!PHåýis” Ckd° b0…}?úõ9@§s œc¯è?Æ¥‘–n§ñü)’™äî>½…'1(É!!yvãŽÞÔ$Ïb›÷¹‘‡1©+n¡ØeÛ –ÅË1Ë·ä)9 M¦kwºuäs­Ä­0 €X•_ÃúU½wZ»Ôu9ØÏ •\¯ÊÄ(Pzz¤‰ä«àò»ÿ×þU,±ï¹“oBÄ“éÍdíÍ{+ÚÄ*ÒÊv™Ôî?•X·³.@äëÎ*K{}Ä0?•M<‚Ñ|´ÁsúSr)î-”G.J¨±‚ É+ßÕJ¶Ï0f î‹Ë²‚sþ’Od€1Û°¥Ì5)¥N2Gà)–VM}(w äßÜÔ¶º{^˹²r=ëN+a'ʹX‡Þ>´œÊJÄPÛ™ÉUâ%ê}jf$€ª0‚¥`…Pjk‘ÉÎóÐzTó‰þà›ÏOj€¡pF~SÔúÿõªB rO_Öœ±yœç )9¢;N@^F8Ûå·ãÅ>ŽAtõ©m¡9ou5aa)9Á©r(Ћd“L2#òcÈíN|Éœr¢¥‚Ôǧ­K‘JßIoo|²I x1oÇjSAstï8Œž>b?Jeª“:±ÎühHO9g§­e§5Í5µˆÒ4 /·Ìi® 7Ê1üªÃ($Œd –Î(¼ôX‰ù¶õNVBšÛð@¥†"q“Î*iŒ%ùr9"œ±T9‘Å…ÀÊ´Œ|£?J—ËÜÀ€H§ª•èH·JNCQ!HÀÆAþupXȶˆÂ³g>ÔÔiAwëVþß+Y*ÀFGZ–ÙQHáü‚3ŽM/‘´€M]òqÀ#šCNÁ?¥ws*%)#8=MÑæâ6ä`ZµäùÓÖÜ‚‡!ÙmB=}ÿúÕ=•pV>?3RùäM>Hƒ*’x¿ÔÒl,Táòßuzš|êdX°2Uxœžjf]Àdp: ‘" Ü(¸(•ã€Ç“Œ“RGL3a½­L¨žŸZgÜ6±Òr6ÚÖKƔƭ œã’8ªëoÎÐF{‘ü«[IÕ¦²2ª}ÊrHà*´÷OÈV$žI㊅'{⬬TpäLdu>”G@;f§Pp $ž”ɘ’@ëÞ­2yJó±o•r}M1a ¹9 þµaa ¹'"Ÿ¿˜ÃXQµru©U®ùjK{'ºó<½¤Æ¥ÎN8©s]F¡ÐªøŒp ÏoZ¯1 à|ÎÕbFÁÇÞcP¸‚rK¦šbå*ÊD ‚Ifê¥2C+làp­ZŽÔÉ‚GËØTíO¯òªæ)YF©ã?ÐT ‡¶?Ï­4e›€@S–$Œcµ AÊW,#qÿëýC&Kd‘ŸÐU™TòH¥F¶ý =…5 å+¬ ™‹FQîÇš³ ŽlîYB¤0Éý+NÀiçC¸Yb˜\åvrÞ»yéëÖ¦U,\ s¦î2>ŸÝö¨eÍÃùhŒ}æõö«ó$S9Ž5˜÷˜¸?‡J– =#ÚBŽ‚©L9J¶ÖkFè?­O³fê?Oo­X%˜Géÿצ:„çaÐzõé9 D­!ÙÆ>cØv¦Ä(òÄôib)w' ëQùm#nXôô¹ŠQ*šG,Ç,ñÚ“È11 ç¾3·ÿ¯üªÏ•å‚!Ï?îÿõéV.Ê1Ž§Ò—8ÔJñÚŸº¸u=jÌ6…˜Ï546Ý”žF‰µysG8ùHg"Í %Û·§½UòÁ'¾O'»{Tæ2Ä–9õ=ϰ¤dÀ# ô©æˆ‘jØA4qÈQ.k¨ÆzUk{6¼—';:óÞ§ŽÍ®[vÕèí³˜ÔaGSK›±\¤QBäL*§+`«ò¨©|¬(ETPÉå€Hç°î)9‚  cÐzT;ZCÎsÞ¬y[óÇãNX‹ñü"¥Ì¥º@_‚FO¹b0¼UËkHd¶•žFYŠ!ý~•$p„êisŽÄPÀ#¸Óvù‡àTìã*)ÑÄXå†ó¥Ì4™¡È$`TÊ›‡U Oô¥9c'’ Š–ÁD³¦i‚ëÌc".ÁëœÕvŒp&=š¤Œ\0¿—JAzƒ“úÔ&îU•ˆ‚mëJ°y9b(†Ó•$ƒNÙÆÓNà‘CÈ=ô©`³k‰ Æ»ˆãµH"´øƒBÙRUºqÅKcDB“ÀuåŒÓ50A‚Ô‹pH.a¤WX¾Px{T¾WÈÎ3õ©x#špCÈjM#šº±–Õ‚Ê…KÃ8äT^H< Þ¯´M!ç-SšÆA*ԹÔ¬T:Ôr0HË´ë³=Øö¨š ™<?¥5 å*ºÇûG©ô¨ÒØÈAaòÕÄ·ó$ Rù!@8?¥>`å*ù{`•DÈ[ «F-ç¡ý)ËndŒÚŽar•D;$àΙ '’0{U§@NHÉ¥0[‚I?‡½ AÈTò‰99úSÄ'pÈåVE¹''9>Ôè ÌÈ9<ŠnaÈTòÉtü©v…Œ~µcÈÀ¦¼$r9ò£œ\…v%ˆýi‚"ý@Õ“b©ÔŒ`ió‡!ØÞ ÈÈÄg`Ó¶„R@8«SK%Ö•‹¶1“ÔJ®èdÁ’“!]€sŽHíC(@}•Nb(§ ‚i¦.‡)ó!NN3Øcõ¥„´„1 ÷G5(¶2¶H898õ©<¡ŒŒÓæQRéÁDx“°V–¥â#w§E¢©`y 0k-ã8Ú8 Ks’Þ%AÏçYÊ)´Ú*7I¤WšñÜíÄjS°Th†àƒ„ ?Ù:Ûy˜R¥HclPp+E"\H¥…¢`ŒŒðWûÓÀ-Vî¦{†#4ŽF2{U$îÉšJ}ÁDZÀ£q䚯)ó˜òB§¹«r¡”H :šbÛ–8t”s@¨b,GË€:Oþ½ Á$kÀ%r:³$D‹ŸsRAd3žýi9D©˜ Ö¥œ’r1úõêзîF?¥:+7¸,HÎä Ÿ­cä(È9 dt”ÁL;‚}­\û0\³‚ìzÓLùlgÓÒ—8(š&vÜÞð§-¿—ŒXþžõpC·«ÓÞ—É*@êOZNcH¦-ˆÆÉäûT±ZtÀëÞ®-®€ “`·QŽXö£œv+2 U ³t¨<Œ’I=O¥YØI$“¸õ>”úAÞ¥Èjfˆ"‚G ¦ÇnndaGëVVØÌãƒïïVÜ€A¹¥Ì>Rí‡Ü\:š“`Qµ@P:ÔÂ=ªxÖ&ÑÈÁ¨r"Fp ì*2…É'$Žþ•cË.ÜIïעܜ€“ìW[}ØÀ t©#€ d °!ãô©’ £8É¥q‘G^xÏò ¦ì€0¿Î§hËc8œ¶û@&ÂÄÁžHÂÔ¡28§X8ÿ*p€`:N@‘B[ØT‹ÆÁ©¼¸àSÖ<H'õ£˜i,$g dŒS„ °æ§ž˜À§*`ñ‚O3)Àq‘œSÄ@H#53F1H4¸ãކÔËùs‚@ü*EŒ ¤ÓÂßà§Ð‚ WC;Ëä’iþ^:“jr¨À$Òr T`½/”1É$TŠ„ç$ŠU@9 ä~5-ŒÂû>:cµ/”zdš¼a#$íMòNO'>¸­”ŒìRò|ŸZý2\hNÆqí@·ž¡È,Rð Ïó§,[I'“W<ßœR9Î2=(æ Ú"Néڛ壒}êï1€9>Ô†¼¾†Ž`±P¡N˜Ïäi ÷æ­‹~{šW‹±ü(æŠL§dóMç®2 hÜâåÔìTcŽõ¶ÝƒíB4T[rOzFQN^õkÈÞ“ÉÀÈ4s Åc$ jk€N 5i¢Æ0OéLû>2:úQÌ4Š… ä’K*ArO;jÚ[9À§}Ÿ€Gô¢áb¯–W  Ò˜ÈXñÀlÞ1€!@¶À…>aYV “Me$ç*ãA»ÔcÚ˜mÎNA P¤ ’@æ”DH5oìç= úÐmñŽ1š9ƒ”¬-dnƒ#êYÓô·žáx ç$õ¤6ç cô©mCp…IRN è“cŠW*ÜéÒ[ÈÈW8=r*lÃ9SùÕ¦ˆÎŘ’ç¹ï@·íŒŸ¦)¦ÄâŠÂ cŽEH#Uà“šŸÊ 2S ‚;Qv.R³)“ â—É ×Š°aÛÈ4ß+'$øÓæaÊVdÉÆ  ü‘•cÈÞqŒš9ƒ”¯äœá@8ïM0íÈгäà` ÊšÑg*&Ž`å*²àpzpƒÌUeGøÕ…¶ì"žbÀÅ+‡)XÄàëH# É?Xò€Çµ4A“’3íO˜9JþX<œZŠ@]±È©«oüã8ñL0ãàP¤5( EˆÐ«‰j“üÿZ‚HÉm«Oz¸`8ŸåBÙ€AÒ¸X©¨U€ó©3Ü?•[nÀÆ3H`999˜r•9Šu¬’ZK棴l8È«ض7 Cn[Ž; NCH¤Ñ4ŽÉ¥ÏRy«¿gÇ¡'Û­Û8É4¹‚̦°sœ“œÓ’Û¶3ŸÂ®¥°$=鿨AÎõ¡H,W–! 1 $ƒÉ.ÄòXõ>•¡4;¢‹'’>œÓ<€«È8=èæ)Kìç1Ò“ìÅÎN~µ¥w!¿hþDP‹·åÍ5möð8jžf7¤vÇõ'ÙÊàŸëV„;Wä÷ÍPÇ :|ÂQ*ýŸààQän<öý*ו»’}=(žF1Ÿz\Å(•Ä9$tÅ*ÁÆëùU‘ÑŽ˜íOX†F@Ò¸$24E€¡K–wp=)» güêsH~¾ô¾I8€(L,B°ï8ãJ&;àj˜D8!r)VÀÚ‹Œ„B} Ç­;ÊðpMK³ƒÎiÉŒŒûÒr%NÀdþTॺœf¥ØCNGÖ•dš\ÀFª gÞå“è©V3€O4ñ’I"‡ #ä)4¢2xÀÔ‹ `` pÔšM€ÀƒžipHàSªð¥Á,0)ÕŒO&—“Å8FxÉÅ9Ps@X`Œ Ò„'¯òqÚŽO@M D«åõ$0Å5ãÜ0Çó«F0zÍONGµ>`å*Cc“J#ì1ùUŸ$Žy…9‡J9‚ÅcF>Ô‰ŒRWÚ¬˜ÎI$géIåäþT)Ec`9ýEÜjÏ’;#Þƒ 訣˜VeVLd`ƒéšiŒ“€M[“ÇÌ)€#¨õ£™ŽÅ_'<3éOXJö95gÈëÇ?ZO$úΚ“Šæ,sȦ˜ö瓟J´bÀ9®i G' dt£˜,UòÉÉÇ?¡¤0g±õÏz² Üs·"”Û€:(æ ¼ : Iå'‚*Ï““ÀÎ;Ñäœgß­Áb²Àb).Ý1V|¯@Æ“Ê'±¡H,V0Œp(ò±ÐV„9çð£Ê逨4sSÉÀü¨ò†@Ê­ùDr?ÒlÏ$ý(比9 ,0< {Õ†w<SÄÓ4ù…bª[‚zr(ǽ\†×.BïMkr2¥Ì¥F„ç ÅAëŒÕ³…#ŽEP'îŽ}é©ЦÄ ±lñÖ¬˜½Sõ£ÉèNÓŽ¾ô9ŠÂŒŒR ld`U±…4ÄTwÏçG0¹J†‚à÷¡m†@Œ~µoÊ,ÜGåJ°‘7!Ù¼Œ E!ƒoQÁ«MÁàgÚƒ=›¹…ÊShFr@Å!ŒgŒqíVš x"‘ $rühæH«äŒ)¯U¶ˆ‚É?¥(‡ž„ëG0X¨–»@àÓ„ ôV|žr:z 9À÷¢áb£AŽØþtrFjÑ„’3ž)6ÕN(æ L[²ôÍ"=I«féŒv Â@ç$ý)9 «±w ªYëKöFV*T’*ÒEŒG§å„}ày÷£˜ ëhÈ ÚIþtGe#È©Ã~©¼—$’yú朑˜È G¿ZNLi¹Ò6B„ÛOZ¤öråO5£4Í$J§#š„BËÁ³I7Ômv+ 6Q÷HÅIö…¡ûõÅJ Ú0I¾Yc‘Mɉ"»Û,r°2¯Fé¦0} üª×’§“Éõ D;dþ6+¼¡Ð ZU‰{…YE4«n1ƒÉüé”®!dIö§lÉlj°" yÀÏ¥xÎ(™ŒŒŽüÓ–< gõ©Œ`s´ŠP§åâ€ådF5õjQ8Â’z”!Æ"•QqÎ úÑpå"ÚFÏéFÎzƒúÔáTpIüivžÊh¸r‘ãIà…#¤ ÝÆ(Ø}Å‘’HåˆÇ¥*D0 #½H#òM8!Ñq¨ŒOSŠ_,{švÂÝp)Dg±¤ä¢ Ð@Á8šw–£’2}é@Æ'!ØhRz RˆÉê*q  RmŒhE)‚F{Ò…'¶)_,{Š<¡ê:u iˆc‚A¤òÈêM>ŠaˆƒsH"$òÏSRQ@¬Fc#¶E7ÊôV5\d"#Ø6iD'¸5-\¼ŸöGçHc yššŠƒËä’(S“ô©è§p±E©l=2¸©ð=‚‹±X€&N 4ÁèEXÚ1Œ Rykè(¸È<¢„Æ“É9?(üêÆÅëG–¾‚‹°+˜ŽOÊ4sü TþRúQå/§ëEØ4AåãøH4žYì`Æ= ?Z<¡ê:.Åb$žÄþ8£Éƒó©Äc¸É Æ;ph»ˆ@œà{ÒyXwzš°#É4y\žN Ì,WØ:’@£ÊÀɧò‰êGåA„`€y§ÌÁ"¸‡#ê(0ñ’J±äðyæƒãZ9…ÊV1€;ÓD<ã>µkÊ<£šEqŒQÌ;"¿tâ zV<£×‘Hb$ä¯ëG0”J§“jSÀàñSùC²°£Êõ G0ry²þ´žA9ã÷«W j dx †‘_ìÃû´aŽ©Ìdu-ùR„r £˜+y$×ò£Ë8Î=qV|µô"“`ÏS­À‘XFXôÀ¥ò‡QŒý*ÁAØäÔžJ°é‚(æ_ÈçŒÑåÈÁ5gìëIäxÍ% !ÙŒnMƒ‚@È«^Vz“H"Ã@ù…b·¼r(0ƒß9«>QìA“ÉN 4®2Ȥc P#^rO5a¡šƒŒÐ¤qŽüÑ厄‚*Ç—ØùQäúÒ‹ˆ¯±}ÇãFÀ½ŠŸÊÁää})Â1ïŠ.}‹èMWÐV c±9¤)Œgš.!2Š]§²ŸÊ¥ƒÔäRùkž”&!Äç¥9cÎHüªO(zŸÎ”F¾™¢áb#ž1NÛÐcö§ùkè(&ÈÆ1ŸZQ“Ð*L:`Å4ÂÄdÀÐv¤ Ä€@4ù˜Xj¦Ñ“Ö—ßó§ùC± Ñåä‘R+ ÇrhÜ=Eûÿÿÿÿÿÿÿÿÿÿÿÿú>IþÿÿÿÿÿÿÿÿÿÿÿÿþIKýÿÿÿÿÿÿÿÿÿÿÿÿýK@öÿÿÿÿÿÿÿÿÿÿÿÿõ@(ÒþÿÿÿÿÿÿÿÿÿÿþÑ(€èÿÿÿÿÿÿÿÿÿÿç~*³åÿÿÿÿÿÿÿÿå²*0°á÷ÿÿÿÿ÷à®0)ŠÐðùùðω)1JWWJ1il32OÇ JÏïúýÿÿýúïÎJhãûýýƒüýýûãhŒÃùý‰üýùÊÙýýü‡ûüûûýýÙˆÖýüûüýÖ†»ýüûýŒûýüý»„aöýûýûýöaƒÛüƒûýˆûýüÛ‚=øûüû€üýÿý‡üûýø=Àüüûüþ‚ÿ‡üûüüÀëüû€üýþ‚ÿþþ€ÿþ‚üûüüëöý€üýÿýýþþƒÿƒüýöûû€ü€ÿþý€þ„ÿþƒüûÿü€þýˆÿþƒüÿý„üþƒÿýüþÿÿþƒüýû„üþ‚ÿüý€ÿþüûõüýüþ‚ÿüüþþüüÿüüýüõãù‚ü‚ÿ€üþÿüüÿ€üùã±øýüÿý€üþ„ÿüüýø±BõûüýþþƒýƒþýüüûõB‚Òø‘ýüýøÒƒYðùýüùðY„µõúüŒýüýúõµ†ÌõúŒýüúṏÌõøüýüˆýøõÌŠ±ðôúýü‚ýúôð±ŒUÑô÷öøûýýûøõ÷ôÑU <¶áòùýýùòá¶<ÇÇ JÏïúýÿÿýúïÏJhåûñã×ÒÑÑÒ×ãñûåhŒÃúìÖÏÐÏ„ÐÖìúÊÙöÝχÍÏÍÍÝöÙˆØóÓ̉ˀÌÓó؆»ôÓÈÊ‹ÈÊÊÓô»„aöÚ€ÆÅÅÄÁÁÂ…ÅÆÇÇÚöaƒ ÛéÅÄÄÂÂÀÈàáÍÀ…ÂÄÅÅéÛ‚=øÎÁÀ¿¿¼Éøÿÿûϼ¿¼½‚¿ÁÂÎø=Àë¿¿½¼¹´åÿñ¸»ÃÁ¹º€¼½½¿ëÀëÙ»º¹¶ÔçøÿâÌïúøæÀ¶€¹»»ÙëöÆ·¶°Ç€ÿìÖ×áÏýÿòº´µµ¶¹Çö ûºµ°Á÷ÿÿÜÍæâÃìƒÿÕ­±±³µºûÿ´±®¶ËÊÅ΀ÿþþƒÿ䨮¯®±³ÿý¯®«ª§§£ç‚ÿ øÐÁÚÿÿà°¨ª«¯¯ýû±«©€¨ áÿô¶«©ÐÿôùÕ¦©«²ûõ½¨¦¤¤¡Èö€ÿô²›¸ã¥©ú€ÿ¸£¨½õã̤£¡žªý€ÿô¯œ›Ûð¡¹ý€ÿ¿¢¥Îã±à¢¢ ¡îÿÿ󮙞™Ãÿúÿ𣢢ౠBõ¸ œ›—¦ÐШ–€› šÀÙ×Ö×ϧœž¸õB‚ ÒÖœš™•’’•™ —“’““’’™œÖÒƒYðÀ™™–‹•–™šÀðY„µå³–•”‰“”–—µåµ†ÌÞ²””’’…’’”•²Þ̈ Ì帔’“‘ހޓ’•¸äÌŠ±ðÏ­‘¬Ïð±ŒUÑô×¼¦™’’š¦¼×ôÑU <¶áòùýýùòá¶<ÇÇ JÒïúýÿÿýúïÏJhåúÈ‘jYTTYj‘ÈúåhŒÆú¶jRSSRƒSj¶úÆŠ Ùã‚QRRQPPOOPPQãÙˆØÖhPPNN…MNOPPhÖØ†»áiNNL‰KLNNhỄ aøMMKJJF@@D…JKMLøaƒÛµJJIGHAY—œbAGGHHGIJKµÛ‚=øiHHEF@]éÿÿòo?DAAEF€EHIiø=ÀÃGFDC;3¯ÿÔ:AUP=?DCCDGGÃÀëDCA=µëÿªlÏñêµP:€ACDëöeAA5e€ÿÇŽ‘«{öÿÙG;??ABeö ýK@9\æÿÿ¢z¸­`ȃÿŽ3<<=@Kýÿ@>9Iyxj}€ÿûüƒÿ¶.9::>@ÿÿ>;95/.(½‚ÿ ê‡džþÿ®A169;>ÿûG96565(±ÿâP$;7Šÿäï”169Hûõa7433.yç€ÿâM$Yº5;ñ€ÿZ17aõãŠ531-Aù€ÿâK('¦Û2^ù€ÿk05‰ã±º330,4ÕÿÿâJ&0'uÿòÿÛ733º±Bõb0/.(A’’C&.-,,s§£ £@,0aõB‚Ò¥1/-,'""',++,*#‚"*/2¥ÒƒYðy-++‡*)++-yðY„µÒ`,()‰()),aÒµ†ÌÁ^**'(…'(&**_Á̈ÌÐq,((‚%$$&((,qÐÌŠ±ðY'€( '(''('Zžð±ŒUÑó±xT8+,9Tx±óÑU <¶áòùýýùòá¶<Çl8mk%19<<91%V½íûþÿÿþûí½VSØüÿÿÿÿÿÿÿÿÿÿüØS#«øÿÿÿÿÿÿÿÿÿÿÿÿÿÿø«#'ÆüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÆ'%ÅüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÅ%§ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû§VõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõVÎþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÎ`øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø`¹üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü¹,çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç,>÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷>JüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüJSþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþSSýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýSNûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûNBóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóB/ÝúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÝ/®õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ® TïþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþïT *¾òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò¾*[æøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøæ[&œêüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüêœ&2±êúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúê±22°èôÿÿÿÿÿÿÿÿÿÿÿÿÿÿôè°23›äëùÿÿÿÿÿÿÿÿÿÿùëä›3 *YºëìïøüÿÿüøïìëºY* 1T¢ÏèõúúõèÏ¢T1 '4@HNNH@4'   it32$5ÿÿÿÿÿ¨H¯ÎÞäêïóõöùùöõóïêäÞίHãœÑåñø‘ùøñåÑ¡Û*½ßñ›ùñß½*Õ¸ãô¡ùôã¸ÐaÕðˆùúûúü‰ûüúûúˆùðÖaË…ßõ†ùûú•ûúû†ùõß…Çsàø„ùúú„ûü„ûúú„ùøàsÃ?Ùõ„ùƒû™üƒû„ùõØ?ÀÃñƒùúúûŸüûúúƒùñýyçƒùúû¥üûúƒùçyº¿ó‚ùúû©üûú‚ùó¿·6áƒùú€û­ü€ûúƒùá6´„îƒù·ûƒù®õ‚ù»û‚ùõ³°Åöùú½ûúùöÅ®Òøùú¿ûúùøÑ¬Ô‚ùÃû‚ùتԂùÅû‚ùÔ¨ÍùúÇûúùͦ¿ø€ùúÉûú€ùø¿¤£ö€ùúËûú€ùö£¢rõùÍûùõr +éùÏûùé+ŸÙùÑûùÙž­ùúÑûúù­œVñùÓûùôV›ÜùÕûùÜš¤ù×ûù¤˜"î€ùÙû€ùî"—ÂùÙûù–Hô€ùÛû€ùôK•Ì€ùúÛûú€ùÌ”Oõ€ùœûýý‚ÿýýµû€ùõO“Åùšûýˆÿý³ûùÅ’3ó€ù™ûýŒÿý²û€ùó3‘°€ùú˜ûýŽÿý±ûú€ù³æ€ùûû—üÿ°üûû€ùæ}ùû—ü‘ÿý°üûú€ù}È€ùú—üý’ÿý°üú€ùÈŽî€ùû—ü”ÿ°üû€ùî‚€ùúû—ü”ÿ°üûú€ù‚Á€ùú—üý”ÿý°üú€ùÀå€ùû—üý”ÿý†üƒý¡üû€ùåŒP€ùúû—üþ”ÿýƒüý‡ÿýýüûú€ùP‹”€ùû’üýþ€ÿý•ÿýüýŒÿýœüû€ù•‹À€ùúüý›ÿý€üýÿý›üú€ùÀ‹ß€ùûüý›ÿý€üý’ÿšüû€ùߊõ€ùûŽüý›ÿþ€ü•ÿ™üû€ùõ‰[ùüœÿ€üþ–ÿ™üùZ‰†€ùûŽüýÿþýüýýÿýüüý—ÿþ˜üû€ù†‰¢€ùúŽüŽÿýˆüþÿ€ü™ÿý—üú€ù¢‰»€ùúŽüŒÿýŽüþšÿ—üú€ùº‰É€ùû‹üýþý‹ÿ‚üýý€þýý„ü›ÿý–üû€ùɉـùûŠüþÿüý†ÿþüý›ÿþ–üû€ùÙ‰ä€ùûŠüÿüŠÿýüüÿ–üû€ùä‰ì€ù‹üŒÿý€üŒÿþüÿý–ü€ùì‰ñ€ù‹üý‹ÿ€üŽÿþÿý–ü€ùñ‰ùœü°ÿþ–üù‰ù›üý°ÿþ–üù‰ð€ù›ü±ÿþ–ü€ùð‰ì€ù›ü±ÿþ–ü€ùì‰ã€ùšüþœÿþýüüýþŒÿþ–ü€ùá‰Ô€ùû™üþšÿ‡üþ‰ÿý•üû€ùԉĀùû™üþ˜ÿþŠüˆÿ–üû€ùĉ±€ùú™üþ—ÿü‡ÿüÿþüú€ù¯‰‘€ùú™üþ–ÿü…ÿþþƒÿþŽüú€ù‘‰sùšü•ÿüþ„ÿþ†ÿüùs‰E€ùúšü”ÿ’üÿŒüú€ùC‰ô€ùšüþ’ÿ‰üþ€ÿþ‚üþŽÿþ‹ü€ùôŠØ€ùû—üþ“ÿ‰üÿ…üÿŠüû€ùØ‹¬€ùú•üþ”ÿ‰üÿ†üÿþ‰üú€ù¬‹wù”üþ”ÿ‰üþ€ÿþ†üþŽÿþ‰üùt‹5ù”ü”ÿŠüÿþ†üþÿ‰üù2ŒÜ€ùû’üþ“ÿþ‰üþÿþ†üþÿˆüû€ùÞ£€ùú’ü“ÿþŠü‚ÿþ†üÿˆüú€ù£Vù‘üþ’ÿþ‹üƒÿþ„üþÿˆüùV ç€ùûüþ‘ÿþŒü„ÿý‚üþÿþ‡üû€ùç Ž¨ùüýÿýü…ÿþ’ÿþ‡üú€ù¨Lù‘üÿýŽüþÿˆüùLÕ€ùúüþÿýüýœÿþ‡üú€ùÕ‘~€ùøüýŒÿþ‘üþšÿþˆüø€ù€‘ì€ùû‘ýŠÿþ“ýþ˜ÿþˆýû€ùì’—€ùúü‘ýþ†ÿþ–ýþ–ÿþˆýüú€ù—“!ó€ùû“ýþ‚ÿþšýþ‘ÿþþŠýû€ùó!”œ€ùøüÙýüø€ùœ•ï€ùúÙýú€ùï–‰ùü×ýüù‰—Þù×ýùÞ˜YùûÕýûùYš²ùüÓýüù²›é€ùúüÑýüú€ùêœ]ùúÑýúù[ž¢ùûÏýúù¢Ÿ ÎùûÍýûùÎ  $ëùüËýüùë$¢CôùüÉýüùôF¤føùüÇýüùøf¦|‚ùüÅýü‚ù}¨ˆ‚ùûÃýû‚ùˆªˆ‚ùûÁýû‚ùˆ¬zøùú¿ýúùø{®bôùúü»ýüúùôb°Bë‚ùû¹ýû‚ùëB²"΃ùüµýüƒùÍ"´ ›ƒùú³ýúƒù› ·Uç‚ùøû¯ýûø‚ùçUº«ƒùúû«ýûúƒù«½PÙƒùúû§ýûúƒùÙPÀ |ï„ùúü¡ýüú„ùï| Ãñ„ùøúü›ýüúú„ùñÇŒé‡ùûü“ýüû‡ùéŒËnΈù€úû€üƒý€üû€úˆùÎnÏ9•ä¡ùä•9ÔBÔ›ùÔBÛ!Z“Ìô‘ùôÌ“Z#ã ,Pq’­ÄÙæîùùîæÙÄ­’qP, ÿÿÿÿÿÿÿ¤ÿÿÿÿÿ¨H¯ÎÞäêïóõöùùöõóïêäÞίHãœÑåñø‘ùøñåÑ¡Û*½ßñ›ùñß½*Õ¸ãô¡ùôã¸ÐaÕð‡ùøìßÖÐËÉÆÅÅÄÄÅÅÆÉËÐÖßìø‡ùðÖaË…ßõ…ùôàÒÉÄÅÈÉɃÊÉÉÈÅÄÉÒàô…ùõß…Çsàø„ù ñØÊÄÄÅÈÊÌÏÐ ÏÌÊÈÅÄÄÊØñ„ùøàsÃ?ÙõƒùõÜÊÄÄÈËÏ—ÐÏËÈÄÄÊÜõƒùõØ?ÀÃñƒùíÑÅÄÈËÏÐÏËÈÄÅÑíƒùñýyçƒùëÌÄÅÊ¥ÏÊÅÄÌêƒùçyº¿ó‚ùíÌÄÆË©ÏËÆÄÌí‚ùó¿·6á‚ùôÒÄÆË­ÏËÆÄÒô‚ùá6´„î‚ùàÅÅ˱ÍËÅÅà‚ù®õùôÎÄɵÍÉÄÎôùõ³°ÅöùåÅÆË·ÍËÆÅåùöÅ®Òøù×ÄÉ»ÌÉÄ×ùøÑ¬ÔùöÎÅʽÌÊÅÎöùتÔùòÉÆÁËÆÉòùÔ¨ÍùðÆÆÃËÆÆðùͦ¿ø€ùíÅÈÅÊÈÅí€ùø¿¤£ö€ùðÆÇÇÊÇÆð€ùö£¢rõ€ùòÆÇÉÈÇÆò€ùõr +é€ùõÈÆËÈÆÈõ€ùé+ŸÙ€ù÷ËÆÍÈÆË÷€ùÙž­ùÕÅÏÇÅÕù­œVñ€ùâÅÑÆÅâ€ùôV›Ü€ùñÕÆñ€ùÜš¤ùÊÕÅÊù¤˜"î€ùÜ×ÅÜ€ùî"—€ùòÆ×ÄÆñ€ù–Hô€ùÎÙÄ΀ùôK•Ì€ùçÅÙÂÅç€ùÌ”Oõ€ùÊšÂ ÅØê÷ÿÿþ÷ê×ijÂÊ€ùõO“Å€ùäĘÁÂÜú†ÿùÛ±ÁÄã€ùÅ’3ó€ùÊÁ—ÀÈóŠÿñǰÀÁÊ€ùó3‘°€ùæÃ—ÀËùŒÿøÈ°ÀÃæ€ù³æ€ùÌ—¿ÅøŽÿõ°¿Ì€ùæ}€ùòÄ—¿ìÿè°¿Äñ€ù}È€ù×—½Ï’ÿͰ½Õ€ùÈŽî€ùÊ—¼î’ÿ밼ɀùî‚€ùêÀ–¼Ã“ÿþÁ¯¼¿ç€ù‚Á€ùÒ—»Ô”ÿÒ°»Ò€ùÀå€ùÈ—»á”ÿÞ…»¿ÌÔÙÙÖΠ»È€ùåŒP€ùî¾—ºæ”ÿズÁÛò…ÿ÷áǺ¾î€ùP‹”€ùÚ‘¹¼ÔçïñéÙî“ÿýÊ€¹ÀãþŠÿìÇœ¹Ú€ù•‹À€ùѹÔù™ÿýÊ€¹ÓûŽÿߺš¹Ñ€ùÀ‹ß€ùÆ·à›ÿÓ··¹â‘ÿï½™·Æ€ùߊõùùô»Ž¶Õ›ÿâ¶¶·è“ÿô½˜¶»ôùùõ‰[€ù厶»ûšÿø»¶¶â•ÿñ¹˜¶å€ùZ‰†€ùÛŽµ×Žÿ öàÏÄÀ¾ÃÎÝô€ÿѵµÐ—ÿ☵ۀù†‰¢€ùÔŽ´îŒÿîɵ†´Äè÷¶´»û˜ÿÈ—´Ô€ù¢‰»€ùÍŽ´ùŠÿú΋´º´´à™ÿó—´Í€ùº‰É€ùÆŠ³¶ÚæÕŠÿò¼€³´ÇÙäçæÝ͹‚³»þšÿÊ–³Æ€ùɉـùÁбæŒÿò¶±±´Öø„ÿþ⻀±Ö›ÿè–±Á€ùÙ‰ä€ù»Š±þ‹ÿúº±±Àôˆÿýб±ï›ÿþ¶•±»€ùä‰ì€ùµŠ°ö‹ÿȰ°Äý‹ÿܵÿÇ•°µ€ùì‰ñ€ù´Š¯Èû‰ÿ鯯¾ûÿçÿÖ•¯´€ùñ‰ùŒ¯´ÁˆÃ¶¯°ò¯ÿà–¯ù‰ù›®Ñ°ÿæ–®ù‰ð€ù±™­®õ°ÿæ•­°€ùð‰ì€ù±™­¾±ÿá•­±€ùì‰ã€ùµ™«Ñ›ÿõÞÎÅÅËÚð‹ÿÚ•«µ€ùá‰Ô€ù»™ªÝ™ÿî넪¼ä‰ÿÉ•ª»€ùԉĀù¿™ªã—ÿþЉªÄù‡ÿ·±Ä»­‘ª¿€ùĉ±€ùÉ™©Þ–ÿú¾‹©·ø…ÿòªêÿÿý㽩ɀù¯‰‘€ùÒ™¨Ö•ÿú»¨¸ý„ÿÔ݃ÿß®¨Ò€ù‘‰s€ùÞ™¨Ä”ÿú¹¨Ìƒÿýâ…ÿ﯌¨Þ€ùs‰E€ùí™§«ý’ÿú¹‰§¯¹¼±€§¨ðÿí©‹§ë€ùC‰ôùù÷©˜¦¨ç‘ÿû¸‡¦§ÈîÿõÆ©¦ÊŽÿÕŠ¦©÷ùùôŠØ€ù¹–¦°Ùú‘ÿû¼‡¦¯íÿÿï­ƒ¦­Žÿý®‰¦¸€ùØ‹¬€ùÌ•¤Æû’ÿû¼‡¤­óÿÿþ²…¤ðŽÿω¤Ì€ù¬‹w€ùß”£Ê“ÿû»ˆ£â€ÿㆣâŽÿ艣߀ùt‹5€ùõ¥’£µþ’ÿû»ˆ£·ÿφ£ÜŽÿùˆ£¥õ€ù2ŒÜ€ù¹’¢å’ÿû¹‰¢Øÿц¢çÿˆ¢¸€ùÞ£€ùÕ‘¡©’ÿû¹Š¡ïÿç…¡©ýÿˆ¡Ó€ù£V€ù󣡹‘ÿû¸‹¡ù‚ÿ¸„¡Üÿô‡¡¢ð€ùV ç€ù¼ ¼ÿû¸Œ ö‚ÿø· £×ÿ߇ ·€ùç Ž¨€ùÝ ²ÿû· ê„ÿâÉÄÕö‘ÿ‡ Ø€ù¨L€ùø¥ž öÿû·ŽžÏœÿô¡†ž¤ö€ùLÕ€ùÇÐŒÿû¶ªü›ÿ½‡Ç€ùÕ‘~€ùï ¢ðŠÿü¸‘КÿÓ‡ ï€ù€‘ì€ù¿œªóˆÿü¹’œžá˜ÿÓˆœ¿€ùì’—€ù뜡نÿ䯔œÒþ”ÿô¼ˆœë€ù—“!ó€ùÀ’›ªÐêùÿûïÖ±˜›ªÒïýŽÿôß¿ž‰›À€ùó!”œ€ùïžÙšžï€ùœ•ï€ùËٚˀùï–‰€ùö©×™©ö€ù‰—Þ€ùã×™ã€ùÞ˜YùÃÕ—ÃùYš²€ùö©Ó—©ö€ù²›é€ùé›Ñ–›è€ùêœ]ù×–Ï•–×ù[ž¢ùÂÏ•Äù¢Ÿ Îù¶Í”¶ùÎ  $ë€ùõ¬Ë”¬õ€ùë$¢Cô€ùó©É“©ó€ùôF¤fø€ùó¨Ç“¨ó€ùøf¦|ùó«Å“«óù}¨ˆùõ´Ã’³õùˆªˆ‚ùÁÁ’Á‚ùˆ¬zøùÕ•½•Õùø{®bôù裻£èùôb°Bëùö¾·¾öùëB²"΂ùࡵ¡à‚ùÍ"´ ›‚ùöÆ”±”Åö‚ù› ·Uç‚ùî¹­Ž¹î‚ùçUº«ƒù鵩޵éƒù«½PÙƒù쾕¥Ž•¾ìƒùÙPÀ |ïƒùõÒ©ŽŸŽ©Òõƒùï| Ãñ„ùîÊ©™©Êî„ùñÇŒé…ùôÙ¿¥‘¥¾Ùô…ùéŒËn·ù÷èÔŸª¢˜“ŒŒ“˜¢ª·ÅÔè÷‡ùÎnÏ9•ä¡ùä•9ÔBÔ›ùÔBÛ!Z“Ìô‘ùôÌ“Z#ã ,Pq’­ÄÙæîùùîæÙÄ­’qP, ÿÿÿÿÿÿÿ¤ÿÿÿÿÿ¨H¯ÎÞäêïóõöùùöõóïêäÞίHãœÑåñø‘ùøñåÑ¡Û*½ßñ›ùñß½*Õ¸ãô¡ùôã¸ÐaÕð‡ùô»…bL;4-))&&))-4;Lb…»ô‡ùðÖaË…ßõ…ù äŒV5(&&',1479; 9741,'&&(5VŒä…ùõß…Çsàø„ù Ñk8'&)2;CKQ KC;2)&'8kÑ„ùøàsÃ?Ùõƒùç{8&(2>J—QJ>2(&8{çƒùõØ?ÀÃñƒùÂP)'3BOQOB3')Pƒùñýyçƒù¶B&,—A´”ÿ«‚AS–×þ„ÿä¥`A>É€ùP‹”€ù€‘AI‚¹ÑÔÀÍ“ÿ÷k€AQ®ûŠÿÄ`œA€ù•‹À€ùgAƒì™ÿùk€A‚ôÿþ¢DšAg€ùÀ‹ß€ùO@¥›ÿ€@@A«‘ÿÐM™@N€ùߊõùùå>Ž@Š›ÿ¬@@A¼“ÿßM˜@?âùùõ‰[€ù©>?KòšÿëI??«•ÿÕD—?>§€ùZ‰†€ùŽŽ?‘Žÿ ç§|aUS_x Þ€ÿ??~—ÿ­˜?Ž€ù†‰¢€ù€Ž>ÎŒÿÎm?†>b¾æA>Lò˜ÿk—>€€ù¢‰»€ùmŽ=ìŠÿñy>Š=J==©™ÿÛ?–=n€ùº‰É€ù^Š=Cš¹‹ŠÿÙR€=@i–µ¼¹¢yH‚=Mûšÿq–=^€ùɉـùVŠ<¸Œÿ×F<ܯÿ«–:ù‰ù›:‡°ÿ»–:ù‰ð€ùA™9:å°ÿº•9A€ùð‰ì€ùB™9^±ÿ±•9B€ùì‰ã€ùK™8‹›ÿå©‚nn{žÙ‹ÿž•8K€ùá‰Ô€ùY™7©™ÿÑi9„7Y»‰ÿy•7Y€ùԉĀùe™7¶—ÿþ‰8ˆ7mð‡ÿQFmY<‘7e€ùĉ±€ù|™6­–ÿò`‹6Rê…ÿÜ:Éÿÿù¸^6}€ù¯‰‘€ù”™6—•ÿòZ6V÷„ÿ©ƒÿ¯@6”€ù‘‰s€ù²™5n”ÿòY5ƒƒÿùµ…ÿ×DŒ5²€ùs‰E€ù×™4>ù’ÿòY‰4DZ]I€47ÚÿÐ:‹4Ö€ùC‰ôùù÷:˜48À‘ÿõY‡46zÔÿæu:4~Žÿ–Š4:öùùôŠØ€ù\–4I£ô‘ÿö`‡4FÐÿÿ×Aƒ4Aþÿ÷C‰4[€ùØ‹¬€ù‡•4wõ’ÿö`‡4BàÿÿüN…4ÚŽÿЉ4‡€ù¬‹w€ù¹”3“ÿö_ˆ3¸€ÿ»†3¸Žÿlj3¹€ùt‹5€ùð7’2Uû’ÿö_ˆ2Yÿ‹†2ªŽÿñˆ27ð€ù2ŒÜ€ù`’2À’ÿö^‰2¡ÿ‘†2Ãÿˆ2^€ùÞ£€ù‘1?þ‘ÿö^Š1×ÿÄ…1?ùÿˆ1š€ù£V€ùê51_‘ÿö]‹1ð‚ÿ\„1¬ÿå‡13â€ùV ç€ùh0eÿö]Œ0ê‚ÿìZ06¡ÿ³‡0]€ùç Ž¨€ù³0Rÿö]0΄ÿºx›ê‘ÿp‡0ª€ù¨L€ùô<02ëÿö\Ž0œÿä3†0:ñ€ùLÕ€ù‚/‘Œÿö\/Dú›ÿi‡/‚€ùÕ‘~€ùà2/6ÛŠÿúa‘/’šÿš‡/2à€ù€‘ì€ùp.Fàˆÿúd’.2¹˜ÿ›/‡.p€ùì’—€ù×1.7§þ…ÿÀN”.1™ü”ÿäiˆ.0×€ù—“!ó€ùu’-G’Ïñÿ÷Ù U˜-G˜ÚùŽÿæµo2‰-u€ùó!”œ€ùá4Ù,4à€ùœ•ï€ùÙ,€ùï–‰€ùòH×,Hò€ù‰—Þ€ùÃ×,Ä€ùÞ˜Yù|Õ+|ùYš²€ùòIÓ+Iò€ù²›é€ùÓ2Ñ*2Ñ€ùêœ]ù«+Ï*+«ù[ž¢ù€Ï)€ù¢Ÿ ΀ù÷eÍ)d÷€ùÎ  $ë€ùñTË(Sñ€ùë$¢Cô€ùêMÉ(Mê€ùôF¤fø€ùêLÇ(Lê€ùøf¦|ùêSÅ(Rêù}¨ˆùñcÃ(cñùˆªˆù÷(¿'(÷ùˆ¬zøùª.½'.ªùø{®bôùÑE»'EÑùôb°Bëùòy(·&(yòùëB²"΂ùÂBµ&BÁ‚ùÍ"´ ›‚ùñŠ-±&-ˆñ‚ù› ·Uç‚ùào(­&(oß‚ùçUº«ƒùÖi(©&(iÖƒù«½PÙƒùß{0¥%0{߃ùÙPÀ |ïƒùñ¤S&Ÿ%&S£ñƒùï| Ãñ„ùà’S)™%(S’ß„ùñÇŒé…ùï²}M*‘%*M|²ï…ùéŒËn·ùöÓªˆnUG8.+$$+.8GUmˆªÓö‡ùÎnÏ9•ä¡ùä•9ÔBÔ›ùÔBÛ!Z“Ìô‘ùôÌ“Z#ã ,Pq’­ÄÙæîùùîæÙÄ­’qP, ÿÿÿÿÿÿÿ¤t8mk@   Cj‡¥¾ÑäðóÿÿóðäѾ¦‡jC  9q¨ÛýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÛ¨q9  Y¢äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä¢Y  P§ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ§P "€ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞ".šôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôš.*ŸùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùŸ* ‰÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Š  _åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå_ ,µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ,aïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïa ¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ 4ÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ3OïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïNjúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿújþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ€ŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠ‚ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚mþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþmTúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúT:ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï: #ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ# ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿk8ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿð8ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºkÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿk ,çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç, “ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”<øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø= ¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ CúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúC!¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥! ;õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ; ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘-âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâ-hÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿh&µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ& 9óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó9 sÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿs(±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°(6êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè6\ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\ ‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠ .¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸.;ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã;JþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþJjÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿk"ŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠ"+¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢+4ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº4<ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎ<CÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜC HëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëH MôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôM Q÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Q TÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿT UÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿU U÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷U TôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôT QìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìQ NßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßN IÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒI CÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁC <­ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­< 3™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™3*€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ*gþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþgYèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçYLÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆL =¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢= -€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ- aîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí`PÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃP <–ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–< &köÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿök&WÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈW?’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’? %gêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêg% Q±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²Q 5wøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøw5]ÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ]>üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü> bÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅb A€úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúA a¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹a =wïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïw= Y¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢Y 2mÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓm2K„õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ„K #a£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤a# 6nÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊo6 IzåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåzI  "Y‹õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ‹Y" )e›üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü›e)4lªþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþªl4 >q¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·q>  Et¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼tE  Iu¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼uI "Jv·þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ¸vJ"#Iv­üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü­vI#"Et öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ tE" =p“æÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ“p=  5f‡ÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿΆf5  /Y­öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ­~Y/  )Iu”×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×”uH) "8bƒ®ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ®ƒb8" .KtŽÃúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÃŽtK.  $7Z~˜Íüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü͘~Z7$  *=bƒ›ÌùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÌ›ƒb=* .@c‚—ÁîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîÁ—‚c@. /?^z¬Ó÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Ó¬z^?/  ,;Qm…•±Ðñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñб•…mQ;,  '4BWo„“¦¼ÔíþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþíÔ¼¦“„oWB4' *5AOdv†“¬ºÅÓÞçð÷ùÿÿù÷ðçÞÓź¬“†vdOA5* '09BJYgs}†“˜œŸ¡¡Ÿœ˜“†}sgYJB90'  %+17=BFJLNPQQPNLJFB=71+%  !#%'(((('%#!  ic08]¤‰PNG  IHDR\r¨f$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxí]|ÅÕŸ]«X–dYîMnØ`Œm°S ¦×ÀG¡×Ð!’@HHò‘„^ ¦÷NL1ÅtlÜqï]–‹dɲ,én¿ÿOÏ^Ÿo÷öN×µï÷ÛÛ½ÝÙ)oçÿæÍ›73JyäqÀã€Ç<xð8àqÀã€Ç<xð8àqÀã€Ç<xð8àqÀã@†q@˰ò´Åâðê8²Zμ¶òœg9pi^ó,d´\ð,‡¿åšçàÃ×rOÞÃ_Ò¬¥pë‘Ýò_?óÌ3‹O:é¤^}ûöíUVVÖ577·,//¯#Î¥YYYsrrÊt]/Áu;MÓòp´ÃužµØ>Ÿ¯Á0Œ8p½Ãï÷W755mÂõæÆÆÆ- ¤k×®ƒ ççç÷È{ggg'£ÍÍÍ5 +·oß¾bÛ¶móÖ¯_?ÆŒóî¸ãŽeUUUÈ…‚õ °ð(…8à €Ôø|Ž;wν뮻öØGâzdAAÁ¾8öB«ŸÙuδ†íõõõ pÌÞ°aÃ4…iøÃàšB¡ÉrxÁ™•qê €¸³8dä;[w‚>­yîC=4tĈc;uêtPQQÑAPÛ;„|3Mo¢;±µ¶¶ö»7~3}úôϯºêª9Ð(D(PSðì þ¾žHÃÉë\&èÏ?ÿüNW_}õØÞ½{ëСÃQPåË—•ä§„®CÕÖ­['­\¹ò“|ðógžyf#r%€gO$à3y ¾L& øv8rÿûßw¿à‚ ~µþ´úûC¥§Q¯Íº >h? ‹ðγÏ>ûöÝwß½L¡؃]O€ ñ OÄž«ä)Mз»þúë{\|ñÅ'vëÖí'P턞ý}l8€Q?» ëÖ­{küøñïß{ï½<8ºà 0!Vä €ØpRøHÐçA­Ïî¹çŽ0`À¹¥¥¥Gy ŽÉ[¶l™´xñâçÎ=÷ÜÑ]ØŽ˜pPWéÛ—*£© ô¥ùë0¼øy´hÒFK#jàMÅÅѨ¼@IÉBÏEƒ<ËÎS†Þ˜R¥åtQþü~JËß[ùÃ&qƒ;v쨽øÚk¯=ÓM7-A&ExZA+*š'¢cùF+>iÚÁ)f,,øWwìØñH´öñã)€­m¬´mÓ”Q¿Di;ôæm·4ˆÑ&ê·t ˆBe@Öiý•Q8R‡Õ#~²Z±yóæO1’𠜟>GÞYx o!Š¿ÊEfÒàò‹F½ü½öÚ«p„ §8ðôö‰yÞ¥m™¨T _?U|C Žb›"L F5C^ge Vªøpe”ôvs<Œ »`8üqÑ¢E÷ðúö‚ »žÑ0îz <³„GÂË;vléþóŸsàvûK¸ÛvÿºË~ŸÒªßSjË{J«[`ªð@¼‹— fÈ$Se‡R¢!›ÏPåõ,¥ñš6IÞ¼v¥ÆÔ>eðySì:˜÷aœçÙœn±†´Ñ…0 )Õñde”œdæÍEN\›òZغæškžýüóÏ·à%jE ÅHª"Ë´_©Ü™V®X•‡ü1[üC9¤øá‡¾”À§¯}Lh\©ô ÐÊ‹¶kMX¶#+:ÀÍÖµåÐØ'ø÷˜×cIŒ[lf7„]ó öpGA”ßÚÁAÊ_~:Q}c’/ÎUÀ<…®¼òÊ'¾úê+ÎSð4‚0œõ@h‘/´†@ÕoÿüóÏŸ‹þõhñ[߹ݱ -ýè½Ò÷Å(IV€gM§Á-]>—ØóÕãh9Sk°#ÊÓâ•¿ÛåýíB¹¾ #÷žsÎ9Ï kK¨BF¼!ÄP L—*ïñ¸G~ðòTÞÇ|üþûïÿ'øá·®V6×(}ý}JmšÅ” ATÙ³ ÍCˆժ|&‘шž°èCW‡9¢€¹”*;Jù»^ cëæ8A,™2eÊŸŽ>úhSÌn%®Ô ‘Ÿ ¿å €À>ÐRUðÈ# 9ýôÓï(..>²5ßßìÓ¯{ VûE¡+¼iE/BE/J³¾5\á»-Bs-l÷8Bb@ …•êvQÀfЊ$kjj>{ã7n½âŠ+æ! ÚHm^HŰ£mþ’ìHÀ?¿3¦²þ^{b4Ö³ÈÉ·UékÿO© rSû "ô˜çƒÖMãµGè.Àv-I5o - ¨u:Nù»ÿRts¤0zØ ï§1¥úÌ;ÀŠ)ÜZ13ö+µeÀ²ó0Õ}XOÃXþpàéÕ×Þ±\i«î†%ÿ{´+Aý]Ê’œ€¾Ä}æ„A5óp„à£Q2J½n‚­ _˜˜B?æ$¤iÓ¦ý£9o"56Ý-h‹@ÊÌV¿=&èôúõ¯ýW8ñ`°:r¢SŽZy'†î æï¦Q"¶\}Ôü´1àE΃ø¼n‚]S“²jëš2Ú£{ÐûÓù(šôáL4ñ_ÿú×MûÛßVá}ªjÔHÖ„w2øWÀÁEÜ­h,/¶úS§N½pï½÷¾“òˆÐˆHÛ6C©wú÷Ö7ÍÖ¾ª*\gõèzÖè¼k ÒO¿ ï7áÒ L;AŸ[!FDÌ*LB¬;wîŸ8à€§ñ256§ ÀôÜ&H€ÏV¿­~Å믿þdŸ>}~µò"êˆkõs•¶ø—J[ó¨Òš6ïb£Éí ÷ùhñ á€çbÂòÒäiNÇ€/Fdß@«zC©­Ÿ*­p(ºZå®Óä·Ç¼c®½öÚÑh¾ƒïŒæp!=°Xg2žÚB!ü¦…Ÿ}}HüD¼Ž^ÓF¥-û½Òj¦ RX´Dʆ®´,¨û%Œ†Z;‡Týl´…Ð5(>@÷@`81âú†Ðol± 0RÚø¡-;‚Ó$h¦ ÑXúòË/ÿ jžÑ·Ê©¯¾[©Ê×Q,Æ=:æ°ÅçØ½GIã€AŸ‚Æ p8b7¬ËéÊßóf´ãTúÜ6}ög?ûÙ­ß}÷ú FˆÌ™ÚàóëßsÏ=ƒ±°Ä˘›?Î}U@ÝÙü¶Ò\õr:^kñËסHävƒªptÍõ(©à7Ðr`sáw1»ÒøVuèªmx£9uËuÛ·o?쬳Î:Ë«óÑGQh‰03»™¨øÙ·o?iÒ¤ã>øàûÑÇs?€LuɵJ«³«â°%ÉAe2£ÉD¶í*jú^A[‡†j‚F`NT ”Ä(ªŒþ÷EÔ-€pë7ß|sÍQG5±p”€öŒëdZMðbuÝö_ýõXçúˆæèW>¤ôUZ³þÀ˜—S†á<™Ù˜¥Ì¬à´yÑÜàZíïuºWàž;-×À,Ã{ÇŒó¬fL!€þFf L, ¿lûSN9¥î¼@‡ÿî¨qÒa2JýÊ]᳡4dwî½á¼]LI£+Úlš+q@+*è­üE7®‡Ü {®®®þô²Ë.»üwÞ©B` ö3Â8˜ 6iõY–â[o½µÿßÿþ÷W±Ôö(üwGUO+}áuqf¾AuÃy*»®ÝµîòB%”üvì²qF¥i$n›j`xI9°w•Ì­@£r,öjølòäÉ´6Òiˆ íÐt/€€ŸMt‡Ç{lÄÙgŸý >šm„þ¢9¦¿N=&!ºl”²1–ìßÓ(8iFÞLã~ ñ6: WÆ€Zì:áË‚ÍM*_xá…óñ‹_Ð*Lµ‚BF–¶Ú@: ?MñE|ðÁq‡vØ#0öa`>0ð?Ì/ŒƒÛ¿üòË+Ž=öX9LȈÒV¤«ð›–~XkÏÁDžÂØçªK£¯ý§Rk&à»±+â¼söõ]‡Ìw¼Ÿ4æðÚ¼GMKÐUèqfÞàªL° ú°ßátÐóxB mGÒQøÑ‰Sí1³ëøóßåÊÒÏå³_…•u|hÊ‹œnÀ½çÅ`Hûå²éMëÐ~seqœ:`UãlaXÁÌ#¸eäÈ‘O ( ƒié9˜nÀ þ¢9sæ\ƒUyÿæ[CíÓç…†\]xs¨ò{þCÚè/G (ü-]AlÑèòl ;è‚%X•ø/C‡½A© ¤H' àg'½ýüùóÿPQQñ+ßÈ\G_›>2»@ÓÏ¢…?ŠȺ÷'˜Bú €Ð8ƒr=ÕxÙ²e÷ <øN¼IMF†ô± ¤ üTû‹"ÿæ7•¶ôO-jž§òƒÙq@ºœÈ%ÉúýIO³ ½Û}ÿ@Ü…›i¥ ¤ƒØ ü³fͺ+õÞ²÷mþ˜Ks­y Oaô¡•?cû™¶Ø¦MÙ½ÛQr€.ÄM«QehÜGÕëqQ`)2Ñaâ;‡ v‚¦Hu à§µ¿Ó5/Þwß})eÃ’¾3ÁªÞ „ãО ~Wƒaãöd8hlZ!@mT~²ò÷½;pæwöìÙ·`ºù“Æ!†”He àGÓ­Šá×,®ê “g?&ò`ÁŽÍ_>•O°œ®¸óZ ´÷ëq …Л0Tè¸Å„"8 …*æèö-¼ОC` ”öHÕ&QÀO} |°?ôÐCïöýr¹½ÖâK±§Þwx dû8¾ïßä‡÷Pgô¢@Õ±¶}%æ‰LQªôܳ¯†l °æÄÑXb.¼Ñ—Ø)"H;qASQøÉå’ûï¿$¶Üžvé.‚Ñ%X±g^CYœº k¿GZÃŽ¥€‰Q¯´†µ˜ø=ö7<5œб…ÜqX^~òûï¿¿°+’”jÀ þâë®»®ÿ 7Üð–¾Aí_ô‹‚*¼û<ò8 p±…ž¨± [²Ãg`;ÉÊ  8h–h°r`<;OÄêBfW å([þ"lçÔõÁ|3±ú8s­¥Ï_ý-‚üðì‹|‘_ç$¼§̵ca‹6ê  À@Ø0šÀ‰:gÃÌK)Ħ²‡ÿðÃï,]º”@ì6o$þ6[ÜT!æ…à/ÀÒ]¥?þøãS˜Ïd¸ÌiË~£´!X ø5Ï­7ϼç­à€òA ÀвÑéh,@zoØÈ°˜Èçð¼` © p ¬ŒÉ'{kFbó&à§Å¿Ã_|ñ7à×Wßå?±ßÉK µL48ÚÆ±`, «SÅ:7 †¤Ø—0:Öù¤S*tÈÌKGZüGu'­©ŽÜ©zFi« ¼šK¿×ò;²Ë{CЙŒ‹ÆÀ& êæ(#B¡p?ǰóÔhÔëy/¾øâ*waÇwñ0Ù@ÀoZü±aÇÞ]tÑÓè;¡³eOÚÖÏ”¾ä6€¥üë÷Èã@"9 ±Šb”š†AÚŸŠ†`©¾¶9`ƒVQQq$öøй %Fœ[YÛâÄì´üíÑGêúÙgŸ½UTT4È1öúyJŸ{.—M½Ž0Ž‘y=´’~tëýMÀ¿7| ¨¶¶v! ƒ§Âm¸Á`P0w"Jš= ™€i³å§(-[¸pá=تë縶'¬ôªÏÆ,yÔŠñ6Æú=ò8lø7 A‚Ó_v‘òïûNÀÍ!OË—/óYþ€ ›pPHšQ0YF@‚_Zÿ’·ß~ûÔ°àǼmmÁÅ-à/øË…GR€¬‹êdsm ŽZw ‘=8 ‡]ªŽÃ£Ä à!DèøÞJ† @ Ë´;`Ïþpø¶ß¿œûòM« 0è=âË/v‘r@+°`SÕ¸.ÃÇ:ÆÐ¯_¿C¡ ¼ƒEm’ê$D0&š˜&ÁŸß®]»²%K–!Úy"Å‚ðàê>Řâ{]~~>;ô¶¤­¼µe¼¿ aè'ä‘Çtäꮆ: Ç5³N;˜xà~ ÔˆÁÃ[­Ä>y,˜¿O}}ýÇß~ûífó¥@‡/®$@ãIŒŸB&GþÆ£¿c?æoìPú,8H5V#xO”yHw4£«þåö6{­Á¯***. œ+wßÛ–‰·–~ÆOÐáñÇ?Úü ¼ú€Ÿ>qxà<ʰ.£N£n›uÜ¡LÀÈ!Ä ‚pXØ!†âÖPÇ-â–Œ³…Pmz`öÓ»ÅÅÅ}ñ?4ÁáGŸ}”Zý»‡ãÝõ8ÖX (7bÂЛŽS‡kjjV`²ÐIX@kÁ¿80,èGÑ Ðx´þ¦è{õÕW/À¾?qJH[t%xÃaPBýzé2ÜãåÓûVnë€F{f²n›‰‘m{7a¬ƒY‚ p6`YñyxÝ€¸€ñšêϱ&ù˜åW6f̸DÙøÐê~D@ýXiÅ#™È³n›uuÞ‰0$xy=¸Øígqë0âX“€ŸÚEñOƒ0`ýð(­8…Q¾ìåþÚuûvxÒ¤I÷œx≡lĬ¸ØÎˆµ`ËÏÒ–””ôÆf¡ÊØ#{ÃJ_ño‰VZÿ3›ôBLgîù3¬dàcÿù˜fù׿«ÔÊW•ßœV“X½HâÎ4zYk•¿Ï¯”ê|™mjXC°kW]] õÏ SAÌŒ‚1ª…fþ¥õ§èˆ¾ÿéÇǸž Ñégѵ?€opÈ3sIÏÎSZÅyJt3V/ðSNƈ H4¬H«õ8ñ¢nl]ˆˆcV?b”I/š=9èiMJÛ6 ½ßópZ À¢9í+**V½þúëü°ˆi7 –€´þì¼ö\³fÍëØµÝ†Ö=§ˆG ài„.¼Í›iu[/¤ô!˜ÛÐ}ýDPýråŸ÷gå¯[ˆÔ¼4Zà ì¬5Êßó ¥ºýÒ6&ì,´ëžÑÔÔ´ (b¦Ī)¢ áÁø:Ü}÷݇8‚Ÿ}ÿõÏøE™ þž')}¿%ü`¾*è«ô¡›q(ÿy”Ê`à èëŸÅ™˜MÄ05O˜C‚1i¼c)D(ÂvÞ„.Jà®¶ùuÈ088ù2Uõ×”ÞïB¥÷Gÿ.V}}'†?ÓsM­Cïéè{ü–÷? š1ý˜p SO=•˜"`¨.k)#¤õ§=¡è¬³Îê×»woJ+[ÒV? ðsÚ3Ë’y¤¸Té½ÎIzÁôþW+½÷éIχ—'ÀB`›;ûpı…Ôˆ5ÁýK.ž0¢Ö3Âx8ô×顇º¬gÏž#í"Õ¶~ª´ ¯ÁNÕIi†¾³Ršt?ë}Îè ;ÖÄå¾Vzf£®‚ÿÀòŒãuº×É¿ .!V4ÝÅŠõ€[‹Á3pÇøñã§ @Zzy´ŠZÛ20žè·)è›b¹ò²#0±L(bÃöÙgŸSˆ1á¤éƒQSkfÔŠî¼óÎ#0î߉7CRã: {,DŸ‡]™ £Üb¥ïýÇÔ,v²Õ÷¹_Ê~zjf¼ å ˜0±ŒØ±EŒá¹tZßÖ6Ô>"ÚsÌ1öãþ XùZÿvJ3'Ed–ËoVÿ_@“Ká¹ y=”Vq¶2Ç—ð(Õ8 ¡mĈ¿×m¶ÙÆhÔÁª"澂Ä»Qƒ©5ĪþqÄ=zõêå`üÃć ï£õ§ñ/³H+×^x÷¥8é=Ï‚#æx”š 6ˆÓÛ7t±ƒ‰5<-ÄAü C¿ænk£æûTÿÛ_qÅã°¿Ÿm|ZõGUhýé'”Y¤÷¿4= „!I=ÌÌéQÌÌ¥‰ b„X±!bŒXÃc¶¤Äž-æl¢Øívk^õŸÝˆö£F:f·˜ƒÿ¬›€Ö†*+th%°ÜvØ/¸´©û¿Ë1J+Àœ„ úUb„Xq ¬Q{Ä0±E+ü|ßTÿ1ôg®ó¿m>Zæ9³jžÞã䨟¼—ð麳»’Yß!SÊCŒ+ÜÃŽˆµqãÆ±/'Ý€¨…@´€y£0Õÿk®¹æh SÚÆ¥myê.Û Œ/ý“|Tù‘i—o½ë Ès†}‹´û 6&F€36Aˆµ«¯¾zK7€XŒŠ¢­LïRbÖŸ3 èøÓ °dX££• ØÒrË”V2 ã¾GÆÔ/b…˜q `Ž€€Ø¢Ñ+ø àœPÞ­[·}móÚ\ƒM–b¦* •1_¨E’• ·-vÊ?0óža9Cê±BÌ(`ÇŽ°RÐPbÏa4ˆ^D#˜'…°HŽÎÎζG«ùa+•€bZ)Kziú ½Ô^f§,ÃÛLÆ€`ÆÄŽM™[FFã±Ø¢˜-pmÒåm¿©þcݲƒÂ¶÷ö±õÏ4Bñ ú¤o¡ û§oÞÛBΉ™*ØÎ¨{­êDê Hð‹ÈÅúåýúõ;È>~X4CýÏ@×_îoj³Š‹=?Rè (¡k°oGë2Û¯VÔΩ(=±–)|Tò¡™rQÓlÖM¯1`Õn®Uþ†µ˜Ê²‹œ®UFÍ",Žé­g`Òî¿Z3¾Í¶%èÔÐÑ/t;Mìƒ T±Ád›Ä'ûv®(RÀH™¶þçž{îࢢ¢Ž¼Š´m³ðá%ó®ó*ª”»§µ+N¹M‘›ye*k¿?(ýà§±„×OC‚Ïœ‚C׺;¯{²ç{)rgËÔðàÏ먲ö¿ šþ%ñàßMø|šÊ:d–=?z·'mæd´Vk¯ƒÄ"øAC ±¹{{†Q‘FÌð<ò1/yo§¸µMcÙs(4I¤à¡u«²€i¼m¨bÕ.øoG«‚ZeóM´.‡¨¬1O+Uv°ÓçMì3heú>PY#ï€ÁmŽMÞ3ñ>1¤mžäÈï,R>]  Ô5‰05€!C†8 £núÿì'CeN)B«2øô5ÏK©\Å=3þ[`”µ™d¢ƒ/ƒRœ/UYPþ7£o¼<î,K‰€!ÃÜ9Û>7-X €BÀµ``7Äåà;ùpEèô¢Öˆþ ’6ä²¶~Ž&ϸ–õ¡¿HVn@åO¡˜ßUé>¤´Î˜‡ÑF(–°Xè°B4Á©+!àVÕŒás±]Q»Î;÷Åuhj®¨™lüSèÐúœŒ1Î ç ¾ë_ôÆØç‡þÃÏ:àîÔRùÃ} =Oé#ÿ C!6?I¡ú·¼°ËFLÙPyyy1‰ÇT¹‰QWàgtn€H†owôÑG÷ÊÍÍe‚!IÛ6Ui ö;„|)Þ7á­¦¾.Þ©¤^ü±Xòzè|eåüUªtdèç)}›¯ìw‡Òº˜Ò¹ŒEæˆ%mÛtÛ¨ˆEbˆI®„€[ÀÄ–GÞa‡VÁv¤U‰EóBªˆg˜G‡Þ¹‰ÉîtitÛMùfÿ ŸV³ào¡©¬á° ”Øä¦~I!†ÿEi‡(_pyÓø?°¤Uíø9Z0Iï4Á©cxyèVì¦`»â~A¨³±}9,µ°¦ϵ.ð\K늊Ëáïù—>ƒ AàHâ;hC.ŶÔcÃG’ê! Ôõ‘Ðbò0ÿ D93â°dl_æø%öÚk/b2b ÀM“h?GÚa§Ò¾N¹ g´pz7ÏôŠí÷cO8U3[ùkÁËp%Œt 9ÕÂó°©… °ÌçvÇË0ßMéôP,Á4^7; 7n†êÿRHvj]áÒÛ÷ÜÏÒò&† 9Dèûæ4<¾´,B¸Lkð>¥|³#©•S£lØ·N¯¹ÞœO"cÄíÊÊÊœ}B9Ôä˜.ž'ˆ83-•ú¸õ«àïþV|ùnÅKÀ&ç kåâÎ…pSî]½ßÊ·f’R[WDIª¾Ù/_b+«å峓t¶jA¡öüKP‡#iýyÎíÓ§O‡‚‚¸c…&­qFÙ!­cr\FåçÊ÷ÅÊ?õOÊØ8 l%øƒùJaðã£Ê÷陘<ó4âoVþ¯ ²H7b× ZgØB:¾ëFÆ]Á°9ô7W*HÛý—Ú–˜ÄúœÈ¡@+fmßá76†c„¹£GîÂvdÔÎ@åcðWt»ÃÜ×Ú÷ "Në×(ÿœ¿+£jZœŠ“eŒyO(ߊ÷¡úc¶b0ÿi,Û熠—2ð/–iÓz)ÅŸfVáš5eÔ΄»ÏPÛrí¿ÿþ—.]‘/€`•&9˜~Ⱦ†-éÛWÃãF±°"¶ÚuŠm|.b3V¿ðߺîâýVÙ¶.äëEÂgõ…ÌIüoê.U¾Õ“!wZMâŸh¼SÀÌ@};ìGé´`“Ý+fÞˆ\ÈÁôÃŽN1ð5gêI¡â¾Øû®>|³26ÏSªa3ôzH&ˆ¨~ÿxúúèGBì»·ïª4Zûs8}ô£ÕË/ËPP·¦2sK°E’£ô[Ø^‚c*ñ—é]Ž Ü[N„}añÆ.£»Fœ‚›ÏÂiVIÂëìÒÒÒÇX;g‚Õÿ‚®*k¶æ.µZÄ Â^–hIù”ÿûÐÏŸ>1,&B6­|”ÒÊF‡o™ÉSÌäóW}­ŒJ8„T³/èÔìž­Ë(¬Û{÷›þOïƒàÚ/2«”Í Žå{>±ILãÖá”Ȩ×ç@tàM[jÂГûºiëX›/ë1Bág%Œ¡÷>Óz#~×Ï÷}óK,Ê´Ø9Â.X`ãç˜ã~">ShknÈಫJöQ:5ðXPªà’ÐÏÅpb“s¥`|Z¯BF›Ñ7‹áØÚ`õŠÌ)f€5)¬±ëHn;ë"²‘ˆ£Ð(Hú óB€?@ëìÿ–g'ðCHé#«²ŽzB DþPE)è…±üß©¬£_SZ?ÝAËÉ/ÏÀ¡bÉø{zc2ªŒZa_ B­@Øò»~† +óÍ©q$æÐº'÷#ûgݵŽmyµ>Ǩ¬q/À2}*„ÈåtPúЛUÖacYî^xqOžkÑÅÐbœnYLfP­§h>{ò%¯Rþ}CXæÙĪàÖေÀ)€D"ç¬üü|J{â2Ó‰ä7 gI"cÙó°3|º¼X5XßËíw”2~—8Ôݬ±OB»€0 â=—ïn³D—颞{ð$˜Gió?ÌîXŒdªƒ‚W9ÛV7_–ˆ²œœ€ÌT8w9‘´cc"SÛ•V-Ö³ÿññ]ÿ­WðßÏóXÇêy¢ˆsä‡ßàr¤ÈÏÅ×ì4&pÝFµ2ÌÈ¢‡­aZ0ô¬À!tà‘ àç9+''‡ŽöäK¤Â}- aI ßô;áðâƒäa­ÁcDbXrÌÃú­»:vQÖÛ’RŠØ%Ê‘–Œ¡0€Í”Õ*ZZ{¸àÛ"tlê(4‚"Öî®öùWþϪ¬îG'Ôh¬xM©Í ÷ÌUv;•uà]P;îù,w´Š³á:º £ë˜jj&¥u”ÐúO.hÍv –ÆÙuÿŸQ…Óø Ëk=¬FJ1¢˜RC5|í¯„n’‰ Ž÷Ï:dJú°k•ê8"ä³DßÔ_£ô~g':ÙÔKû&Ì$Þ¥³C‹ €¹±â7dî"Ö°-±£ L)ÅtHuë•ïs¨½ÅJñsSÊxda;ZÕíh]ƒHë9F¸Óƒî&ù/ýÚ:Ѭ°+¼)פ?'|ήÍÀfܦ ó4]£4ø ~ÉÏÕË0Ç~™õNb®s Ñï¾11iy©DÎ<øÇÔf€SòlFÀ0h6Sd„r„ÉBÛ|¬¹ó$§H´MƤH©µÖ:^¥H9”áÛ‚×°/¸Öâk~b­üÖÄSòº<íúü,%³æeª…™"ÂlHÛÔdº †½µ^¸µðFlø|¾F¨öv#¡†Ç¬©fеÞý~úê{”Â@;—À‘©¸1»W;Qss3tsMÎ1†ˆ¦±±Ñy,"Q³ïBä-á·àb«õýI“õl£pšó–@4·pƵ©0FïË l›¡NXeYˆm¦ôéSÐ0.´iSÓÈoŸ[4ΜÊ>ºk- ’.Sö£Ÿá,tDéw>ãL[Ò±¼¶G©ÏcGu†ÔIçöÚts"_$€û·:uêdûÕ ¬hãZÿ°%=h2ÈÍ4–³ÂÕ¯Ä Å+°úR•¹‚‘ MD˜©¨õÅJGÉwGÞ¾%šÒ¥Ü;Ä–Õƒð<"+}$€iûëêê¶:e¢ÕsÝ#O¥‡s\t¢­Ñö*e¬™¨üë¿QŠކ]ÿ|*Á]Xž]ïuLâ=%)¤¶UfÆW 3š±}ûöm(¨Wš€ÀˆäðÕÔÔÔ:r“S_3ÁâêXH<,„ä0îõ´{^5EùNPjÝ4|_g´Ýˆª³e¹2pø¾n®}¨vòV&Ÿ³Ðz%“hå9÷)ßG—ÆüÖò`—ÿ‡ÿS¾O.„оÒú$¦×Ʀ1/©‘µsö6ݲe‹ÁkØì†Ó¬ñºyÓ¦MLÄž¸?Cf:e²ú©Ä¾¯~£ÔÆñÿŠBÈ\¨ôQ7c•ccžžQ9}W}ìy0öS<4°qJ}%6e…àټ̚˜§—à 9¯[·ŽØdGhÅoÈ,…ò’DÔ¼jÕ*G“ª+w¥/¯g้ݭ ¤ªï•ïû;Ð*êŸ(ÂÆ—þ¯±šÑ~ë7øŒQ³ØÚ2 ¨C•5ú.ŒHìÚ'‚+g˜„nޱúCl©öf n»)w`Ë>[kÖ¬á4U"ì_À7@ÀÏsÓ‚ ×àÒ z8&˜1ÃìÖš–åĎžɿƒÙÙÕ#.e3üÊ?ã¥k>¥ ¼8&I+ßăîZÖÁÝ ü»%€Ñë*îs­2V½¯üsŸÆ¶í0¦[N¨nÁ¦U87KçF0 ¦éÓ§; £€€Ž7d4ÂL'ó~¶oΨ2•_)ÿ7Á„”ð[8éŸþ0V)UZßÓ,w£»4[tÔEýàÛ1d;ÈE$píîu’Êêy¢2OPþÙOºÚwÁEÄ­‚ylÙG5sæLjtÕ¼Úny¤:’D$ç¦ÊÊÊmµµµöú/6¡Ty©¼’¡çô„3Cì?—Nò÷²ê?°¶¶vk U}‡V|5Vf¾Û„‹,&Îñx¡Ê:š@I¼›dž0}bŠØ²!b6è)Áƒ3ló–ÙTÛ>“›t14mܸѱƒh–Ë»}6¶´²’¦wàÿ=¾,ÁŸ"-Ä÷õÍȳèÈ·ð€ÿWX$õœè"à[íûb3n#£#Fo†ÃT &É0b”XÜ:æ œ /KdŒ¸qýúõŽ–£C¿]ÉË›™x¦7\“ þÉ?çw¥Ú÷ÙºVsá/ Õ-WzqJpn4oïþŒ†Y‡Ý§T“Ê#S»çl·ÐÌÙ(³õw ~FàFHÕ`Ä¢´Qÿk"ôýxøhÀm9ë(ßij3·'˜Â`ª“"¯r¶Íl8 /2"‘,;¾ýö[G`p-vºw¶9ÆÂç"¯ ÂÕ$œMðgð·+RzÅ1X*í$LþÙ7P¤¬PÏ ìå௚ƒÕ•ÀßÞ¿ìc•5üsv¡D‘´s~g¥¾Yù'Ã>‘H‚QÒè°—cŠßÿ=1)€X%fÃ’ RD„@ÃŒ3ÖcæQ#ö Ì ™g-t3Éú3æf~iz 9LèñÇüX°Bßû\¥ ¾º%ꀕŒ&eÌú2ÕúH&AK1–½¡ó­±%íZëq´RÝ_Wjí”ÄåX²80'L,N›6`³."¸ ¾Û7€/ø)YvÀëhõ€`í MFé¥e¢€z©WÀÀĵ˒oÍýw7MW¾ÏÐ’ÆKí/ƒ#Í!Ã,Éî{&ÞTØ·¡ Ó‡£ ÿÊTVŠf?køõÊ·F°ˆ?KNïÜÕÄ$ˆ0®#o€Ña¥£(ÛGi+¿tÊwz=Ë‚CIÿ•6ô*¥  ¦üŸ\‡ê±=.ÙÖ«´Ñw;kw¥c4ûðZL(ŠüfD˜/  Dâ¾Ëò®\;_¡?®÷:PùW~ë.FO `ɉ–.]ºÏ¥õð»ÒÜŒ0m«ÀqÆíè,å[*ÝÏöQÚ=(ùqO ¯{z‚RÁ?èd¥xghðãC³ïWjý­ûäØǨšÖº8bývÿÿ‰uŒöñufÿ O~øáb‘Ò]|D8¾Ç‡‘¦˜4i’£0:Bj™ûˆŠ JϳÞó@€ÿìö;4,3S.[þI¿BëY¬Åžÿz”vÀmöÅÆæ¤þ¹/Å&íêöé$á‰ÖíŒjŦlNß2ÂÔ½Ï>û,XÈÇË7@"£T!øyÔÓêˆÕX³BÜ Ž›ÊÛixÖûb¿¿Ãïs4À„.| ÜðSíï :*mÌÝhù1ÚcCÆ"Nî‹ôk–Û¤’¤Û(·ÞZn,Êæ‡‰!`b°e€X|««#ƒÜF ‘1b4ÖÏŸ?Ú‘Q~€Ý£Ô¿ßm?Tpø¤;Tð”-„üqÊ$ÝlUn˸¾Mþ5ߨ<‰âvæ(^Šó+ã_¿òŽ… ‰E 6³aÉ­`D~‘2õè{8ëe]Çà5‘itÆð^ÖaÿL_ð pšÓ•ãÄóN±òÉΕ Æ?U½"fßßvñQçìÄã©VBë|œx,ñv=Ì1ë- ný‰UWäVH)1ço{÷ÝwM»FÉÌbâX9B§Ñ¡úuØÖ %J=bËÿ1,îù­>'|Ùëס¦ šÄ*áSL|ˆ¢~±+_(>;&†JÖ‚AÎÎ%&‰MbTbÃ¥3¹Œ…‘Š`BÛ&Ož¼,ÜaF·ýùnúÙºÁƒ-ݨJÀŸ¡¾ìh‡}z¿ó¯ýEˆ!AûÀaŸèâF6d„éµ6'á°CìƒH‡€˜´ WÉ»"QDPÚìÀ.AìÌvJÉßí<¶¾žÚ×®Z7§'ã†È|“ZZþ8óZçÔX7›¡Ò{»DÅ*?eÐ&SL>į>°c_hbD:“ÖÖŸ Kn#b„V € Ö}üñÇŽ@u=ÃñãSìâÆ¾†ZŸcYÖô!+øÁã0F©ŒƒSV†>r,ò„y%7IEŠEùBÅAÌ;Ô‚½:!ãª0Ì&&È£îÕW_)Ä{¡)»½2R`A…ЙÛý®^ŽV&›Uìžlôÿ° ‰ï“ëÑç³ÚoÍaIë?Çk­ÂMWÁ1 ó¡Þu8f\Òà–bÔX· ™˜vì˜3€=ÚàD‚ObÕE¢0BF,’Ƙ°CKR3zåô8užuL£iÌÿ‡WBù«M(ÿ´Ân®ÓÓž‰Iae®Ã‡ ˆ-±µQ¿ ù(é7·­Ž[Âa˜[ìmFD.]ƒŸ™D0b”2LŒ^ªªÈ8Û’ÑóÈ–n^çáT="¨Ü¶…MÄæ¥'š—YA³üœÊ mJs+B šE™O}†4KàP–‚dÔ,‹º\ŽüÈ‚÷1ã@-˜£ô'‰Eb’Ø$Fy¸¢H#dÄ{€§žzjºÏç³O”Ý€£\e(©¦\&5_ÖÄ­à·ÞOÔµŸuÍ=iÝWú˜‹€Um##xÚí…Òö:?²×zô¸¤ftVÔlnsHÜN¸ÎW¤_E¤ …k­PG*çÎëèèï›þ ë’E°9}éhòGðµŸ-²¨qKÄ)Äú¸{àâì9¸3b¸ëG݃™—(k “±>> VæÌ™³˜˜kX‡·þdm¤€ïˆ@•ƒê]·þ÷¿ÿг=õ€JC§ T&,S•²d‚ÿ ôù“~0ÇØJï¾ÈIƒ(ëŒ÷”>âRlÂÑ#dZi¶û¥Ê:ý=¥õ<:d˜”¹Y³;GÇ Ç2#ÄŠkSð˜Ø#‰EéàÒ=e»j† ¥0[Ç?ã7¿ùÍÙÙÙÙZÈ81¡ÁßïX¥Ïy)ä㔸¹eaJdcLø·'Öà·G>xcã¥úžòQØ›X%Hvy¨°_m]ŠÆw`ØŠ+ÒÊûÒXòz ) [èÈ#Nëÿ777Äb¥ ö®„²lÅ¢¦Nú£cqûŸÎáiìú9o>ì©D[æBíGËŸ à_ŒuŽö^÷œãN·˜,¦u=çi~ÕŒ½ ç¿å¾¬nCR'FKýH¬!ˆUHëoo‡³‰3š.£!@´P Q©yöÙg¿ÄÙ–Œö}”Ñe_ÛçIzcõ§IÏÆÎ üþÿ¢œ"àg¾ŒK`zZ¶3‹mñÂøñqtŶżèÄ1âD&L ÆjpˆúO JÿßéÕÏ¢~J`0;”0s¶äçØp”CB yoîs¶yOèüW(#C}a¾1/Ex”ÐҒضµÊ? åãhž›Øp(°µìL IÓDPÕauÒÚ÷ßÿ[‡2ÀÀqŒRÜ;“8Ƈ‡þ53”±ö‹8ÄA”;ÁŸ}þÙ6¼­$… ¦!ò›[Ø·ð‹›¡óÒõ>ÆDLl}CŒ!ˆ96ÀQƒïF5 À÷HÔ˜8»Ò ¨¾ï¾û¾æ8%î…&]WþÁÐR˜Œ¯ïk9Ç" ë²ÿ}¶ü© ~rÄŒïïNs’›¤1ãßhØÇžLLvDL[x^CÔ⎴Ç:‘}ŠNod¿C†™ŠÅ-³fÍZƒ%Šæ:½nô;멵ǪÊFJªûÒ}u‹Sâó }kÿû¿0ÇùS•7’/cñ$¬×ÿn|ø‚±‹_QÆ´§âR_‰åž2eÊ ¨Åwnˆ}|§¿ ôØ €õë×W<øVXÿ¢8ôÿg7€£Ì…µ€¨ÁÛÂ3µ Æ—Ík¸,tîÜ9̘1Cð?4a3IeÔ+}ýôÐÏSé.¸\3E _ƒù¥þì}QÑíl™unw½ìe|y»R3&ÀØG¡žATµ;ÿ¾b~S­t`zí§P· ›—>ªŒÏoUjŒíüÞq&ÿ°ó°ÑèaŽ©<òÈ#ïðÁ3h=¾Õèø~¸‡àp᜞3‚^´€"\³ÕïV\\¼×¼yóî(++³GJS]@ H;0 Øåƒ”Ö}$ôáJëÐúOOp¢Å®A»A}¥2jWüç×MU| TªÏ8ć‹ a=@­ÇŒm >a…ý #–Å$êVGÍÓü6[° æ6«àº²y9¢º!8KF^´þo;6"UUU5C† ¹½¶¶vX‡ƒ­?LJ¥õ§”jU¦ ÜXÕHµ„ ›–Ôl‚ëâ¤ë¯¿ÞÞäVÔ¿ßÅ*ëÛ{c‘ƾo˜¯ J=ߺ¯À\',)¶_ù½R<@­ª¥ Ëtâòïw‰#ø™“'žxâ#€ .©*SÄAOµ¿UÆ?¼oR,4F$ê?tzÅ&P´€®Ðýøã·———3`HòûTÖ;g(­zUÈÇÞM™Ä£¤—òúªã¬¿uëÖmÞwß}ÿÜÒúSý—Ö¿×1n,ˆž‰ÒIœ‚pmj=ö؇¸¶'¬ûæuƒýsï‰Ç â€Y×öûcQ~øá~ ±õ'–zb‹#Öb¢TµÖˆ|ì$jrP°°{Áø³àXwÎ9çm ÿCSQȸ=- 4w¼»ÂŸ1Êv¥ciV®\YuÑE=C:ÇžÙò[1±ÒX Ѩšì¦`cËwÜñ9‘1ê&eää9ñžyH[°n£o›ÿ¿üå/o3Üú‹Ú“ÖŸ‰· ÚB‹eÕ3Ï<3ó»ï¾£ÅÌ–ŒÂîÊ¿ÿå¶Ï½Ò™¬Û¬ãNDŒ<ýôÓ3¦ ±CõŸÆ?6ª)-¿=´fž‡.ª±dØ›Pk­—Æàó•Ñy0‚Ûæ)Ž'IDAT{äq s8`tÞKƒÎs,±qã7¾‰@lý‰bGúþ1?â6ûè<ÇŠdTÁj 0íHÀ¿víÚ,Œkï³Ï>èðÛ^-¦ô…àƒ²‚ÊŽwx‚_†ýèðÃÖ_ŒlýcNñÒ `¦E0=^ç|óÍ70ÖyPNN»¡‰›$+}»EyH/øý­2ºê˜éúúú†ÓN;í±Í›7sÌŽù÷ýãÒú3cñŒŸDÀ‹®€ÎÁ&"McÇŽÝÇ e÷S†Ç[ç+mËr»Þ})Çÿ#”±ÿ aóu÷Ýw¿ñæ›oÎBÀU8¨úS°õ·ZÿãÒú#„¦C² Sð@õÙzÜqÇõëÑ£GY Hè_£ÇáJ[ñ¡Ò’¹'^è¬yw=ìÁ[Ÿùê]~èÛo¿É%—ÐAN<þ(¤õ—‰?qký™·xk=IÀϳh¼ŸóÙgŸ­ã¨@»vírx#$eáQw¿«´ÌÓ™ï¦Ç0ró”ÿx€?ŒÃ&ÉÔtÒIVWW‹ê/­¿ÕðwãW¼€•e¡„€ È3j1*°Ÿ5ð×ÄÚéúòOöxäÝð8@ ÷ñ'¬„1&lv®½öÚg`õ_ˆ€?«á/.Ã~Hc7J” ø…D  &ÀÃÏQaÆ•b飞(ä¹tf݆„è)é‘ÇÔâ€oÄyJí}QØL½öÚk_ÝvÛmlÉ~úû[ VÕ?l\­ (`ͧUô³>üðÃu?ýéO÷)--åZöÔý ”̃Qp…}ï‰ÇsÀßïpeò¿H•ÕÛž–-[¶Vÿ ;vìXPqˆêo5üI¿?nÆ?É¡PþÇûlåŽh¦†äLžùäáHíqÆzsFŽ ì öä‘ÇäpÀ(î¦|'>1WníõË_þòYhºó‘Ó•8¬à§á/¡ª¿p+‘@Ò´ž r«ðÏœ9s{·nݲGŽÙßpkî¤ÒëP¥-yOiÍ2õÈã@b9À…=ý'ü…ÝÂ&Œõý>¾ë®»¾@@é÷‹HŠê/N–Ö]΢0_úÇ\9nܸ>={öì$ ynW¢Œ\ú†é1é‘ÇÄp€;úøN|H©Ò½Â&ˆñþçž{îË>ŸýþM8~V«BU¤mR2€€ž ‘CþólÚÀ¨ìwß}w9fGí]RRb¿¤8c(袌.C•¾ä#Œ'‡yˆ3àãï;þßX~ÿ° -_¾|=œÝžÀ¸J¦«/Ö$ßiõ—~?‡ühøK8p‰&‚žÑʃ}2‚Òz•7nÜpÊ)§< 2Ì™º¤šû&ÛÏ0vŽÀ{êqÀ%PÇ̺†:ŽXwY‡Y—–€u›?iù­ý~Á'Ž’¡8•ŽZ€hM˜#õiåÏþó‘Y §U‡>ÊUWô¥“ ^}þ0S{Yt÷ÁË﵇zh*þÊü~(Õ?©K¶Ux"øßõj l?üðÇzi·{E½”¿çhŒ|„!Bv³<ò8Œ¼öÊwò#0øà* õ½…)¾_#0}di/Áãý¬ÛRß]Åë@©(¬e!`ªI˜<±¹¨¨¨é ƒd ò£ªâ(¥­Â²bž³PHy79@'ÿ)ã•ê~¨1Ý{ï½ïßzë­Ÿã’?ëpU‚Ÿý~±ø'üÈKܧ3h(X*šÃƒŒ>UðÈ1bDE؈óà'0àD¥U~ç¹ ‡e–ÀÊ£ë`´üûðN>|oüøñŸüú׿þ—´øÓG]Œ~?U?-ÔIí÷#ý”Š€üÖkj¦y>ë\ x OÅ¢ÞªB;?»wáÄ¿±XËï¡°î½Áå•Wþÿ¹™‡øiô³¶þòzRÏ©&ò`²kÛ·oß|ðÁ ~aÿœ;ÐÿøÀTâu³wÉ_Æì¤`ú‰oä¹Ê8ìÏpIsžØ#uì_ÿú×Ñòà -,øÙxYë²D‘Ôsª +3䳄bš© °;€êaÜ+ìèÝ z¢ŒŽ½”¾ê+o„ÀÊiï­}žòu‡2†^n„j‡vg­ýØÃïmXü'ã ë!ëp_(‹¿ÔéÝ#Kâ¿Td‹€_ÎÂ*~!ªS¦oÆÊª[<òÈÁaýø6©«´µ˜N¼Ý4Ú:ŒRìIyÊÃXÁ÷W¬à8ÿ-·Üòúßþö·oñ ~¡Ô~ë·ªýÁõØUzñ ”ê@Ê.’SÈ3…5‡—,YR g¡!a=c>–Ûë4˜i–*mórÞñ¨rÀ?ðå?Ã|…=\q€~W\qÅó>úè4¼`Ücõñ§Å?én¾n ”À z–)ø?-ªMsæÌ©Ç*ÃKà{=$???ü¤xvýNÀ:ƒ•¾ú{Ø(¨=j3ÀVݾ#~íºvõ^á –²¯…{ïø÷Þ{oîqœŸ›xZÕ~ë¬PÒï—:‹[©Eá;;ÉÏ/óȃÂ*Á‡£G{\‰GÝ Ð £TTTtÁW¤Õ,Áäßa¸p¡«ð^ ôæ€ÑÛu}2Šû».–òªÄB5/^LàÓÃO€/N>~ëpŸ²àgáÓA`>IÂHaªõ,Ï ¥^xaÞ˜1cºõêÕ«Ì|3ÜO^Ge þ©2ôJ¯œm€J…GÇìlå;àBå‡ =èº%t1bJï„5kÖPå炽2ÎoUûS¾å—²§“`ž] ¬½f<ÿüó‹°À¨vÀô ?B€˜¹a÷ƒÑ-ÀRcgyŽCRC2äLÇÿIa8øäÀ·vQ.Zú~øáϰoÅ[uuutðaë/ÀçYÀOƒŸôùÓüÈsZiÌ/É*Ä£Š÷¤Ùæu-µ'N\¿téR.È0Èy¡QFÛB46—X~Ü›P$œIÏ3&òøÆ\«ü‡ÿ‹Ç”».ð¼üòË_úûßÿþêÁÏa>;ð‹“OZŸÌHói%± Ð=˜6\´ à»m®y bÜëŒÑò§žzêÔC=tþGFMuJ›õ„Êšñ"V2dÝð(éàœýá?WưKÑ °ç}ùå— /ºè¢·W­ZU…7Ùßçv]Áà§•ßjé7=QqO4P\¦¥{@8.AÎÖî€HhžùѶoݺµy„ ‹àB\‡áÂ>® „L D Û“ù÷†¡0«Yé¡ðœˆÈš„ |#ÎÆ®<÷*ÕûˆÀ·‰ øþ ·ß~ûDÌ䛈:A—^Zù ~«±‚@Z~éïKËG;Ò¼N;Jç.@0³YÅ8(]jb ¤F µò¾}ûv~ðÁO8ꨣãäÔP­´™ª¬9oxAäÜ‹î ¶øûœ¦ŒáWÀ%ŒvÞÈiÒ¤Ió¯¾úêÿ._¾\,üÒê ày¦¡­~p_•ÈN±72Iµ,v(Ðd›žƒÒ%À3ï•ã(ÁXïP,çtByyyä:$"PÍÛ•6ÿE¥Ïx^i5lH<Š5Ìzö;ô?GgŸ.r‚A¸îüãÑœƒ·iݯÂA[ÏkÞ“ñý´7ö¡,!)Ó iìâˆ]€BѬ¯i*îêˆõÜÆžsÎ9£²³³©IDNØœD[>Qé³_PÚê™PÙ+ñ(j`޾Ñs?åß÷leô=ú]t½Öææf?œÃ¦Ü|óÍŸcþÍÈ|´æ²•ðóÚÚê«üÒÅD°Ì Lü2R.‚˜5†‡t òp-‚@´ ÞëÈcß}÷íŽõÝŽ>ì°ÃàÔ¤Õ`¶á¼—”6ûÖ³±ñÈ-Œ,ç¶÷IhíÏ‚Ï~?·¯… ‡Ib‹o¼ñÆg̘Á¡=‚Ÿ[ø`ðK«/*?ûúÓßGYö Ê2ä†U &`§ PÈAAÀ!ÃbŒB·àØŠŠŠ2üž0„¨–¨ôï(}Ù·¨RÔ(=Úƒ9¹Êßç@åßë¥ú 1ÎÏ=aÏ&ÌÛÿèµ×^[€XØÇg«/À—Ö^μOàK«OË®ôõ3VËt€o¸[— Ø@Hm€‡€_δ”ajqñe—]6ìºë®;ÇÑYœÑNjªUÚ2lfºè¥¯œê ƒ¬åï}Öm< µ=;[GØH¦Ku}ñøãÏ‚K/Ïq}ŽÙ†?ûù<¤Õàg<øQæª2¯3™DÐQH·€]‚PÝ« p } caaaX‡c÷C°}yëk)"U+>…Íà3Ø ¦`ÒÞÍx2Ú—¢_? }ú#”ÑçȘ€žL[·n]í<ðFuflÛfzkQÕg?Ÿ?ÿ[ouì!øIÛòŠ×v€µ¼"¨cÊH Ùúó  k¥×\s͌Խ{w ‡Øg!®œŒ5 ±Œùú¹l”2€rÚ)£ëÞØ¬ ïs:XÃbZ¨µk×n}ä‘G¾»ï¾û¦µŸ’Ô |?Ïrˆºoµð·‰VßÊ|i­÷2ýZÊ,B@F D  àü"x[ÿRt Š0Z0Âà L6ê‚{±%Ú 6L‡ ˜†c¦Ò6,Äðb%Ú$iœb›\Ìbôj£[¶wÆÚ‹]÷Ã1¾—#ÐÔ´®?*˜¬Syÿý÷ ëþ<¨útÞ!ðyµ^ÀÎ~>¯¥Å·ªûbäÆf|«>ì$ÃÎmè‚e—Ã:R`'(DðLA ÖhéÆ×_ýcÇŽíçjí¼Á Ymž‡‰Is•¶ aÓT÷õè: ‹›èELt½=l£E{Ù|ùÞè, NEÖć8G;D-Å(Íw|ðÁ2üeßžC,< ðyð‡¾¨û¿ íµ)à£Ü&µe`åù ¶2¤+èEðLM5„bXŽ®Á¾?ýéO÷ëÚµküP€Äv#Œ*hu«”Q³Riµ«…ú€¼ikD£¸CÝÍ烑» ‡u Dìy¯¸û:[o¸×*Œ½› nW¨Œ|;,t‚È늩µ½”VÜàï…w(+Cëׯ¯{õÕWgbŽÙ‹-¢óU|øØº³Eç!`—³ZöyX/ê>ng~_Ÿ… EžpEø`í éP ˆ ൠS´k×®‹Gö¿øâ‹÷£/æHüÔ¼_Whjj28†wf¾õÖ[Kvì Û |Z€/@·ŸÏì€ß&ÕýPL÷*æî\!?ä@ …Vc¡U+°   j4ÁPX‚Å%œqÆCFÝ;®]$˜îDÿûï¿_‰±ûyXÄe1 |TïÙ¯g‹ÏÖÞ |‚\À/g>[{1ðI?¿M«ûàÇä €=XbÞ!À359(¬‚@Zr–îÃÒhÈ£°wïÞ¥?ûÙÏ`uÙÁX«°§§€+ ¶ôS§N]Õœç¿üòË‹W®\Ic[{Ÿ,­¹€Þzæu0ð z9<àƒ¡È¡¸²ëž‚P];a ] ^‹À &AA@Û@!æÁxØëØc­€ñp| è–ÜfhݺuÛ`Ì[üÑG-ÇÚ+áŸO ô4æñš9=Á/àf+/`—³„‘_@O5_úùmÒÀ‡ò‡%O„eÑNg)òJÏ´;.]Ñ DX5†ã{;ç!`7£ùä“UÓ§O¯Äb›4ÕzŸA/@¶¶ø¼¶ž×¢ð9ô|>y ‡v.éˆ ­@Z}«@! ÂBßå= ó)à[P†»Œ5ªÛ°aúp„NH|'å Î8M´ÔÏš5«rÊ”)ë°®~%Æì7µž†:<-à ¾€Þz–0<Ë{ÖßSõÁ˜HÈ‘pkWØ`A C ;a`V! BCÞc|N @FÚA(ä@”@tĦåC† éÔ¯_¿âž={–b}äh XG¯~÷[°ôzͼyó6b{6‚~3À_ °¤l©ÙÊ‹už`&`¼V@óšÏƒkyÏ ziíüˆÂ#·ð€[N…'üãÙÚ=AÀ³´ôt9‹³„AÀ3ß—ƒÏ¥k!š…ùNÇŽó0Q©=V7*‚¡‘#°1äã(Àæ(yEEEy:th————›››ÓrÎÆnʈèܾ½‘óå±ï¥¯¡¡¡àUX"kGmmmÖ-[Ð?¯Ç±ùzèj±ŠN-ÖÏ«Ã.L7A)à5]Ttªôb6/ïË=9KÜò>Ïžš&ÄŠ¤Ç*¾¶ð‘çPÂ@‚Üxžƒk¸`AÀ¸‚…õ}yW‡œåÉ£äY¾™´ Ò¢òl°€P@) ¥Ý;ÁÀ—÷y–8%Œœ%®`ЋQOÎRï!‚+A„¯{ÁCp@xÊ3A'g.Ïjk¨³y&@æÆ+ÿØÖ´˜f¨·w5å:DòŸçP‡U@0­@%xå¿™gºõžõšïð?Ï"|¬iYó… Å‚¬$ÅÂ_ž­ËYÀLp ëÿàkyñÖ4ymÍ þîüÏkR0À¬à·Q@/g»œÄV@˽೼øx-q2m^ç ·<Š%¤RÄ2N/®Ð^  X^ p f^[ÏV€Ëuðóà÷応%=ëÉì&‚æüVÀ9Ü'Àç…yõ(N`¥ð(ñ¾[AÉk+håZÎ|ùït–¸‚ã—ÿv%¶‚Ï*x--²´ÒáÎV!a%‰ËšóÄÿ%¬%Ÿò Ö3ÎÿNgyf gC®YR^ ñ:tòß Nëµ¼ÁÀf8y|¶ÆÁk’œÿ¼ß„sÀZž¸— -ä»XϼŽö`BÖ¸ì¶R®ynÍÁ´¬qÙ¥íÝO¤R$!i/É9`ýVrm=Û]3y|* V>“këÙîÚ>øšÿ=JAX+F fÏË’KÇpÿ]F»SHx¿Ý¹ï=xð8àqÀã€Ç<xð8àqÀã€Ç<xð8àqÀã€Ç<xð8àq 9øq$¬%ýÒž½IEND®B`‚ic09Ò™‰PNG  IHDRôxÔú$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATxì}œÅ•þ«žÚ¤ÕJZ…UÎ Dƒ ŒqÂ`28c8Œ}öùo|øÀ6Á`c|Ûc|$“3ˆ „PÎ9K»’6Íôÿ{=S«ÞÙÙ0fzfÞûýz»g¦«êÕ×½õ½zõªŠHDA@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@P‰_ÈgA@È ‚ö¿kfj¢¤ ´#´F¤]1¹òîþù7ý{oÏ ¡¾7ÎÄï»"pû÷úº7g}Ob¹ü¹»ß’Ý/ß ‚€$6>!Y ‚€ dÿsü]âÁIÚ¿»õÖ[Ëg̘ѯÿþ}ûôéSSTTT͇Rªª   2 Uà(F£}ð¹ iË Ã(Á™"ÜW„Ïa\óQ€ÃÀwÎdšf'>Úp´"V|׌k>öâó^œw·µµíF‘H¤Ç.|Þ‰ûv477o磱±që¦M›¶½ûî»[~ô£5 ½>pÙ~­¿Kf$ûŽÓŠ‚€Ç$kŒ<.B²òdÿWíd4ô5°br?üðÇ †”––.,,r¯Ù©Àyε l&óÀ Œ‚½06Ãp؈óFœ7À@XßÒÒ²nÏž=kY^ýõ56#»Q ¯ë*ÆA""òYp@²†ÊEv’TÈ;ÿ‡4¹óÙ"xœÕùçŸ_rÑE¬««QYY9$?=õa|€à‡‚à«ò 9;`¬†a%0VìܹsÅúõë—ÿîw¿[öØc±×A‰‚*1 ìhȵ ‰W IåVA ïHüÑd¯‰Þ:?÷Üs£êëëÇUTTŒ)))‡G¡÷>çÁy‡˜ƒ ·¶¶®…a ÎK÷îÝ»x×®]‹W­Zµð„NXŠì˜ðµA Ï‰F@âgZHA ÷HlÐr¿ÆRCA ÷Øÿ?4Ùó¹ð_xá…ñ#GŽœˆqù ÅÅÅãÑ“Ÿ€^ýX>³‹x„ 8 ÚÁsðySSÓÄ|¾lÙ²ùÇü¡ }fÀnد=ÒH²²{—ýµ‘î°ÿ?hÂg²·®é‡vظð§`¬~ zô“Aö“t0»¢%uªÀ(ˆÂ(ø ž‚yˆ-øCŸ¾õÖ[Ÿb¨e#òbÒgƒÀnè"Ä ÐHÈ9¯°7xy „T>/°¿ÿ‰„o<þøãõS§NÝ¿ªªjåíqûý@øuy‰T–T~‚ ÃwìØññܹs?>çœsVA}m ˆA%ÏRÔô{èiR‚ Yì﻾Ö=|ƒ{ø3gÎ<¨ººú@þ4þ ü~™UYJwƒ ‚-0æÀ øpûöísÞ|óÍâ»AÀEؽök7ÅKZA ÐèF0ÐJŠr‚€ ìï8_ó¡I?ôÁÌ0`Àtì ²?Ç0eIÒ€#ƒ€g|€ÀÂ÷7nÜøÞAô.TŽàГ¿Ý°_¼v¢ž öÆ1µ”r· \ìïµð?üáu‡rÈ¡pë‚ýèåOn5D3¿€wà=Ì4xÃï@Þ¾ð ףLm èá­† 9çö†2'*$•È[ô»¬Ïí½ügŸ}vì„ C¤þaˆÔ?½üQy‹’T¼KàXŠoc†Á[Ÿþù['žxâ"Ül÷pZmès—ùÉ‚@ÐÐeÐõýdè÷WŸÛIsñ'Bf•••ŽñüY ýÉ2ïdÀ؈¸7vïÞýúüùóßÀóqŸÉÀ’ï²ÝpfmDñ¼CÀþÎòµôÇôé Ò?¤_›wèH…=GÆÀf¯ÃxÆÀk0¢»1`÷د=×E2¼DÀÞ˜z™¯ä%x‰€ý=åk>B8xLȬY³ŽFäþј—$ŽA^,y v°æÀ:¯bFÁËo¼ñÆËˆXƒß9V€ &»`¿ÆO"‚@°°7¬ÁÒL´bDÏ8è÷Ô"ý#<²äî»ï>;ãƒy˜øÇ X‚@º€!° ½Œ_ºüòË_|õÕWyÿm °:ÚÐçt«(å Ý" Öno’4"`'ùºÝÅÿÊ+¯ì?zôèãÌw"øH£NR” Ð-˜Ið‚_\²dÉ‹GuÔǸY†ºEL~ öÆ6úˆù‹€~õ™{û¡ë¯¿¾ê’K.™Ý¯_¿Ù˜²w<Æõûç-D‘]¤š–µ,#³e-›ÈlÛªi jÛMFt™‘&ôA›Ñ÷ÿðm\耚|ÖŸ¹£jÅv–†ž/y+|6pVx|E8SÔ(%*(ÃÓ)ÇmU-ìOªp QáH2‹Gâû [Æùu‰xM˜ZøÂ–-[ž¿ï¾ûž¿ýöÛñ€,c€ í ÐçØ·òWȶÿø ”.Eæ;ö÷¯ù°ˆÿå—_Þo̘1' ·zû‡æúäÈ&»`¿ÆO"‚@z°7Àé)QJbDÏ8è÷»Ÿñúé§'8ðdþ Û’k`©¦ÏÉÜõ6Èþ3¢¦•¤Z¶àw¡§‚ïÀ ¹Vs{}ðØ 6*È,ìKT< FÁ$R‡Âƒ0Á~cN\#V` Œç6lØðÏ)S¦<‹JiC@»a´ Ï9Qo©DðÐ pð5 sý¾ñ™‹øüã×^pÁ§`9ÞS0…ï$ì®ÇÆ@vKÛVR;_&Õð>©½‹ÉlÞ¢oÌž^|¦ÐçG_ЇTQ2KÆY~0™•G㻚LiäY¹Ø½0‚©„ÿ‡eˆŸyä‘Gž¹å–[6#s6Ø`ò×€>ã+AÀ?tƒì_ ’³ °¯§o'þ^¡oòäɧÂÍ*zü‡d-PƒW;ž#Úõ&©=X<® íz”ÂE2Jª|™5§gåðO%„Gàé¥K—þýð߃§£‡ì~hâèÍ«+÷¤„€½‘N)¡Ü,t€ý²Áûï¿?sذagÀÍ:¢ù‡v‘>p_«ÝŸÚö7¸ó?"s/Ö}á(û´ `´ë‘oÀ†â}ë°ì©Øoü=Â(b£'|<¬BÙ‡¥Mæp’5kÀ$x±cŸ£ü]üšÏ<Ë€ë{¾æßÒÌYœ¢}ÏÆ4źÄ;÷™§bq¡§V¯^ý·iÓ¦½ÅÜSÊ…ìvîÔJj’Nìï&~tQ)ôÑG=dÈ3Ñã?3 !Ü;¨±öhË_ÑËŸ —>¦Þù!Læ!D¿£§jMƒÃµRøÌßç£XŒLƒ´<+Ö5>¦$šåS‰ú ,´ìSÊñ ËH$² '׬Yóäð2²doì°{ì×øIDè=öÆ»÷©äNA´eA¿îñ‰ÿY þ³KüŒÛoy®ý0%oY¬wj«»KîуرhqðÎ ½Q|p—mÞ¤Žbĵ¨‚)­3Œ/=0ºÌ2,\Ô÷x_Á3êHtã†À_áø+<¯BIñòIe§RöF<;k ZgýÞt þwÞygÆÈ‘#¿âÿR ]ý˜šgly„hëóD<–Ÿ¸ž#$Eö z¬§ °JžB_Ä{Ìf„ì€#ÃÀ«µ8^±T3›¢ý.ä”C€GàÏË–-ûó!‡ò.ÀMfˆ7Àû·.§sÔ yNWR*çú}ÑÄÏ]Ú‚çž{n*äìòòò³Õ_ïYi^dÔ¶“ŒM‚ô1M¯i-rtÙFr0žÕ³-‡«¸‡/={/ž”ƒ<ØSCË ÇŒx ¬àCYµ'Á«]<ÆÀñíÿ-¼Ý•í¿á³V544<1wîÜ'°-1Æ«,C@¦áád¡ºAÏBÕEå4" ß“ÄÿðÃ×c‰Ós«ªªÎñOJ£>ÝŽí¤Ð–§Èܽ÷ƧµuŸ*ù¯á³¿Ì:b„ŸüVù6óXAuà=pe¤Ê†S¤ß0ÎÃógc/Cà³;v<Ž%³ÿôÕ¯~u´b€Áxß±úÇÐï„&~fÂ7ÞxcƸqãÎC€ßùˆìG÷8“ÅÒ»ÿG´þAR‹¡ˆ?OÅ+(·ÅÛÛŠä&¶ñVÊ8-îdÙg QÝ7°4ñIÀd™Ì@œàîÇ.\øÇY³f½ MØH\LHŒ€Ì=¢À•¬ûÀ)& ¥ý.hâçsøÞ{ïrê©§~¥ººú|Œó£µË ´n@oÿWèí¿„¦ 㼩 OÅÃt|(6D8&¼+£µ3£ƒ…ŸxȨæŠÖ]…ÿšÅñ‹·oßþØ?þñG/½ôRLw¡VÚ  }Ψ®RxfÐ~fµÒ3‰€~ìgËÝ¿hÑ¢súõëwzýÇdTÁ½s‰Vý©]8§ÚÛ·zú üp\û˜›/"ô„€Ù‚E 1œd0 Rx*°qýõØÍ1x^Ú²eË#cÇŽ}j؇X+mès5•¢3…€nô3U¾”›Yôóç3–»›õL?~ü˜Öw¶æÍPW™Ýüÿ$µö^¢=䜂0ч¹§_%=ý`“[;#ó Àh…w†AJRZOæàK1|Çwøàx¬âw!ÜýgfD«Ö- ý;‰6?›Z@ð¡U<¶àµÝ3‚©ê˜MÀÃôÔSOýÏW\ÁËcJ`·ˆåîšr·†R3F@?gMþV–=›ö|Ûôž˜v˜ZVňÇû½o8yQž0»øAþíUJ»æR  "€Ð ï:/>Ô!kV3 ë{“ÂÓ{°íð³ØdèA,ãý 2¶ ê¡}ö´\É,8hbŽF¢‰—è竉ŸÏaŒùÒ—¾ôMôú¿ŽM{Ò;g©e-ˆÿGèñó4åÞÌ߇ÊÖÔ=ôö´«—IòÊ-L^Š TY³Úƒí»«#fTÏ€!p+Qáàînôü7l2´Þ€ÿùóŸÿü{ÄÉ”AÏv†š ‚­¥hçýlù̇5Ö?gΜGõM¬äÇ¡ÉéŒñ«Õÿíw_ë]ŸÝüèíSÄo°ÃBDÈ.Ì(:ÕìèÍð{úAæÐàÝOoŒVüçÒ¥Kà"Gb²ëMs®-“‚Hn!  ŸÏ<÷ˆÂK.¹¤ß“O>yE}}ý÷‹ŠŠJ[•y7¾5 þe? µgŠíÁ«ÈSø k,==~¬ÅÏ[µŠYˆ¿» ‹f*Ī`Ü /žFØ]œ‹Ijï R%Õ¶ŠÌ2ü›òâUi^ä«oß¾‡bŸ ,DG•åVnG´Ø¯õwrÎbäfñÃK¢º~ž|æÃêõcß™'N¼þg'IãÏW&âŠ6ÞKÆÚ? áëÅb*ÜС׋æ÷G%ÉUÈ4±Ù[ð?é®= f D_H4àRü7‡{ºÛ³ß1Sà‰ùóçÿË ¿‰L9@Pf x†n°2Ò„,­D'hÒ×g+ÐS~¾Ù¿ÿoßì$S'iÔÖ?ÃÝ)}­ŠêI¬À>&~¬Ë/"ä &ï?€a±^ bó!sè5dÖ|)mè`¦À¼M›6ýSƒBÙ3Ѓ+/mªJA.ÀxIªŸ¡&~ö™‡{ì±ÑÇsÌÅØ²÷b¬æ—–îƒÚý1©eß'jâX¢„çï‚øy÷=A O0#ØÓ¢e3 ^¬'P<„Ì‘?ÅÐÀiA «¶b«áû_zé¥ûÏ?ÿü%(”½Qv@ ´<  ÑäáOî’«ßèçÇg&~> ?üðÃGŒq1¦÷ï·Vþ­›Ù1þmì1ì¡=àakl4-ºI!‚@ 36õÂ# (Èküf~mZj†˜€–/_~ÿ´iÓ8@cØІëÐÃ?=ß"D4Q7Ñ©kôsã³>Øå_—ÿ¥ ¸ÓûFtÜ£_Lx7Þ ?Œó÷´N:¯‚ñ‹«ß#ð%›\D 64À†@q3–¹ñ—£à}Ó—oܸñ> `sËàaí Ѐ>û«ŒäîšH<ËP2òýÌ4ñ[.ÿÿýßÿsôÑG_ —ÿ%¾k€Tã;¤–Þs_vW Õß¾ ãתw—@~òðh1-0z2¬1Œf ”šÐ0$pßË/¿|ï—¿üåÅ(P†Ò‚º…H‹ì¶~䬟ŸÛ]þˆò?vÒ¤IßIËŠ~XàD­¼îþ7º¯Ÿ5s™1_ˆ¿{¨äWA 90¬u,ØÃ:fßYdû ͪIž•‡ßò ‚Ÿ}öÙo0Kà_ÈV†<Ä6ÝYiBIw¹R^êð³²ì÷ /^¼øëuuu—"ÊBêY¦’C~›%cÕ¯Ð;én ì^À§äoÙ(©”!÷ ‚@gð¿×#€ênõLž6X56ú îãþ‚YŸ¯_¿þÞ1cÆüJaO@†” ‹,ô'Ô‘ôµ¾ôÒKkÿö·¿]ñþïc¼¯Õh^FjñEdlz=þ?ïBxÉÞ¡èõ‹»¿ „äkAÀø·7Ê`TW!-þÿºŠ€—@í@ îNtÌ+Æý0Ä}’P(TÛ§OŸ#Е`Áϰ›(-p` ]¸½ 0ò€üp š~>|æÃïâ‰'¦yä‘WTVV^à¯úXÿcÃ=ò{ {¤à7ÚajŸˆ ø‹OlÝе!À¥c.:ä[D/Ãûy;wî|äÕW_½ëì³Ïþ…I\ãŸ%¢ &KÔÍ+5õ³ÑÄÏä_øæ›o‡ñþ+°–ÿ±¾¢Ñ´A~×bùÞ]cóc*RÈ¿žF×…Ë/‚@ž#Á¦àvPZOÑQ¿$*í+Xðü qwÍœ9óE$q¾¢í]æšd¼ËQrò~.öƒMøBüƒ}eذaW`¼’…$Ï^¼÷“±ú¾Üý•p1"º? S’ë)ß ‚€5$׆Ù¼qWÂÞ€¡ßÁ”Á‹q‡±ˆ ølåÊ•w¡ƒò( b#.ÄS%.€IÄÒÓˆéb'~¾ó±dÉ’«ìw%Æûý[ý£e5zý×`Šß¢®QQ˜Ï_(îþ®’_ ÀÃ-0»^?Àì3–ÌQwàÿ·Þ7±^ÀfþzôèÑp;XÃ<$ÀÄo?|+_2N ‡RÓ%ßïN$~ËåóÍ7üÓŸþô}û݈ÀDù#jëŸÈXt©fô&’ Ôá-J oÈsûEA 8ðjß$¨ÐŒX³t:w¶UËVR›ÿBTï]éd_t7 £¬¢¢â¨Ë.»¬´¸¸ø³×_§ %*ÃmH€‡ôsà3ù?þøãã:ê¨k| öƒëP­¸Ôö·»FÂÚ°Äoñw ’ü"Þv¸u ½]*dVBæðÛa4ÀðI88ð•W^¹óœsÎY€" TûòÁÚ ÐgŸ4l{B@OO÷Éïþ! Ÿ&~>=ÿüó3<ðÀk0ÕæT¿ŠVï‘Zr‹]÷ú9È{"‚€ 0µêE„¬¡ø$j‡«Èý 2ûLOò£7_566þcΜ9wΞ=û]äÈã¬OÔä¯ÏøJ$ÝH«žnÄ;–§ñç3÷úù(ÂÊ~³'Ož|5"ýïx»WŸðÿ·îWd¬}òÿb±vëC¯ß AHò»|%Y€†à[Ø€¤bPtð׈]ƒ_¹ùñ^0Càõyóæý+>ÜõzbxuÊ9jJ9¡$p€ÆžÿëøÚŠôÿ裾8jÔ¨k‹ŠŠ¦º.!Y¼”ïÒ+Iíš›ìW|u¬^¿,áÛ@òµ e “Ýî Hnð›S øk ðÿ½÷ÒÜÜøà÷û÷ï­ÇåŲÛüËn…{½k Â~Ö–½}~‚€ —pð¯öÀš*˜#„í¿ÕÖgÉ,ÄNŸeû{OYYÙa§œrJáòåËç ŠÇ#¸Ýñ 1|ÙêWšüûþú׿þ~mm-Âñ½–(ý~HŠ·ïíô„¯ØåÏäox?ÚàuM$?A@H#¼©W«r§¡SÇÁ$µã-RÑdV ¥tÓæ~0ÁöæE0>„À½1¼¶Ç\Äè"G7èÿäî¹çÖÜqÇÜó¿ÜQ®Ý%ŠìÁüþïÚò¯$wA ž\P0¿iÕ’Ü&_ ‚@#€¶ã ôU’-Ôø9Ñž9DUÇ{Þ‰€0ýˆ#Ž(F\À‡ØõT¯hÒpÙÑðèZ €´e£_T>óÑÞó“ÿe¶{½¹lÝ@ÆÂ¯jÀ?h¢°e_8Zx?Á ±(ù,9€€Bä.ÿènTF¯Ó«—jZGj'†ªÃ=Þ#Â8xæÌ™E+V¬àáñ¤áUÀ[“’ÿé§Ÿ^u÷ÝwßèGÏ_íýŒŒÏ/Ä›IvñãdÞú“·ðA ·ð¤$öX q€¾M°˜Úúw¢Ê1Ï¢í'·—l`8 ÛŸ°páB‰ p héÅè Ö½þöžÿŒ3Ê9àÛù^™b^=Þ®v½HjáXæ“-õ10žÇ¾É¢{n•‚€ tFÎK6H&{åmmÆpãÓ AT<ÊöƒûËøp@øí·ß~oíÚµl}$Ƹ/Dr°Ð=VÃ=ÈûbÏ;÷溺ºïºÏ>!‡Í cÅíø2ñj„j1ÞüDA@ð¶íèhlFNÛ›èðë‰já…ôXÖ¯_ÿßS§NýÏ]»vñ:ì àñV@¸qƒ€nÐÛ—6‘üyNk6¿¸Ëû~oßm]­»;ùq¤¢À¡®C§¿,ñù,‚€;8& u=òˆtÊ':øØQÐû~– ¾ ›£ý ² ‚½btBßùb8ÇN§LJþ‹-ºº¾¾þfoù‰Mó£ Oê²÷­%}‡`¼óüEA@ðž"غ}pî'È€/P´þGø’ãž½^1pÕªUÿ9vìX^6XŒo`mÏÅ»'Õže^]$’?ÇTaW¿KÐóÿ®§äZv5%',ä&äŸW¯žTVÈÜÁ°Ú´9‰²ño±6 m•WÂm(·¥Ü¦"OŽfæ6–yËÞö⣈Äp‚Z,ýdùÅä1ÿ Ñóÿ®§û G-½‘·¯ÄJ¶ÿå¼ÂCñïÀÅ‹‚€ à3ÜÖp›ÃmO‚pÅmU§ Á„ûRùÈm)·©Ü¶"[b¤`7÷2‰‰¤Ž@"ù³PüÞ{ï}{]ÿ;¶ô‘z–]¤à~–]Š•¸>ì|ƒQ…`?Þ=XcgpäA@ðÄâµaúqtG§b̪id޼Tõ<l%¼ž€ŸLŸ>ý/È’9@b\à+€ÔÁÓl«Æ°è•W^™=nܸk<'ÿÅßHNþV¤ÿ­ÕI½"’Bç íáÕE¹-Jî°(´]„ŒWÂm+·±ÜÖ"Oà¶W·Ã\Œ4†ŒB "@ `áVý‚é]QEÿûßÙo¿ý®*..ž’ZvÝÜÍ=ÿE_Ãê~ón‚ !ìÞê›ð½|A p[ÄmR{óÓÛ.µèOnc¹­å6¥è˜n—5—é6:¦„üí8îž?êK¿lüÂÝ{ï½N8á„ïõéÓçØw»ù É¿qAB.(2ŒÅ}xSA@‚‚€.æ]­åƒyš~LTË6¢†7ˆúžŠß½Ù„ ž€z¬ªZ3räÈÏžyæ,P` è"ù¬Ûjûwr1’€’ä+ýBÙɿ𪫮ª»è¢‹n¬®®>+Ig_1ù³ÛŸ7Þè xTáÁxµ½Së½|AÀ ‘Ì1b¸À»N v¼kĈ·¢0Ú¾P=0пzæ@ÎzÜ$ªâ[4ùë3{MбeåUXâ÷rÏJå©~‹¿•dÌŸÉŸøò÷ kÉHüC€Û*n³¬ÙzûбbÓÓ)‚Üs[ŒR¸ä¶Y·Óú¼O¹ê„€ éð…~‰øÌXYäÿÁœ7lذ˱Hï^x‘ŸÅ˜ê×0¯c^¼•¯5ÇŸc]DA@ÈxR«íbgé>Q Ÿ‘Zr)ö½ûîHíŠÛ`n‹¹MFJmp[mo»SË4îö†Àr0û ¤É¿èù矟þ~ˆhÔ‰ÞT;JjÙUXäçÕ„ìâäoz8“¹|AÀ– n]rÚ:”eÖ‰u~…ï¼éƒ655ÍG,ÀgÏžý<2å%ƒÙ°ì‹LÄ"1¸G+ÒmiK’q*zà¦{ì±ÿVZZ:½sgß+nĶš/&$òOD> ‚@V"€¦3„£Ð~_œžÚ»’Të*2«Ž÷¤Vµ~Ø3`>¦"ê°ü9&ݦóg‘8bt~ô‹Âg6ø(<÷Üsû_vÙeß«ªª:­sgßkN´‘µ² “?ÆÏLDÔŠ‚€ õ°PÖÉ =‹ÁÊdVÌô¤†………#P²víÚw 3zª&»^Üš7·0&vòçA¬’%K–Ü4tèÐïz†Âæ‡ÈXq{BvBþ €ÈGA@ÈT|'Á„á€èðë‰j¿æY-W¯^ýߣGþ)2d#€ÇØõ`ÀGF@ €Žï&mXä?gΜ¯O˜0á?°)ÌX÷¢v<ƒ ¿›Ñ>—˜_BÏ_¶óu°ä ÁD€·ެnö @Ó‚áoœ«‘Hd÷çŸþƒ<ðPÝà¡}àRÄ›ŒÜÀ1‘ü­qÿþóŸÇ`\éÛž‘ã;ˆ‚½ˆ%’ÿ !ÿÜx¤‚€ ÐÜÁ ¡­ë0EÐKnÅ,¨·»J•Ò÷ÜVs›Ím7ò*nË™ëìm<>ŠH @ìàƒE¿$ùÿìg?wÊ)§ÜPVV6#ö³Ë¿ÍËÈXømp?¯Y¡Eò?„ Z"‚€ ä:<½™× 090;ä,0v¼Dfߣ±Áöp)0úÕÔÔTãøäÅ_ÔËëÂø¬Û|—%ewraß‹ÀX°ÀäÏsïJW®\ùÓ~ ×î¥mó¿„ *my¡ÈP4ðddÁ–¯\ ‚€ pLìY%5/ã²hE'>î‰Àµß°aÃX'à&\¢0œÄÓñÑ^8Ì/a‰Œ…>Š>ýôÓ‹=#k•?ôü;?—Ö_È_Þ>A@ÈOx_ní‚6R-¾´ÌSùÝ ·áÜ–#' Ðí;Ÿ¥ó ò}€_}ðKÁx”<ûì³'aËÉëáFªÂg×¢V\÷Öûó1ú¡dO²ï˜¯|A [àš^öÄEµ`Ëlt’þÊÕ¹¢¢bäG±ê‘GYŽŒ8úÐærp•uÖ'Îg@[€Ú*d, ò“ŸŒ;õÔSoÀb?xòt7ÞCÆú':f¥*a‹ÂA ߰⟘—÷õúÕžådò¬>»F‡;r}ûö­ª¬¬ü襗^âx»Àך \—•mämÅãë¯{þ<îÏóý‚ùþì2r-j׋¤^‡|lÿ «b÷A@؇@t=¨™µ`zà¸_`¡ ãô®ÎXà~¬ðïÈ„§&ÆØWådSb&¿|&~MþÚP„ %¾Ží}¿é MXå*q®?G¾=É^2A §නÀm(ÚR/„Ûvnã‘W²x€¼ì çã€&m0Å=öØáØäçz,'9ÀõËi cÁ…Xƒj‡-+8x¡Ÿüõ6Ù°KA@’ ÀRË ÷ššm¤v¾Jf¿3ÑybÞv.ñƒ§Nºè/ùËZä”÷ñùfh+O÷úù\ˆ¹þ®¸âŠ0Ft„ó×K§äÝý®$Õ¸@3`6ƒûyPKDA 9h¢yZ´}€†š>#ê{*’è&Àím8òrüŸ¡Ê'€‰_\o>J°\䉘òw"E+ðÙ•¨†×ÉXúcäa{ŸT-J…[KDA —pL67Ѷé;?$ª˜Œüa½Ì£ëÛ00bÖ¬YË}ôѸ‹‡Xl wì‹\ÿËçƒ0ñ³èž?×»nÿaçœsÎõ}úôq?å¯u}|™ß}SYHÁ¦P5VÁòGA ¬€@î ë6ÕD<ÀkX.ødØå)dÔùVîðak÷>ÍÍÍïAvᎼ ÐÄØ¡ÜúF÷üÙ`òg×vŒúÞÈ‘#ÝoñZt6³˜·5~yý‰‚€ 8FÀ\ƒ¾ù¾ýSÌòÉdŽ}Ý9÷ý×eË–ý7vz½ ºíÆÁÖ{Ø`o@Î{˜s]4ùóY{ŠŸ{|'•ßpgGògûBÉ\O°•LA ¿°ÚRî³ÅÄêhm¸Ctuf`.@&è±µóƒ3\åôÄîM¨`×$‹&~®o\ÿõgŸ}öõåååS¬_]üQ o±üÿ!m,¢Hƒ·»Ä¶—"‚€ .@óm6´ç£>E<šï¢úöïœ\”!€‡ÞÁPWCš `— i´%Ç€vý÷™;wîõãÆ»ÞuÚ¶’1ï XSÊ6ßß úÃR¿"‚€ Þ!`îD?kó¾üÂUô$öní·ï;‡W˜x;Ö¸É1ç0†˜sU4ùóYŘòw,ÆýÏó¢ÒjÅ÷ÈÑþ¼Î¿ˆ ‚€·pÛjŸQ…Ž—Zy£'e0'07 3 àÎ"s†Cð1÷$W ~p,šü¹žÇ{lÍôéÓÏÃbX•Ǩ-Úþ®-vù'lmiûU.A@Ü"Àmì¾áUnƒÕ–‡ÝfJÌ Ì ÌÈŒ˜3´ÀùkNá뜑œ¬ž×K“¿vý—}ôÑG—Mœ8ñV×O¯y\ÿç`´HOOÁ{¢Ø¦Å~\c+‚€ Ð-hwM^É7>\%‚£“Gó;²ÛT½ùqþüù?:à€îÁ½y1+€-œ\MþÚà:ÝÿýÓ‡þeו嵩—!| ü‘£5×_Èß5¶’ ="€¶Ö¾¾ Úb«MFÛìV˜#˜+7èÌ|Ø9sGrÍàÅb'vçsÌ1ç–––޳~uógý¯°Î¿}w*^åOÆýÝ@*iA@H ns¹í‰Õ&£mv+ÌÌȇ €œ È5€Ÿ¿¶Ö¸nìþ/~饗ÎÂVðÙ»µ÷32ÖýÁ– –«TýmŸåRA -Xm//n›¹v+ÌÌÈ'Y@ Û앞 2WD¿îýsÝ /¿üòá˜ó,»‘®*Ê®ÿÅ“jÙÏŨ\„«l%± ‚€¸ æŽ:ÏÜcÁZ,»çõ;ß;ïÛb×௠°wïÞ·ßÿ}½L°^è%VTŽüÍE€Ÿ<»nø(ýíoû-ìô÷×Ïkýdl}Ù–M5^2wëQÛ2“KA@”àfž¹9¶T°ÂÔ@Sµ•šrNöÅÅÅÃêëëwüæ7¿ùßëà.(§ çf’­Ì_'öþ¹^E ÿƒÔsÐ¥4-HpýÃêT}]f*ÉA@\#`µÅì ˆ‰5L‹6Û­0w0‡ Μ9…;×àcv ›OÙ.ü@Xø¬׫èè£þRIIÉHþѹDI-¿vŸÞ1’‹À¸NÙÎÑ‘”‚€ dŽÅŠO D[­–ÿ;™05ТgÚ1w0‡ 5ƨ‡Þ$HŸ™s²š ˜ÍrA´UÆõáa¢§Ÿ~ús|Ñuå6?Œ¨»5É=÷w«d ‚€gp›¼Ï+«mþƒëÜ™C˜K{˜[˜c4ßà2»%Û ~,|æºðÆšÎÕXÌá‹Øó¹ ŸKë2VÝmKÏA¡2åψ\ ‚€ ¸mæ6:&ƪ{Ðoß ?::3‡0—0§ žr yÆÎ=ŽòB¢l7Cmq]¬Þ?7¾X[[{‚[€ÕªÂé³7ž g/SþÜb*éA@ðn£ã´†¶ÛjÃ]Æ\œ‚lrΠ̀&þ½ÿË.»løèÑ£ÏtùÌIíz™Ô¶7mÙ°{ißœSÛr)‚€ ¸¶   ç¶Ü­0§0· ŸD/€æ!·Ed$}60®Üû/¾è¢‹Î¬¬¬äÈMçbbiÉ?µ¥g·R…í³\ ‚€ n«÷ Xm9Út7œÂÜÏXÇd=rE²Q´Õ¥ÉߊúÿùϾÿ1Çsmaaa?W•Úxzÿ¯Å³à¢xÁŸl…Ê’X,D€½õ 1½#d†¬ßg†«z”••ÕÖÔÔ|øÂ /lBF< ¾‘«l3š˜Ù-…õ¶“?»eÊçÍ›wÓ˜1c.sU¡–Õd|ú8kðàÁ§ñÎ^œÕl!j/¶š4Kœg')A@2‹€Õ†ëmƒÑ¶[m¼»¡{ææT,ë§f“ -+MþÚ(>ì°ÃNuø§¶þÖáâøËЬeÜ?³ÿ¸Rº ^ `µå1ªã6žÛz7Â\܃<ì^.ÀÎQnŠH[Ú*i+ÎuA °>ØýRôÐCŽåy©Fçb6a|è®}éM÷Ï…möUI®A@ÈOЖ[mz¬öjͯ‰"z7gˆ0ç0÷ µöh^ÒF€³ŒÓœ*[XNƒÊg6Z˜ü-àC9Bõ]ȦˆZ¶Æ3@l‡Yk=à"_Išu…˜ñѧž¨lìû:2ŠêîƒX0–åCñ„›D± iÛ.¼?ˆ6nÙDѦõD{qìY޽É×P´5>É–D.A Íp›®ø³»Z¶q›_w…c%˜s˜{Áë8x‘W`ÒÐs_Z4±ZI(Çzjòg£…Òßÿþ÷Ç}öÙw»2ÚvñÉ x|{%ÄÄœÿ¨ŒýÇÀÈý¿F)–í; ë!Úþ ‚‘a,ˆ‚@ú0ÐëWbå¥Ýï90‰ó¾cKKËŽ'žxâòo~ó›/"S&žȇÝÀÇàJ6x´‘¢ í(ž9sæI®ÈÏÅØ×;ù— ù÷]õL3£lQíL2ú‹^>zû~ ò7¸ŒJî½÷ÞYÿjìÖ„'êPZדZz ³Á†b¢è ZÙ;ÌO’£ ˆÔ€£(4ö*RÿEªòXÿ¼{X:ïXQRÕ3H 9‹ŒòÑVCdîÝ%ï-L'PR– à&†xÆXÞ»‘Y{:šürÇe•––ª¯¯ŸûÌ3ϬA&Üû×äï8Ït& º€ÉŸ…ÏlYéÞæbž ƒ³ÎÅØp//æ1ù%ˆ/a}!r£ÏuЩd :„qÀÀ^龇’ÁGÓ:Š®ù™_"3£§("äã…6Aa(m¿±þnŠÖÿÄq™ƒ˜‹ÁÛ8²Î t¿&ÿöÞÿm·Ývð1ÇsuAAsÓ­e©e?Döl°Á®°zÿl_ˆäF¸ŒÔ°sȘp3©ªƒðˆ‹‚[-¼ÆŠ ³¡ã^2–ã,à>0Ñ,«0ÑX^üíYBf¿“ápî „`@uuõœ_|‘ ²Ê Œ§ €öÞÿìÙ³OÀŠLƒÜ¼„ƺ»ÑÆFbY˜üðƒn ¹©m¥Uzû³É8øA2†~ÿèYÐ ‡–1òj*8ø^2j˜("> €¶Þšé…¬Á¸(…¹ˆ9 Yp/ƒ‰„¹Šæ®@KY/Yï¿ø†n˜xê©§^ ×K_ÇÈrï9»}¸—¢µ8þY9®n¾$4ú £Ðä’xþýÜãïé 6A!@Ñàéˆ;ç¡ÂTCA@ðöXpÀÞe^xª£ÑèÛo½õÖ(É=K&>-A7t¯Ÿõäx…ÒÛo¿ý¼aÆ!rù«Š9Ú‹bD`G°KH${Pd ÿ2ã¾oÙeoE4/cAÆ-ëÉl\™ð£|ç Ãg‚^xj xZEwYu¼ãì¸CZYY¹þø™p 6ôÙqÞ~&d‚ ¢èÞ¿>³ža¸Y`»ßã\)ŒÈÚ‚ùŸ–`Q+øÏUŽ’8ƒŵTpÀÏɨÿœ8A¶g‚TPÃæfÄ2Ü€ê;ÌD’ ‚@'¬¶?¾°ssƒ anbŽBœ)s–æ/}v‘»?Iƒjpm5h¬#·ìE×\sÍqòNÅØø[~|ì?â|§åK:ï0úîGÆ´{ˆÊ'y—i@s2úG¡i¿"£ÌUèK@k'j B@sÇl¸ß•ÌMÌQÈ„]ÊÌYv#ÀUÞ~%¢ ‰ŸÏšü-`„ îzÿXõ6þ=Ž%÷þËüÂUòõcèÉdL¹ ¶v¦öù\i ûß…©ƒS|.H²ò‹â^€MO#†›«ŠÇ9J‰FsZ $ˆ¤Ö¢‡~ø˜ººº£ùGDzéwøã©šmùÅ>É߬A@‘1úV´|ì5ÉŽQ”‡&ßF†Ëo”‘\@@ssïàB˜£˜«š¿4Ÿ¹ÈÙŸ¤¬`Ä”ÏêýO›6í¥\ òb÷'cãŸcuåPéýé¹÷JP?ÆÃ¯$cð—{uÎÞ„cìÀó—EAÀÌÌ cã_Ð9äeý ssRk/€æ1ÎÐÎoÎ ð8“kD¤]'ì›)¾å–[¦xâ‰WºZøg룤¶½««µ?tì©ò¢K×0ù«ñ×`±DÅ‹X¨¾‡ ±Bôò®øŒÁE"ž6x€VL ú0eû;ÌSÕJKû…Ãá÷^{í5^ˆÎx­y–ÀM ä©uAmh˩褓N: ‹-Ô9W4ŠÇbÉMØÑR˜b{Ϋ—ë)•"5öb2œë5M¹~ƨ+ÑÄ4‘¹î…”ÓJA@ˆ!`šØRÆ7(, ®ˆÖ^ˆ˜‚Ræ*æ¬ÿøÇØÔZ˜3Šo8,âqVÃÔ1éM Mü|f½Ø Þo¿ýú>üÈÞdÐÕ=j'GÞ§%Zaùabäo6 `-é[‡µüE’"`Œ½žT?,w,"Ž`Òan°\aqFì“£¿ÌYÌ]HÌ^líѶsœ£|½N$€ë¦ÉŸõâ£ð?øÁQ555®¦þц‡8oH >Hä ‹ìø«Nvïé Lü©òáÝÝ$¿ ‚@7ĸ¹Òα©þeÎbîB:kÖ|ÆgËÖÀ9 Aì–‘6øIMœ8Ñ]ïÏ|lüôi¬Ž¶ð…°¬ªÓÞÆ/°úJ1£³~„õ2Ë¥–(#dà‹#Àà îp#qî²2ùØ7Ù{’6(€® ƒ£­¥BÿMÁ´ŠÃõNÎjËÃñdÜûïã$ I“ B%dLúþ]$X³×ðÕQhâ ¸ÿDA UbóìãŽTs‰ÝÏÜņOv/@ þ9ƒdØÉßêýŸp ‡—””Ô8ƒ©" D›ãÁQ&ÿ U×q­ò"¡{9æȪw)?lÌ PCOM9™$Faq.™;˜C ss’Û½LB1‚Àˆ †ý` X6bĈY¸v.ÛþŒÀ^øÙKïß9ŽiN©úÏDÄÿì4—š;Å#/%U:8w*$5Ò‰€ÅÌàæÂÆ\†,xÆ&;ß¹ÈÝ}Ò˜¯Ã}>nr`0Ö…Žš,ùõ¯={ÆŒ—àÚ±ËnÂÒŽ»`Å•‘ÂÑi&ž (G°0—ShêÿÛ ß8~ñÖL¨Cæúçшá—w\0w ×ï€â]UX©•TÓ*2\àø_k 0`À¼§žzj)2A¦Öt@ûÓpœ· ™x3)vKÈnxà‡¹QL5¾‹©kbYD%0Ê –éL«F& lÒäslX²|­@IDAT¤‰Å5Ž’A~" 9£i-Y\â…8—Ù‡yÏEîî’fÚÐÚÛɿଳÎ2hÐ Wm~<–·Y„à? $Ó@ù¬*Gb¥?¿öê#¾ cªWÙI>‚@Þ `q¸ÃÍ%kÏ\Æœ†ä< À^næ]漌K m ±.|]pÁ‡•——rŒN¤qß²¿: Ãqf’0]£.MWQùQvJTÃÏɺJ-¯ˆÄ<ÇÖòà§Â\Æœ†ôlQhžÓ¼ç4[OÒeÒÐðYƒÂÖQá¤I“uS;µý©XŒ-Á"G@õJTå|ýíÀW0C ƒ¿ˆÙÎ'ÒdHm)VÈ8*R@ITÛÿæJŸ8§±+Z{˜óìè*§‰3i°Îm„/»ì²±ˆšœá´BVºÍ%oãàK.B$è#¿t³S?£Tý—²SwÑZÈ(à‹C „æ‡ú0§1·!9¹k¾Óüç0W÷É‚`h0Ø2*:å”Sf`3…ޫּ A‹­äÖ¢öxK¹îu$l:#ÇUÕx¢ xD|AÀt:š¸3åý äHéPñ`@Õ¸Ûú,süÿÉœÆÜ† ìÁ€Ì}í¡fÊЖ>³–û̘1Ó£Ì ·²«oyÓÈ¢œ¥¼ñAÇÀ*¿¹þ {†œˆüåA0w ¥w jb.áÿ­qϲÃÿÔ8·Ù‡4ÿé³Ãœ'Ë”ÀëJ³|„¯¼òÊq˜3éÊ0¶<Ãyƒü%ú9DÀÿa|ºßW2ûÕ³¼X@DRD Î%Æ–ÿK1aÇÛ™Û˜ãðm`†2Õ"hòç3ë`õþ±‡òÁp•ðŠŽDíþnšMHËÁlµ‰5øX¨È¯ˆ¯ $+ÐÒ×B$sA ÷ˆq ( Ü¢vÏq\Aæ6æ8dЕÀqÞNfÂЭ½&֢ѣG38ŽEmû{,mGþëbg' Ó€€QwRJ‘"£n¶!)#.±8¬² 3Ì\HœãìÓ™û4Y鳋RKš €5äŠêƒ{ÿáK.¹d\$ñÎ$Š1šcI£ý/t¬ý닇]ÍÜѯû’„¸í”М²å_HI)©ýfæ8æ:|ÇÃÌ}šÓNþ¬W& {…¹|> ±kÒAp‘ôc¥œˆjü€¨u'b5ð¶ë| ú»ZîÁÉk’ßiŒRÕS‚ÿ^Èÿ®<£€½1Nç{ËX\ã°%aŽc®CrÐügçD‡9;K–n@[9|Ö•· €±cÇNsV…X*µýŸ±‹6^¼A$0jÄHûsªq5Ê–vu¥@A 0ĹEmw ç:»ÀhçÆ´U9ÝWÌníXîÿãŽ;® %à¼ÖûÜÿÖ®Òý”3¡õ)ļôò ι¤t„€Ñï࿉ïŠ|–g€w Æ-xÖP38Ç¡0×1ç!yƇ2ipÙ|žwÞyÓ°^r½C<á’Ad&»ÿ#ßä­E€ªäÙ0Úè ¼º¹£`ñ`„Û:žh“;8HMT`naŽ×Xœ“júøýÌuÌyøh÷莱Ã\%K'[ê ò™ËÕGx¿ýösµ¼Ú©ƒÿdÝg¯ARUMÌ@¡R$# ªÇ ‚€ àhŒcÚ9ÇIHç<ûżvŽt˜sjÉÒi°fö rÙ¡p8\TWWçÊ ­/[Y«øT .H$ØåBB{B}Fg¬h)XÈfbÛú’«j0ç1÷!ÏùsÒmp™ÚÀ/¼é¦›öïׯŸó…à›Wb†õ1׌¸”ßì!¡Œ='£|lÆÊ–‚ìFôÅÃÍp€{ ss’ó0€Ýp˜£³dÎ’¥œŠIß~°áÁGáôéÓ÷K97{‚ÏÅ>ñÖ÷&|8°PÆ¡3ö Ê†ÉÿJÆÀ—‚³æšPsOÿ‹W'Î}ï ƒ½8’y|g´t$64ùó9Œ•‘œ÷þ‘Úwÿ[{7ëbädTqmÕË}ÝŠ€là_?ÚܺaR¥ý‰xib>cψ‚JRØÕP`¡¯P’é¾­dF›Èlm jÙŽÁMëÉܳç-¨okpë+še  \cÒpÏ¿ÈtaĹ/Y@Ú°H§ É_Ÿ Ž<òȵµµ“×6²јŸÃ%/ŠÉÙún09VUÚ(`û —éGÿ+EÕèwlJÑÉJ ÷!U1Ѝr<8¨t^!’ÿ§SN‘<Ú†=«ˆS´q)zo ÈÜmÃцˆ)!À\ÎQ Éä÷'ä,øœ¹9ðÕW_Ý…òÙ:åW—;Æ<Ç0-d–.@ÿ_ê r% Ï9çœ)eeeƒpíHT㛀 Ë2Fdç?Gf*Qae¦J–rã¨Â 23eðöÄ5püõÝŸŒ¾X˜¨Ï˜4<4=¥Ã¬Ãp\¼<´±0¶aÑ-}šÞ–4è"Ed=¼Ù\ˆ§¾IfåñŽªÃÜÇ`%2hÆÁ¼hçJ߀t\!]1®$á)S¦L✊Úùº•”]2"Y„\¹"F \‘^à²WfÁûô›‰€cŸ2-h’úŒ%ÕŸòǸî–w)ºñE27amþ,"$A 6 `çkŽ Î6ÎȦyQó$ÿÌ×¾é0tE¸2º’Ö €!C†¸2h;{Â88;‘¬A._‘ #Æ8ºï¢HõÛT݉¤úÒï¦Òzuý${ÌM¯¹öi2·ÍG"_Ûán”’Ÿ‰sNܳý-Î5Œs [ÃLbšµàûK—.€Ò•âJœvÚiCjjjœ-ëäƒ1Ì6D”û«/âü ˆd´7~ýßbLðñd > .÷Á™­¦ÓÒy˜bàlëàØèš'É\ó<ÚØ€01:Éfd.|úé§±jš'Óq:Zb]!>k '|òÉ'OÀÎHˆDr&ªá +¡jÃCI=^ÒVnVUc±ªÜ„عA[øÞŠ.ïAUà,h¦‡låçÞ"ÀËf7.ïíݽ¿‘újÜEšõ'2Æ\™½äŸXãÒz2Æ^M¡#Gý¾ 2…5¢|ü¬¹Gs‘ ˜™ ‘î„v~´s¦“l{ÆoW„ÅNþl„'NœÈ•v.;Ùý¬¢ì=ñ½ª Öâµû­èì!(J?Ö$¥rPæÞµ ˜¥EÄ5mý˜Ì8ó÷q11«›ômröæÍùà:¢Ýk¼Ë½ÓóFžOÆ3ñjøÝ¤x§vÊ9aú¡1ì«DCÏ¥èê'È\ñg„nqÇM$/`îab.ª9Ç1q.ü'2Ðd>ë&’Ï~ùê(ÿ­\ûÁ• :t<ÎŽEíú.^IQÄS˜ôûDÆ ã¬u(^É=, ®eô˜ø0úM4 ÚÁmjn}›ÌõÏ‘¹ùC<7 ®òô™õ6³=k)2çzh{›¢ûûBŤFœMÆð¯à=É#Cu5†¡ÎCÏ¢èòGÈ\þ+f {°äלDÄ\䆡ã\>šøí|é&ë!O§ ­›‚C=´uµ‹IZÐÃlÅBmMÞãîí Ü‹vÆmÏ€yæq„xG€cÔ² Ï µˆ¤ŒcGÞ¿=Vüßx j‚åÆ\Žõ0쓯b”1êÛDCΠ袻`ྑ¯Häo½Û`ø21'v„s!sâÛo¿Íî$Í“Úp”goqa~ W‚E[6|Ÿyæ™ãJKK/§Þ²2UÑ{§V*ùÓÌWã/¦Ðá·÷¦×äß¡0|à%€y)Z‘ô!м nÿ¼!ÿ’:è62&ßšßäozEýɘò:ð§ˆpܬÙs”ë,A@sjxÓ±ÆÌ…Ì‰È ŒÃΕœ§æP¾ö\üôhŵ%ó €I“&uU“]ïbTªGüTß•†ÁOŒ'¡†ÌF/î2ÿI?øh䮆ð¸DÞ»«àmvWG~_†ŸNÆh¼/ùäîOµšCù¼w“¹ê ¤’XîÍNÀAÌE»ÞsçÄ—€æIÍ› _û2à7ƒêJðYW,\__?†kåTTÃ\¸ÿeüß)~TÚBSo&ªÚÏq’0 hk€Ûÿü¹ó/éK¡)ßC0èÁYPé «ˆ˜c<‚,kgRäÓÛ° fø‰ø_<¸H5|⊡㜨=Ì•vîô…ü.ÈOÑ•ÐâÅ °¢s ÒW&4^ÿ_$eÔ€ƒ)tèï„üSF.Û˜ýä¬}¿Æ•âªÿ:ì÷Bþ©¢ÈÞ€™’ªšjJ¹?Û`.Â0179”8'r‡œ9Rw˜5:̵çd~¬<‹®—Upá…ŽFÐÃhëÔž*JÊ2Ø0’£wàAŒÁT­Ð+ñ{œßÁs•$Þ"f\|âüÿÿ­jìWȘö y_œ>špÞAjÔÙñ¤­ê][•]8Ÿœdq“³—…9‘¹©ÙÐf;‡:˸‡T~vŹ }„gÍš5J)å¸\³aÞ!xJ¢l(‰ô C‘1õD,_Ô«Ûå¦ìF ºêƒæåÅJA1…öÿ!#¿å0I¶üï¹”BÓà ‰×r.9tÅ\N2wsçÔ™0'27"µ}€yÒÎ¥Î2ï&•c"î&Oý“îùë3—U€=GꜜÕ.mŒ‘Hï@4å:RƒNïÝírWv#°s’`ˆÇ©ðxÿŒ_bMü#œæ é’!€51B3îÀ,˜Êd¿ÊwÙŽ8IíxßU-âܘèÐüé*ï®sa~ŠVžÉŸpÿþýÝ{—Å ö‰ôˆ€šømlÆrJ÷É 9€@ËŠ|ücŒEFU¦Ï M‡Ë¿h ³ô’ª{*&"žâÌÊø®ûÀÌîK’_Ó{—» Œs£Ý ùÓ·Ú0)û%Zy}æ²8p„ãÛ°ˆLÛ.R²üo¯ TÃOÅŠeçõê^¹)ûˆ~úCDowTU5 =Ô_ ù;B/…DÅ0²¹‡¨œ—ÔÉ,NjÃŒæ(‡çÆ´zü24éó™Ë°Èÿì³ÏVQQ1Ü!>²Àô?’ŒÈ@O*ÄYã¯îé6ù=Gˆ.{Û×rÐ_ꢪF’qð±EšRO.)RE‹a…¦ÿ›hL5¥ÜT,N Å9Ê™’ÌÌ‘H­æM;—:˸›T\€× kÑÊ[–;‚èS=›lÈøϰ…Kô÷C¼:~ðô¬ŠÜ‘vÃõ¸äGÅÈÿN49åŽÒK"‡À0ü/xœ-ë°TIæ'à&‹£–ÁÜȉäÚÐü©s´s«þÎÕÙ/†ÐŠó™ÉŸ0‚غq,jçÇèý³ÊÐˆÆø‹rg+Öî**¿Yÿ ѹÿ‰ÿ‹ÖÔÑ(«‹‘êØy‘‚=ð¼DÞ¹+5º\¬É }$w€›˜£L!4qŽLÀ\ê9ñùáÐ Ú¾.¨«««×?:9«½+âóÿ¤Î4ªz–ø=3?*+µ¤è²?¹cIêHUà ýßâöO9oSÕÂàç oMn ÃÌQn$ΑÜËMäO7Ùv™Ö/À®¼öÔÔÔ87¢캄 ö°$Gg ðΓ®íòaË9†¶÷µ\ÿ©þ/„Šâ×Ôå YZÒÁx?‰­ê³”û;·ƒ™Â„㘣˜«Jœ#ÙмiçR‡¹vÌÀ®0çÏŸÚÚÚ’ªªª¡]«ÒÃ/-˜þÇC#²P—@©ºÃ0¦8¾Ëßå‡ÜB ºàWˆ‰IÑõ¯…öû7¢Ê ¹F¶×ûrðz„ç#’¥XÜŽjYê¸̑̕Ƞ;qmçTÇy'Kèµ`{µÒ\FÁÉ'Ÿ<´¬¬¬2%zójZÿïÍÝùy1â‚ü¬x>Özë;dnx7åš«Ñç 86åt’ÀTÝ Ä;.Šd1дÐq˜#™+‘öhÕyÚ9VçøÌ…x-Zaû¹`êÔ©®Â]Uã<ôv<­»×õÎh~ªvéÕ¹}Ñc­Æ\ú dîÝHf¶ÐmÝ…c7ÜŒmxÿšö•î»Z»-êKªd©bØ·Åp«—¸ˆÚWB×Wf„"ŸaÎ~Š¢úMÁ²´—¤˜JnO'Æ„k(ºk1™[ç§³X)Ë+ÀQ¼[­Yušãã\ù2°s¨¾æÏÄ€•ÓÊrïßòŒ1•`î^D†ÌèòÁ«¡'wù›ü&ôs)º sç–’Ù°‚¨qˆÞÙø]‡ÿÊp©òaŽAªr<©¾aVÆ $J8ûÊ\ówèº&µÄEؘfÿ#Ñ©—î»dzÿ(òú×áJnLwáRžK8*ºÛAP®­Ü8Wjó§æSÛ]Þ\úaèF+ÍçÆ5\µ€ªi-ÆÿýP× 3š æý«GgT…¬(|÷*Šn|™h+ÖËßþyǽ—€ÇÀ܆“ž‰åÌ‚š)¤ú‚ãp˜ÅÅÎJ„á]üpŠiyÜÿDšW¥˜NnÏ<3`Êw)2ç?2R¼êp”jFp®‹,â\ ÷b;ñÛ9ÕEΓúŨvò·<ˆntrܺ1•k ߀üÅ«ÂSGE:!€HùèúgÉ\ÿ:Ñ®å~NÛ<¤°†AþExfa†£q>*¥gg®~C[SR[ ;¨ß¬”ÒÈÍFqjÈ›x_þ•aE¤ø”`/5s• ‰s%s³½÷¯9wNêµ`'~ûu¨²²Ò¹Àk,3n̪ÎuÏ™oTíÁ9So*‚eÓk]ñ2·`õH3`/N¤™ÌuhÜqP–„r<õga˜€cº³½ÿGSû?(©!cÜÕÝd*?cµÙ<Ÿ;B jýrW/tÞ™³ œuXã\™è°ó©g [~ˆV–óÕ××—#ºÑqd”jÆÀ¨ôp“?(ÔLOþS¾}mé?J‘—ϦÈû? s3Æ÷ƒFþ‰Ï¤¹Ì¥¥È+_¥èûß%Ú»sÍ?RÞì'4ù4D¥]ä(_˜“® ´Š¢\¬až¶îL˜+™3‘š»ÀY†Ý¤òÒ`ÒgÑä¯Ï¡Y³f ,))á 9“效‰:K›ë©x-ñš\¯e÷õãžñŠG(òÒ9d~v?"ù½ŸmCÅÜ4‡"o]EÑ÷®JjD—ÿ%¥Z©ºCˆú‘R¹9X¨Ç!fdZ°”mºG€¹Š9Ë¡0W2g"y2/çÊÜê‰xi°Bšôíçиqã0?ʹ¨= IÉÀ¤ª>õI¿Ï—/ÍuÿˆÿoñOÇCEÙ/ì¹° ¿cfm¬B˜÷O «{_9#ŒÝ aHˆd=ÆD áð”S‘¬@€¹JíYäJ×8g&3<#VÐë]imè!€Zýƒ“³¹g%ö`U=úp¢F0ÓôéaÜ8˜Z»×ªa1EçÝŽh{Dó稘ëß¦ÈÆ9¤F}…¨eïß5â Ù*WÞ‹²á¤†ŸBæò§r¥F¹]p•¹g…«:b€9“ _‡¼64ñsåõ5OtePóY˜M"ª4Ï<ìî_pÿ#Iɱ¯°8‘¹øñÔ*ÅcÇ£¿žZ¹;Ðc.¦Èª0jO õå€/ ÌœåBâœi÷pnšS]äÜ1©×€]Im¹„0­Á• ¢{ÑØsÝEP%ý¿ÊÝÏK(òá0oeîÖÑƒš©‘˜Q [üz€d€²€Q§FžAæ¢?H)Q%9gõÞ_×9—8gj@s©ç$È{%¬œVP_sþ¡òòrwQjUˆ$GÀà}#r_ÌåQ䵋…ü{zÔEèýüJOwÉïYˆ€µ×‡ÌèÈŽ'璳✙l@s«'8xih…´‚ú´ÈßÅöŠZ©œ=”ålÕ¬ŠñÔ¾n¡èg¿Á{€å{EºE@ ÇØ¿ÓU»ÍY~Ì8ì@,€H `µUÎ;®qÎÔÍ¥|öT¼ЊÙÕ×ìèëXëÖ­XTôÃVq¬•ÿ «Ça•8,[>’“|¤ Ô`“, bnþÈúl)Êa@ÓzÌçÿ>ÑÎeþã*$ê3„T¦U–Äæ>µÂBŠ—Ï5øÿ0.0FÍÈnLKÝNfó"<Ú½†ÌÆõ÷ÃçLJ¨ˆŒáçfR)ÛgŒçSdÙ“b ûŒ³ëìÛ0ÀÜv6úçÌd€kÝŒ2XUôÊàÌ´búš?ÇïƒyÕü¥Q­˜ÓÝÊ€={'9eGÕojlñòñfÔ°s€Ç.Š.ý™Ëþj]´rMQäëAªÛý©Yq ©Ú°QÏTRÕûƒü‡£œÞ½cú.}nW°y öøǧ–¡F»Vá'ç½€ö|{y¡†ƒ§²—wËmY‰@ÞÛÁG’¹KJ‹ps—éÐ`Îdî\±b÷|­¦ßVYþìšü9?/ ÎO+ªÏ¼@UAAAÿèHZ×` výÚzaŽ2 z"ŽLø£¾Ñ³¢á Ìñ¾¼GXô|¶Ý¼{#³ÀU—Älˆ`àoÛi)œÉ?Æä‹I¼ 5’x RË €wcÁ›È»7ƒü[¼Q¶'÷˜ŒagUMõ&ÏÞæRØ—Tý­ƒàˆ®z’Ì•ÿÄâ>[z›Cïï«ÇÈ£¦÷ÈéB jQÅplg½"]%J9©"β¸ËûŹS{XÍ­©jÓåý^¬œVP_t,ŒS”1È]QCf¥Nþ¹Ƕ½#ÿBLaƒ‡L‚° .¼Ƙo¹ˆÌµÏbçQ4à+={ŠÆÐ“<ËK2 >ÆÐ“)ºãžà+𝂳˜»Üô[ãÜ© €DnõY/ ­&>XÐÀ•ÚlÛ9•9l„°dë$l“ï²k~Üíï²ç.1õE ¥|\AÜC=ƒO¢sËÿ[¢Æuîž>Þ!Uw¼»<$uV! †œLôÙ}èåÁbXYõdâÊ‚³Ì¶í®4s§ÝÐF€«|퉽6ìäÏסêêê {)_·µ¦œ$›¨ÁG`KXg‘¢ÙTÏnuݽkß#௠>¹U,®ž.fº(?Õ¤¼ÑKhÀÑd®øV7|õß“jÖýªÿAþseg;*We{ª~“±Ô'TBŠî—ÜçάˆÐįñП Ìgt×2Y˽zð¨u ÔYÕ(}Ò®LkzþßCÀÜ.çE—ÕQhÿ#ª9Øy™J‰M^¦v…OѹÿEæú·RÖDÕÁˆÉ;Ô ›>λzgM…]®[çN»@W]ó«kbôËÀŠZJb>c­µ£s3\WÓQÉiI¤ª¦¤¥œ@‚-p£"à¯a­3õÜéÃO$còul*v–GPRÁ düs2×ü†À¯zï `½1‚òÓ©‡5Û„~‰öÑÍHs:5γ²˜»\Hœ;5ÙsNök9ïKê×àºVÔÀ|F¬bã\”K+ÊyÉiJ‰à°|•è‚_aüCgÕÇX¿1ýV2¦Â€Èvò·! †œJ¡£ÀŒ…¶o»¹¬Fô?¦…Šä!ÜZ=2+žUvË]qîLæð / MúúÌJ²à.«M‚\<{ÚAÊhóÛØØäÏÎ4ê3ˆBGÜùöÇ9KôT¥C)tøoI =ªGMUÿ{¼GnÈ]Tm{åîãèX3—ûĹSs´æU}îX–ÃO:s‡É­d‰ éÏ|6 Ý­UÍí @žžwÒº»úýÕv0¶ƒùî¡#~‹•ûFä6lðjÓ~BjÜyÝÖÓè7½ÛßåÇÜFÀ¨‘ÛÌæÚ¹ä®8wÚ=Ì©Z4ÏêÏŽÎ^]l)ˆJ¸ô¸œÖ•vùÞÜñi@4IŸÑÿ“¨)õ)2jàAšyo^-wkŒ¿œŒý¯Æè_’ÕÄ=¤{q£ô½&RRo¨ÆâVÊëP®Þ,÷ôˆ€ËYqîô„è»Ò5I«ÒÕ­=~¯µŸp8ì.: b¹,æºWs¹zêf®Kã:‰tŸŽ1ÿÿBcî”g®¡† #àÚÎÕ¬<øßM$o0 {/’· e¨â.¹+ΉͯžTÊoÓQ¹68Ð%ž åS&æÚ×°\46<ʇµxkßyw¥ü<ÕÀ![^’¿~íTý™d`GÈèÜ»ÛñS(’÷¨ê dn[”÷8—ìqîôÕÂ÷ÒÀøkeµ•¢°©LT’ëA€mÍhÔá ìI]÷ýîcúŽEÏÿçyMþú «ç!&à+ú#©J1ÚÁÈã U9&kàª[›Ø9×/Îí\ÏIs¬óŒm)½68k»‚*âÖ]HÌq5×¾NæÒ‡]€”Iw¯$sÉßRS´¬–B3nÏ©i~©Ðùncü¥Ø\èëU1ºó òMÞ! *Ææ]³¢Â.¹+ÎøÔëz{5 ­­ŸþÌ€«A[åÕ®pZ³€ž£ŸÞG†ÙJjô7ª¡;µ¢ ‡uËSXc›¡éÿ/k–õu‡Nj©ýo¡HãšÜŸ ‘,ù{w<$ê’pò@jî–»âÜÙÎ¥6-õw¶¯œ]úî€Ã+#ÃY ³&VÅ›÷EÞ¼”h炬ѺWŠ6,!sõ+½ºUßdì%QåýQÎvØ8:+ÀIô·•ü½æ@Àâêü­Pkn2O;—8wÚ3±_;ÏØ–ÒkrÖ òÙ: ÃpW†KmuÍŽËÍs)òò·°®ý82Š=ÞG‘â¿Bî–SÈdå£ îO©w¢c{äú³2©rðË–Õÿ‚ÿŒÒ©ai¢½[ÓY¢”Õ#š{¼1é qîlçÒøMî2M(É9'd–䣂ðnFÎ…·»Ì홀ɱٲ¢8òNŠ«0å ËûŠ‚@¯P%0Yêó^ß/7¦—ëĹÓSÂO¬µCº ­¸»2\‚¨•‘sv `L½BÖ¶ÏŽG%Z ’<ßRŽà'ÅB¾ì5ì8<Ê‚&]#$¿Ý PXÙÍòS6"îôÓЮ‹¨+ð W˸*Z§ ĉ㾦¤A 0Šr°RY^%÷Ót5wj.õ¿g 2ÕäHç3D,#’»¨ú£ˆJån¥f‚€Ï(^ @|­>£œböîÖÀÓÜ™b¡©Ýî»ZË¿¹X˜ßjy³S{¬Yt7v³3F_E ‹ª‚@Pv2XOÆÝóˆs§¯UòsÀR¼ âk $óìF ßD¬ø'k™g÷CíAÀkÒÁ¾dpç¿/(öWÉ/@ÃO 6¢Š ¥È>Á{p.¹Ë5wö¿ ³Ò =º¼Åt¹’p—Ë™G TŒyÿ³3¯‡h d9f¤1Ëkƒê» Œs§»q„`õÛ Œc4÷ C÷?dïøÝWL~UuÉV¿ò^ ‘‘V/`ô23쎻\sg/*ãw ÙÒÒâÎài€z2D/*$·djÐÑÙ£¬h*Vx¤ Ör9…=ξzü4XqhrõT¯à+®Ô“Ä0 Rf:L,ÉA ÍÛðQÚɘdúƒÅ]Εˆs§Å£Îsé>¥ßCæž={ÜáÒîk ¿f'Õ£dÓŸì|r¢u0›6P«e¸4Çz»bÑÅ‹ïÄ’†-áp¸ÐþC¯¯CE°Ð± B‹»Ù„½.Onô—»dù¯ ”Ð-{7QäÝ›ˆ6Íëö¶¬øqïvоy ©¯‘qÀ÷1}ÐÝâ-鮳¹õ#)!Ý5ÈÑò ñ1w9æLæN$·{æÖu2/=ÚJ±Ÿ£6lØ% wt­BÏ¿˜Eâ2î¥,ºÃå YYTÓœSÕÜø&Ež??7ÈßötÌå/PäÅ Ñ›^jû6 .7¼Ýµ’ƒˆj'õÅ’Ã󦺾]~ñ·œÅœÉÜ ì;·z¢¬Ÿ­lt×®]Û+++‡~— hLºðä"“hK Ô%RCÀ\ø{ŠÎýzœ‘ÔfËÝ»VøˆŒ? lÙ©2ºî ËMm‚”ÕRèØ‡;Ç7ðÉ=«ÈÜ C«0F·ÏÇú áau5[;¡pùH%îbט3¢ü}Õ @½VPÖç(æ3n:t¨þ=õs‰ÌO´§ˆºÛ*À5ËMÕZÈœ{'æõÿ#7ëg¯¦ Fß¼‰ŒiW"HžŽ Kâݛ;kˆe“CÓoíLþ|g»«–"…ƒ†ÌŽM±æ%—·}„5^£èšW¥³ÕÑÔ¿q9Õ™9…Ú Í§Z—ÄÏúû”Î^º@­>ó÷|Ù¶mWƱ˜ðˆçÊ1|ÁKȽ‘ì@ qE^¾Œh/V›ËÁj…Ñ9¿$£y'©‰—¶ÖæÚ—“êfLº®ÿƒ“þ–ôK…Öµf–RÆ: S®g`>™ËÿJÑ/µŠg )f=|iºôÄ9“]mÌ¡,šWõ9ö­Ë¿^ÆØUÑJò9²eË„ªºbñ¸@/xI›]…„¯>¹ª‘Eþ À|"Û³ŒÎû2çßeû&X—ÑU èDÁbGj" 67R5‘ÔÿN¡ÓþÀHäÅC°"©!Pì|Ä› Šs¦64Ÿ¦¦C/îöÒÀÅÙÕ×¼€«îƒYŠ`ÎM$'0÷lNП$“ÿKLþîl÷ W³'ý¢Ÿ>L†QLjüE=ÝšÞßw.î¼èRy…¹ zxä/ÅŒ5æk}>¦|þ‘¢Ÿ#¦ iWz뙥¥™eà,çLûç¦9ÕEΓzåHTLæsdåÊ•® U6¤£Öò)«0›dëÒ@?@!ÿ':÷·d®|²Ãw™þ`®|º£ ˜v:üvŒû#ÒßkQaRc/¤ÐÉ%cìé°/¼¢ ¯ N~n9+Ι]y4¿º®°_­ e,X°À•`–Àš2 jTÆŽ]?ñ dа!ZˆÉh'Wÿ²ÉrÎÞïЊEß»B¥d®=(õ0)ºòEèñÿÛû09ª+ëW=Š3¤ÑH#rÎ$’Aäd‚λëݵ½^c×ìz0k¯½ÆÆÆÿØl²"HB (ç¬QÎi$ÍTý÷ôÌ‘žJÝ3Ý]ÕùÞ﫾¯^½xªºÎ}±ðz‰´5%—ÿLîÒtž®ß¶å24p·)é›ìñcdÕ„J ä~x‚õ4s¦ß ¯ÆÈ45¯t˜r,$uã[o½µWÖ5M­ˆ+R"Ÿ ¶¬"å¼5bø—€†ãá§«)C@É?>~Òøh|í›2$’}ãÕÛ6M–ò5÷¢9%²lQ60ªº8~ÙþÒmœ)¹ñOò…Å[ÃN¹0ÒW³Rp%8S¢Ç2RL5v´0 >r¢ºq×®]G<c½JìBÅòõJ«cy«_¾"p`y¾–¼0Ë}¬¶yÌ_[þqopýAÓ8OÈËæ²(îš'šswLdÂÓ/ Digœ ß2‘K¿hÇ»,˜¶¬½Ò`“ÖÁ•àL) ß@™É­¡”?L€⿃…nÜ·oßnHET‘Jž'}xû—¦/qM99Ží¥~Ÿ)ÚÙþIµg¹ñ–ÿ2©(¡>¸Ò˜=Ë$Iÿ²WÁ‡CM>ÙÄ`|”\ûkÙeP¿ÚJì¼²:SÒÍ\üSJ3^¤° ›ôáæ,Ʊh¦|ÀÛÇŸ‹žç6î>5âý)3ê%ÿOËæ/»òî:ÝÊðÿß]ñ'c­ÊèmbfîêÇÄÙLþCþÞÙÕ]ǘ’ëgL'iùfø^äd~úºÍ\Ù ‰Mr¨l ôíÈa( Å.,*иmÛ¶@€W>ˆi«.v/)„ZäwlòÏïšd¶ô˜°à»’§ýÊË@dކ·e¶t»ßmœ\!V[–j—\ó[c*‚‘“Ëgíu¨øÍ\‰?ù3Ýм° È&~Ûݰnݺ`³g*†±òª ¬'–ÇT²„€’0à÷¯3ÞzŽÅK*ÑØÞªÇLä²{dÌ_–âå¢Èö·%WþBV#ÏŪ%U¦ò¡I÷næJö؇ëÈu¬Ûo8"ß¼—ãØvãZoÜ-ÓŒÙ-Ëé‚®é—Ï{kÏé¯fëv;Ã>&¿aÌÖ¹Ù*Bæó ØKŽ”BÇêþG]È©¡Õ+l€cAiÅ@7lÚ´©öŠ+®`˜äuבÉÇÑ9€»qš)÷•¦ï”çtIó¸p…Fþ2¾é+«Óã"cÚtlùæàs·²Ÿ½·ë5vÚõ¶¬K:Ùrœ$®ºkž6%#Ÿ‚±¡r%}[>û¡âù¨T1D8R¢Ó ’O¤;jØO, KŸZ±bE°!XWØbÑÅ •‚@àÄãmú«lhò‘‚¨NÎU¢È¿Çhù͇d"Üu‰Œ'öË8ýo»îyéªOÓ„½ã·õ%™[ÎÝþ¬H&oG&ÞeÜÙÿ™õ¢¤½ÂM^—á²iæÈS’H,¥_ <ìÈaÎ@á ,$5­˜†E‹moi –Â/¬øÎÁ&Y¤«FI3ÑU¢Mš3*¶ä …ü«Ï7%7üFvœ{Ô8}ß™ ù{Æ[ý;Óøì{å3¶O¦ü›Ÿ)wý3Åöt%\_§ÏÆô–žš—(7 G¥*àFp¤Ä·{È£ÔHîP$슅%ùCŸš3gNíîÝ»·÷êÕ«&­+dŒïত£i„C ¤½1=Ç›HÏ ŒÓ³ð_GÿÄ>ÙÞ÷sù=æß©ÚD.üªqª¯H>|×`ÎWÙ—Á ¦»–J7·¬t–µð*ç"P2᫦q§ôò¹à¶pS7‚#% ôØÜI> zì¨a,¨_³2 ²ËѶ €×m´q6¿»6ê›ÛȲ HßwÓï鯕—z¤Cn—7_KòŸ!cÒ‡·åg dÌ>2ê#ÆóïòŒ´K®» ùˤRY¢—Qñ\Ù¥o²q†<£ÙæMf²402èFŠ)ÜIÜঠn”ø-µþÉ«A²9+nØgA¡IþЧ6oÞ¼õ /d¸äµ|Š2šbò15F¶(«4‘á·gÐí²AH·l•¢8ò%ùØšŸõ-­0‘w|Gz….KºüÞ®¹Æõ5y…†7Á/™B¸Û_1%jÄ…Ì#=R¦ÊýA·Ü@À=^ë\º¤Ã`Ac˜¨Yâu–Im¥ûøÔ‰ÐÁÐCFÄ?êc²ƒÙ£³°CN]“ó#ïä_5Ü”Lú©t£WùkÖúùþ·²JþÑî^.ä&K¸[[•Ðzm 3„ Dú_cÜõS ¯~ÂIQn P³fn´ ›C‘2¹5@.gG s 2 ÎÖ?Î1ùïÔ¼yó¶Ê\‡Ô+iìc vAÕÚ´3‘ó>aJn{Î8ÃþAÉ? Ÿ“d¾“Í…¦äº‡S#ÿc;Mã,YJš¥–ÿé{!ó›½½¯Ÿ>Uǹ8# sˆÄë"œ„j) 8Ü(Ña€+Á‘6¦Î™’PD$_âsßþMf°N4—ýë Y´áœ¾7Iï`ØmÏ, .'fNÄìU›+É4B%7Òµ lWÖÍ©×_ÖNêÒ¶³ñ*¤_c†‡@צäÆßЯ@E’R¾“ÛR!ÿŸš0ç­ýSîtýó±ÃòÓy¦:ø´{±±®ä¥Ÿ×¹¿LLï¨ìÍœÈñ›3m. ”G¬Èé2—]p¸Y©“3gÎÜ$_<:«@‰úyÝÇœ›ƒ?G=O/F•CMÉõ¿3¦¬&ÑÛ¦áÂ@ Jþÿ"cþÒ‘–§Ïxä’¯Ó©_4<ã®þKnÖÿкõ*ލ‘Þ—äæ½KáÿäU3fÀ…àD¹óv€¿$iy0ÒeØ…'ñS7HwǾ-[¶l R#¯jBè7(ò¶’kË·^Ï€©h¯çÅ©DÓ8)"p¥q¾7ÅØ-% …ü¥ò‘1Ÿ_iù•£›…ûñJÉQ)ä/Þ… yÀ¯ç…Y”TÓòªe2c‚ %‰D†ä;j¶z¢FÀÊ•+7Œ;öüØEKÀ·R¬¯6daa}5H Úw2ÎEß ”„FN’ÿÞ¹páÂ@=FvŸózÈr@•´#9O–ëJ{! )ƒB"¹/‘!ï okhÁ&§¥mYN/W çtì•+EI©^•ppPiæ@vÿ“mδ¹4HV1ã¦Ë@fvÁmC•ÄqbòäÉëöîÝ+æ|êâõº,õÈ31*jdìö «¡‚#P`ängP8­ÿ(¸N:;.ƒß>ÓA'È&„b‡® ËÕ@^ï`ÜîJýði[ò"ÉœishZ`H§€³¨Ü´p O­]»v߆ Íâs{])I©¤Ȩê’Ëtl§}êpÓR¿Bèög½ªdÒhùžÖN»ß{¢¢à:E!¬É&NA¹Ü”:Ȭֳ¸\I΄;m’)€B¥hé@ŸX²dI À)íe¼.%)d¡Gètì*ÿnlUÒŽ@”üe™ÜÞ5’Uá<ˑޗ† ]YßœÆÇ醕©´Ž&„æésÞe€÷‘fî³[ÿàDJ›¤Ó`Áy‡Y1Û8!K Ïpò°­¤JZˆ ¼.ð8WZ Vh‰žEþ…U9§:äÕ:¥Õ2%GÇÙ;IÙÊzÖ ÔÚœƒ€‚QÛÌ}¶`s$yy“KÏ)GPtvÁQ1T‚d/ÀɧžzjͦM›‚½¯Ê[C2× `gлpUÒ‰€¿;MZþ{¤åÏ¿}¡è™)]uAèèEªFç$V‘¾ÁÆ…C*×Ì×çœ@Àyà>Iâ¤äCò#¹9À6I·€‚ó³rìæ€np]÷ÄÒ¥KDÊâUŽ“eF:ñ&eãE”[L×Qñ®ªDÉÿ_íö#ÁÜJÃéÚ_æ¤aÒ^-°t å zO:’-Ì4±¡S>Š,irN€²ƒóÀ}’Dƒ6'’'É›ri=j& V¤ÅƒÊŸX°`A°IÄísyëµÕI!é©c™I–là†ãÆ{ùóBþÿdsÎXx§sMZòrÞ&k KÒ’vª‰:=FÓMz&TCàd Â&–GB¹}&Nµ™ól€Fy’:p^-%n•€@Ó²¡¦pâÙgŸ]-K"vFC¦øãõ»!Ř-.½B»›Q^ùÏøŒqw-+ìʇ8ûÿ, dy¤ÿegyeûÄ÷Ùl!¿ò¯Çøü¯ïõ ®çI"ñÆÿÁ‘6wʯ¥Èé67-Û ùCŸ\½zõÙ €¤.ÝÇÓ!ØGRϼ0c:øb—Jø ù¹²^áãל¢3ösâ akáJés¡qz_BJÅ“„W·-ÿ* Ž©ÉDΔâ·»Â"Ú 3$ƒ ”o«BÀ;u,Pü¢,äïN—uþ˜ðWÌR·#£µwª/3%ïþ«‰ô{GèùF\)i?eœ>×…žv±%èmÍ/À(ÌJ3·±õφ¯Í…6GÂvÉ”`WC¥Ùõq–ðÜsÏ­8xð` -¢¼ïÎPW ]­s×K×­‡[£’4Íäïí*ròp‡Ñàɰt¬2ÎÕ¿4‘aœ*Ù/HwŸ‹LÉm0Εһ i«D nk~ÿ˰’×?X÷?8 Ü&Èù ò`Æ[ÿ¸‹™0³ŸÛ‰eÔÏž={«ì“¼|Ò¤I—Û“r·ëb¼š‹Œ³ùµ¤¢i` W ÔÛt/ ’„œ2®éÍø7ãíPò^ÞÁmYÛª½ÎͲn{ÿ2ã­{Êx[æïö_iE¤YäÈ0¢Óo’q†¾_–øõm%‚^Noýß›š€ÉDÊbX¯ïE²É\·@%§Û$$~h’?ù1P^ÉDΤÀ. ö ÒñŒ€`ônS¢@2ÏÂ9a½«Œ£›ƒK\ÿ¬7níÛqƒÛïà&±ĘLdzÛã\„C"Ý"ß^ã Æí±½2Oãˆx ãwèÚôA±ŠaÆé>FæT&šº†Koí‹IÆÈnppIPò_.iÄ#r! reÐl[ŸI€…a%YiX@áqü/ùËòO~ò“Û{÷î]ÃHIëê+Är—?q]~î7t}ÓaŸ<³ºÆ91dIþ[%¾XB:a¼Ýo§çŹQãNýŒ#‡Jvð¶Ï4Þá@Ÿ}ÉlÁˤå_=)PžµµµÛÁi’Èq9ÈsÐlýƒ É‹âÌœdk+ x˜²Y®7ß|€¥.²ŒÍ|âFêÈÿ˜Þ6BIè.*ù· ÓÎù-_׫ŃÀò?äU]ÝÁ²ó_À¯N‚ËÀiRqÿúrù:£’i€„f4€†!p|ÆŒ?“æ ù€Ü¼LWQJ_ âí— \uµR›4UCÉ¿U`½­óZ £ŠýKŒ»]Öÿç‹wD9$`y›¹Œ­›ël´¹1`މGÏ;¢¢<‰Ÿ½Ç}ôÑ%²nreâU‰²cOãõÉ‘®ÇÅË/os~×eS%ÿ„àöö¬6æÈÆ„Âj ÂEÀ{ãþ¼ªœ'«?ŒpH‡Ë$ ä8pù|QɆ€ Ú¶-"‚sêØ±cusçÎ] w˜ôx’)aà­þ[Ð[P˜ñAþ/Ë„¿Í Sµ؞GoíÓ…ùh­BÀ«mÜ­2?&ÞÃ.z 8 \&É`ÛCò›Íy6Ì-ùèÙ0hå@Ó‚>§àÙgŸ]zäÈ‘CÉWËŠÑóRÙ°å¡Îdðl7^í«ÉD)ü°$ÿ­Bþ* !à­{Aþáy¶õkB5Ó@­" «@¼?j5XNgô ¶™¸ &õj©õî³91£0dÃ@m«‡äO«VÞǧL™²~ñâÅ{d2àˆ#O•ð–<œbÌŒ¦äŸÒMõŽî7Þú§RŠ«‘òoéÆ;€%ðù#MœŒÁ]à0©5 öç IþäÃŒ¬†ÁŠËJ û¨1~H¼ï•5¾]¥QÌ‘½Ú%ÆÛ6½˜!hª»’ gÀ[ò¨Ägc'PR9_8°Ò¸oý>_JÛTNáŠ(g,u3wqí¿Ík$Û˜[jѳeü©i¨c?þøÛk×®]“Zõšc•´5îÐà›9*CžGöýLÞݸ=E*Jþo<Ö{«þ_àt4ùë¾òòFϯ¡Ÿ(Wgp¸KÒ8&‡Íix‰Ò ÿQÉ2¥¸Ù2XXTÜî 8 OÍÉ;vœ3gNð^€áÿ ·g¾ª“D]xÞ²“ŒU Á£äÿ9™Ä¤cþAï¨÷ƲZ7ç Šc>Ä÷^û/ÙóS>õL…#“±#N0Fp L<°UqdÆ '¯¼òÊš!C† ”óÔ¥b€qVÿÕ8²…™ªn?Œ+d¸cž| E†SJŠ 7äÿÊ]2ym–>/ò¯KäI$ŒÙ·>º2Çé:<õÿ²ÆÌY¼­ÓŒ÷ê÷òî=kÙøgÒ=Æ4^}õÕù÷ÜsÏ ¹AXÁ†98NÈáï `@ÖŒ€l÷&§WØC´–`=á8þüóÏ¿ÕØØˆ0)‹×©¿l tIÊñ5¢ p¨Öx3ï,üùùë}oνòažÍá'¬)fo×Ùã›2°èU•:x}/1àˆ ŽWIœùo÷äTëõÌåà0âaÇ|ðÁŲ§2€ $îèOН‘åfm}ÝxsåO^¨¢äŸþ;{²Î¸ÓÅl@/©J! àí˜o¼©¸§hèæŸ¸£>¸Ðà(p•$äïþ'¯ÑÈZ«ß®d¶ €`0Mþ° ðDŸ:uj`Àt?߸U#$9• x«'‹pw$r3®’æî˾ Æ›ñùÇã/®’Ïx[§ ù˽<™Ÿ]”ª.| š9 ­plä3›ümÞ“ Ù‘l¬5À°‡l#àD|àMY^±–‘RÕîØJ5ªÆ³ðV=/cä_.œáÿ¬¦1«šêL#Þ6éMzõ®Ây†ÒˆU®&í­úƒñ¦}-o[þÀ5 N7£$9vÿ“ø¡Ái4Àu༬K.¶%DC€`‘ü¡ë·lÙ²ïå—_F÷J0©¹Æx݇KCcGðÖM7î”O‰½‹ù.y,$ÿ ³ò¸ùYtoëB ŸÁ\)•¼A@Öù£Лûã¼6à¢\ œTÀMà(I²Í]ä3¿ÍyA³ ? V€äï èÀÆ@‹e}eàoÔ6Žûæ«:(Ûß2îßåÃ{ƒÐ-JJñnijù+ù§_‘<ÙcÁ}éòßFršFº8´Þ¸Ï~H6vz>Ý9¥=ý0¸œn’Ârìßîú‡å\ëÀæÂ2@”ÿz†‰}pY`dûöí ãÇï>vìØaˆ˜²thœÚ™Æ©ÓMIRÆÐŽxâ¨ñÖÊËÀ=jœ^ÉÍ%ÛÒ.¨å®Û!+¾h¼×¤s`“uAYA n¯ñÖ=kL÷!Æ)"h¦­ €ž²åËÿF&ÝÓJàÜ¿ìU 5Þ_ \P™ùÿÊ/ù˹’½ô=œ `hìæ„äŠ@0ü†Ê&¡€}JNœ8an¸á†1;v,eÄT´WÚÝD6NM%ªÆ‰…€'7;ß6Þ¦Ó]Öx—õŽ*û~x‰É–´ÞtùãÐ¥hÙ¿!V 0 °N6ñާúB1$síe•µÈœÞ®…òŸ‘‰~ØàGö)i¼ôÆHc0ˆÈ¾?û~ðƒ<»nݺ­’z@ü8°ö=8ü=9aäÒ¿ äOÄOmŽ}ââ‹/î1bĈÁŒ’î<@k®ôä¿%›RýÓ©þ°ñVKKnß[Æ©”¹º§+§¤ÓnR2ý‹ò›,Iü/Ury7î”P­ΘŠ>Æ ø‚νúåY‰®’qþÿ’OúþJèí@ž>~qÝž£w¾L@ (2óî½÷Þ;S’9(‡MþÜü‡­9Aü¬r.,HŸ[ÿÐÑÖ¿h”nçºë®×^DÜ)‹WÑÏDÖåÿ8Vʤ3â¡mÆ[ù”tŠ­4NYUözÐâßð7™m.Ý–Kÿ,ÑÃ鬵¦2¬dÖÉrÓÝ Ä蓽ç'¬úäY:X×oÞc¼y÷IOÙ–<+}ëÅmœô]y¦jZØBˆÃ"ÿû¿ÿûìŠ+6K°:9Øò‡f럀= °…T3w D›KBâg‹¿G9ÐÝ_Ö|tÝãé§Ÿþä-·Ürµ¸Iäå3‘m‹¥¡‘@ Û ãŒz¿qú¿Ó˜Ž• D䀴\Ö=-s¦IËEçzD3ûÑ«ÇgôGåù¹AúñZP ã{ä?#Æòé})àá1·Ï…ƽæ×á{á…f¾ï}ï{TÂìU±X£F `´þÙ3½¹Ö@@°:g€½4ÚDD®¿þúqíD!eé2ØDÖü=åè1AŽK÷á–¹òUAY7\ûªü-öË\AéÀ1ƤA,Kª}͘Iwåÿï͇ٵLìp,ËUÉ{ŽÊ;vã ã­ø£¼j7DßNiµè¶y_µ¬U@zÇÌ^nY÷WùHÓÿIkÿÿŒÙ¾PÚ±y¾¬·E@ã^)[Qw”^ÉRWWwTZÿÏ-[¶l“$òg÷¿¿õÏ•mrKOÔ\ë@-Q&=tõãßnþ˜½Ï<óÌ'oºé¦«äz ‰Ìýº Ì”†FN|¦¹jXÓÄÁréêíÜOf»^!O€Üö¶ågÆ~»?*à G·‹–ãÀ:ãí]ÝÔMY ““ÎTX]-"‘öžª‘Æt$s¤— ÏPû®òÜH‡¡ƒWˆ&âY*FÉ×Ëðô‰ýòŸÙzæ?³o­1{ähÀPuñˆ;äZã^ü‹”“'Ožõîw¿ûQAN,Ó˜­NÄŒˆ37¤ùß‘…±J. ]'QÞü§t«Ô=ñÄoLš4ibYY†R–Æóï4Φ9ÆÑÍHRÆ0åˆÀ|‡´Bä äL ¤:7påµ°k…ñä è³C$Tûðä+¦Ñw½ÿB’çhýƒ{$ºûÁE67«ÀYä/ò™xå– •kB°  €äA#€€×ýéOZ:k֬׃VÂ)íeÜÑ·MFã+Š€" ä($ïú Î÷H:0@þä$’?9‹­~òZЬCŸ‹+HÀhX6àÇž|òÉ×1“SÕޘϯ£tª(Š€" x·{£?¸NàpŽ$„‰~6ÁMžby,p¾éH W ‚Fm™¬.tÅ,›9s¦Ì\ (mJ;þ_&¢ÑE@Pr 軽m ‘âh•À5à9ÁÄ?¶üÉIìð·üÁe9'¹j(€ mÀî èu=öØ"Ù‘i/#¦ª½!0^åT£kÄ:k¸æšk†ta)iìa_·Þ8û6¤]#)Š€" äîÐëŒ7âã #¢ÛößÿýßÏoÞ¼YÖG{ìuÿ\ò‡žNùç´är£…î´´ m ¬î•W^Ù ;3ï@F|ÅxíKÅ¥¢(Š€"xme^—¼ËÃp 8FÒâÒ?òÍIä)òVY§-\ï@Å“ép6mÚtüꫯн{wÙ^.€`‘¶%²Eð‚‰hTE@Pl!à^ôoÆôzGàìW¯^½öë_ÿús{÷îÝ)‰akÑD[ÿ9Ý =¸y´¦h]ÑâBw ­0èã+W®¬•ÝCamoØ?¯ûP䯢(Š€"GàÝwxN·HZ ›sìÉä'òUY§5|è±z8F Έ,^¼øà•W^Ù»¦¦&ØŽ²?½W9ÒDÖ>#Éç´!'åSQE@ˆ" ïîÆkå»eÕY¸páâ/|á ÏÖ××ï—Ä0ù­ŒûÓ@£Ô?öŸó¤‘/=‚í9½ Ã³{Ž‘]šÈ à &•£Mã¨÷KCc+Š€" d wÔ{Œ©8?p¸œ"‰Ù­ò‰?ïZÿ'_zPV»€çð³{Ø `-Ztð /ì6lذHzN0Îúçs ÆŸŠ" (Š@®"à•U÷êû¤_¸mà"Êæ|õ«_}I¢ÀÖ?4gþÃÀ#€­~jñÊ]ɧ Py°»%V/ṉ‡~xþîÝ»1i#˜È—ýg°44¶" (Š@Úh¼ìnùòcð\àpˆ-?»»ßßú‘—ò‚øyò©e¶{ü­Î 6ëÖ­;>hРN&LÁ §¬ËûÉâÆÙ»áì[mßvu+6ú è3 Ï@ÖžwØõ²ßÿ?§üš·#>þøãÓþóŸÏ?´þÙò‡!@c† 0ò®õ/eΫ!”—€­áéÛ‡1Ž^vÙe5ÕÕÕUH ˆx½.2ΆçŒsCA*Š€" (¹‚€×©›q¯û…°ZûÀEzûí·W`ÙŸl.·[³'þ±ë“ÿl€f_à¼3™@¾õ?ù㜀ӀÜÀÆòòòY0®¤¤×Sy°¼ŠY?MÒÀýVQE@È>²ÝïUß5¦kðÎÞS§N5ÜÿýÏËÆ?Ë¥^Gä`ëŸä›üó²õ{–Ê ‰eЀ¦`æÍ›·âĉ˜Ø?3ÈOçAbn–m‚×IEã*Š€" „„€;ü&ã çK®˜øwçw¾(E;$º{iØÝÿìúÏÛñ@¢ÌWa—‹2 ×eòfáæÕ=ôÐCód/gläXÜ‹¾i¼òžÓÑE@P‚!àuîiðNCÀà I ÛýÚ-~òŠÝò·É?Œì3žF>÷¬–zØ àaB l Ôá’K.ň)ë’vÆ«n"ë^Б€”AÔˆŠ€" D "]ÿ×ýĘÎ&Ôýw¿ûÝ”_ÿúטùoOü³{h ]ÿìþÏË1á|68î;G7´€ÃŽLì8p饗VõíÛ·7"’²ã52‘]Ë%£‘E@PRC qì‡úÁÔ"ûbÉPñ_úÒ—ž¯««Û'—0ñÏßý^œùïK%¿NóÙð#m4 Ù `äÆz ®LÚ¡C‡Žþ’>ï)«¶Ï2NvˆTQE@È^Õã^ñ¿Òä Nc²ÑßþÿùŸÿyQŒLî²'þÁàp²Mþv÷^¶þqŸ‚#‡T²' xÉŸn´úi Žìð–,YrtðàÁ¥çŸþp$xðzÉ.ëdi`#z„TE@PÒ€×®ƒqoú•1»‡’ÕÿøÇé÷Þ{ï«’Ø9ÐåïoýƒüiØ]ÿâ¿’ï§@7жàȧ_|ñÅÕ½{÷>“¯}Wc:u5‘MxvTE@PÒ€;éëÆëuY(Ù¼þúëK¿öµ¯=o­ù'ùÇkýsÜùçmë…/$ –!«'ÀÁÞŽãx—_~9†:ˆ@Òm¤Ì]'K7JF#+Š€" ´Œ€;ì:ãÿb˼zHäÇ?þñ‹3fÌX%QÐõo“?zü³ÿIþyMü„§ Ô%ùÃŒì ðä“Á‡†Z:~üøar=°x½ßaœÍÓŒS8pZš€" (ŠÀ¹x]jŒ{-vûkwîÅ|þüç?Ïøîw¿;K¢Úû¡€±ÿXÿHþÔ)äœQ Åð£Iò·µßpV®\yH¾ØC–öô'ô9Èޛ渘¢¢(Š€"^ÛöMãþeÁq¡L .\"]ÿ/X]ÿþ±?ùÄÄ?û~’@²gýxMò§;Zo ¸®Û(ß ÜQ„SÖ*e>@72€QPظWÈl½'ž˜¤¯¼û÷ÿèG?zqæÌ™«%*gý£åƒ³þý@Þ·øý0’`×Í&ÛMC€Ú“½÷ïß¿½l|i”óê·gÏ»<êVE@Hwä-Æ;ïßSŒ}n´Ç{lª,û›-W’íú‡P0†@¡ {uÓYÓ9ü@üÔ4Ìo¼±O>ÜmÀ€5ŒD{½/3Ní+º?@5®" (‚@t½ÿ5?“·w›Pðxå•WÉ^ÿ±6ü‰ÕúG·AMü³A,4u³ÉŸn’>5É:ºAlqBv ì[QQÑ~DT·ï¤èVÁN†•TE@P’EÀëØÅ4Üò[ã´ï’lÔ˜á·nݺM&ý½$“À7J»ë/jèþoiÍÁ´þ¥ž± õhI@ú¶!ÀsÛðÖ¬YS×µk×1FEDZJ0‘kNÛNÆë9JŒ€—Ä„-¨g&‘êkE@P‚! ­5ÞtŸqºß³ ‘]`eŸÿ—|ðÁErjïõ–?Éãþ8øµ?»õ_p/òBì{wáãB#ä·mOº†v=ºlÔ¨Qå<¸t’ï”–™È–¹ÁÓÒE@("/»Ë˜ï ­ÆO?ýô¬;î¸CZd§ÉŸÄÏÖ¿MþüØH¿àˆŸ ª€ú‘ðéæ948òÕÀÃXØ«W¯ˆXº“y¥ÛŒ³W'ÆRP¢@Ày«ñ.¸3´ºJ—ÿòo|ã/î‘Dñ©_?ùÛkþ1îoý£i²€›æ—–ŒFžSÒUtJ†”–Jó=ñú\iÌîEÆ9²3„Ô4 E@P ·f¼q¯ú©4Ó¢¯äÀÝ»wïYò÷Ò”)SVIbØ© -~Û ùM×?A-tÀ&|ÖÙö‹¶úå‚­ßzë­ÃUUUÑùŒH˃ìõ¿Ú8›d§À˜w¢¢(Š€"àGÀ«þÞù°1m‚oË´xà—~ò“Ÿ¼&çñ>ôCÝþEÑõOl Ý@=Iø¶~ö€F@Ùzç¸qã:1b"–ùä@ß˳þEãœÂó¦¢(Š€"@¼Ž+3þMiOzÖÏ<óÌ+Ÿýìg_„ÉV¿Ýò·'þÅûÒ_AvýØb0XWj›øáÇsÛ€díÚµ/¸à‚îòÕÀpæÈR¯JVlœ&+K1Ĥ¢(Š€"`d›ßÆë¥Û¿ûèÐÀý]–aÜçλ%Ñ£rÄ"´ÆHþö¸?ˆ¿ É_êWËQO<„ºéì ùûž<8'ëêêN\tÑE}:wî\ÎHtyãUô#`²””FVE ï!ÒÆ«¿-=¤×„V•íÛ·×þà?xiúôé«%QŽûs¶¿¿åÀOþ¡•%—*¦›üé&ñû5{ÜeË–)++s.¹ä’amDB¹™]‡¯}[Ùº ”ä4E@PòÆK?o¼á­øõõõ'î¿ÿþɲæ¡$ê_ïÏ^´ü1é­¬÷çšqG묘 ÜÔ–„FÈßv{³gÏÞ=hРöòéà!-%Ôµç‹Í¹ß8»–%M+Š€"P(¸c?(Ëý¾juüñéò•?g=kÜŸÄÏÖQwýðb3@ì|ÓÙ™¡ú³à´1°hÑ"lT>xðྌT{5—IçÔ:ãìß4)¯(Š@^!à¹Ö¸“¾'eæk9xñ§N:ï®»îzñèÑ£˜ñL»ÛßOþìúçxÑÉ›€',ÖÓF?~mär7mÚtXzºWWWW!¡àâÈòÀëŒÙ÷–qmžœ¦ (Š@ àö»È¸×ü\ÞÆáQ,ß^y÷Ýw¿´jÕ*¼L±Þ­~û Àõþ\òWt]ÿ|DÂCŸ)æ—&ñ£Ô~Ò÷Ÿ{Û¶m«C ^&ö–IÁ?ÍUöxƒqvÎ7ÎQLVUQE pðz5î¿‘)èmC«¤LúÛ~Ï=÷LY)‰bÒŸMüpÛäoûÛ­ííŽäWBñ ÿP&–¹€îĉvèС}(Õ”¯z¯7ÎöÙú áPÕDE ðz •ü÷¹%QtûsÒ_,ògËãþöš”§([ÿ¨x±À€B²Ç¹ßMcšF€#+öÈVÁÄèÃD‚êÓFÀ–éÒ ß ЧÆWì"€Ïn{,tò—ûÌ—ÿ/9rd¿Ô_øC·¿Mþö¸?ˆŸ“þŠzÜ_p8-jœMö†äo“~,·‘¯aõêÕ¤ ¢OŸ>Õ§Q è€`Èǃ6‹pϵŠ" (ù‡€×¹§qo{Dö÷íõaÁ‚oË6¿“׬Yƒÿö6¿4lò·'ýqì¿h[ýöS¤@6éÇ{0l#€óÜ;vÔË–ÁGåÃA•òÁJÜ@îv²È`à5ÆÙ2S¿ H¬(Ù@-¿WVjö+V¬Xóï|gªlжN¶·ùµÉºýIþèöÇÁÖ¿8‹·ë•‡¨Є~iœñ9ÛÅ붆!à®[·®îðáÃÇåÃAÕá,DÞb¸ƒo’9bÔã9WQE ÷ðºövû‡Ýòß²e˶ïÿûSþö·¿-Hþ6ñÃȤ¿x ½Ü7ĪÐ2˜${„¢Ú4by ëº'Ĩ‘o„¶Æåôœ5Z¾SzUPr(ùßúhècþ{D~üãOyä‘GÞ”ŠÆÛãŸ-NúcËß^î§äßü¤¨ÿ/CÂGºIü±ü\™¸¿mÛ¶ bômdÎÕ;^3Î1ÌwQQE ÷ðª†ÈR¿ß†Nþ²Öÿð}÷Ý7EÖûÏ—Zû—ûôí–?É“þìn»û?÷ÀËB‰Ô8t’½ÿŠíOCÀ¯Ý¹sçî–M]1Š1ÚVW0¼!7Ëǃçˆîè¿9z®(ÙEÀë=Æ4¾ó¡P×ù£FÇE~õ«_MùÞ÷¾÷ªœ¢Ûßßåºþý䯓þ”x¢@ldHöÔ±CÅîpgΜ¹³²²ÒL˜0aHD$^ä¤ýe³ oÈ­ò퀷õÛIƒ§E ]¸ý/4nÈ;ü¡¬ ¿ùÍo&ÿÇüÇËrJòg‹†€ŸüíIv·?’Ó® `‰>gkäÏàìÀ9ãxÓ¦MÛ^SS‘ž€¡ ŠÆ¶Áƒn‘O]¬Õ¯†¨&¢(Ap‡^cÜkïuo–GÆû§ÜyçS团Øýа[þJþ.A­@‚@%Œäµ4e·Àm}ûöœwÞyƒˆŸx§éBæÔ~X‘x< ©(Š@ˆ¸ã>`Ü+¾/MŸð©ä±Ç›úùÏ~²L®FËßÞè§5òǸ¿Ýú×–œ{þ]‹“Qy“ìýÕ¢Ô×{ùå—·Ë&AmdŸ€AþÀÁÎåSÂ}¯0ž|(²ma°¤4¶" (É Ÿ@i|Çç7áK‹¯½dh9ìã?>ã‹_üâä'N`Â_¢äÏIJþ-Ã{úª§¡HÈëI÷ûᜇwêÔ)wÖ¬YÛ¥' Í˜1c&”K2zœo¼®5&²y¶ô;à¹WQE Èg|¯ýŽñF|$-™Èþþ/K·ÿdÙiõ€d@òçX?Çý9á“þØõï'~mù·r‡Ôh æË~’g,Ûßvã:Îq¸bź²kU-Œ€Ñ£GÄÅP¥ëpãö'[¿bœü/TE@¯Cg™éŸ1ý® ?qIñÉ'Ÿœù¥/}iʰÞ[üÚÄo“? ´úí–?ñVi 5ZCèÌu?ÁŸ¹r¦Œa¨nOV²4¾úê«;0 =p!T)ïcÌ Ù:xÛ«ú¡PÕÄEx]jšöõï>&-€üùÏžòß'"üí%œðòG«Ÿ-ŽùÛ䯭ÿî’ €d!±S[—b:އ+F@ƒµ½zõ*‘ Œ#ˆgû.Æv›1{Þ’½vIIã*Š€"p¯æ|ÓxëoCÿ¨3øãÿ8óË_þ2ȯø‘üãµþín’?Ÿ¤OÍäUÇA@ €8À´à BÇF þ×ü?2'`[ïÞ½#áO ”J:È^ï’­2¶g÷𦒡tz(ú è3Â3àŽºU–ùý̘6ýï´PÎ1áOZþ“}ÝþlùÇêögëäµâ(¸UD@ €ò‹Eð‡ڎÆ8žÌ hœ>}ú¶êêjgüøñƒí@¡¸±L°ÿµò®rY!°@JÅÿF(©k"Š€"P ”´1W~Ùxï’æNxû™ÙÐýþ÷¿Ÿ†Ùþ1&üù ô åÃóÇ»–ï[jñRI5A)±0ñ>?4ÝÑÕ/½ôÒVù„°'û uÇ@–·jœq{7ÎV™pJ'ÕŠ€"Ð2^Y…Löû¹|’üæ–¦x;ü=üðÃSï¸ãŽ)ÖR?¶öIþà„?ŽùÃ@«†cþ¶b‰Š3šáßwÔþNØ'@Œ€-]ºti”á€þòé€6þÀÏer ;ä&²cqêôCBñÔGÀë!ôy×£Æé6"-5=vìXý<0å®»îš&ï@ìð‡¥~-‘¿=écþJþ!Ü5B1F6ùÛn¥}ˆ±mpiiéI™XæWOgÖ®ÜxÃß# jj³g-½U+Š€"pîè[Œ{Ã/Œ#ŠÓ!øªß/ùË)wß}÷,IŸäÏ–>[þ4ØíïóWò鿍1’±‰ßv3(\ÃfA;Ç©—%‚Õeee¥ šÆ7ú_g¼Š*™ _ÔtaH«(Š€" ´mo¯¾ÛxÜaŒ¼+Ò!»wïÞ+ŸôzÏ=÷Ì•ô±½/÷öÑÇ#ÎøÇ ‹­¼3yˆS%UÔH¹Äã‘ü©ÓvÃÀy#>%,«êd³ ÊŠŠŠÎºTŽ2ÞÀ+ŒSûšqŽÃWQbFÀë†õý¯Ï•iƒaË–-Û~øÃNýÙÏ~†}ËAþlåÇ"~¶üí Jþi¸;j¤ÔI’ð©c‰ ¯¿þú~±”:´s=*c ì×±{Ó@Ýfãì[89M@Pòwøõòß_SV“¶ ,[¶lí÷¾÷½é2ãÿ-É{û“üí–?Ü<ìÙþ±fü·ôM[= 1a5½«ìÖ•*ZhºípŒÛ°|ùòC6lØ?pàÀRÙ>¸§(4wI;é ¸Q†z4}LÈÅÿLEPж¥Ëÿ›MKüä].yíµ×–~ë[ßšöÜsÏ­”<@þ˜ÐG⧦AÀÙþlùÇ"ÿtµ(ÓU üÛN"÷§LÒ§æuÿ9üÄ8ºtéÒݲupÛ!C†ôaàÐ5†_kœ¯ë*ÐÁÕÜC³üÝÛ2^Íåi-ÜäÉ“|ó›ßœ&C›$#›üýÄs¿¶¿¿Ûåõ¾„¿J ¨h DIÄàƒì×L¾qÇŽǰup÷îݬ “ã¥Ë8©é]eHàvùkC`¹¤Á"¥–œÆRD@6óq/øˆìê÷Scd0]â‰Èî~³dkßikÖ¬Ù.ù`²Hž[üÐìàd?Ìøñ+ù é5Ò‡p<²¶ÙÕvÛ%aÜFÙ!ëä³Ï>»©¼¼üäÈ‘#±L0=ýu‘™4ɸ}.0ÎŽ…Æ9í¸UE ð*ªecŸŸoä‡e–ú^û²Ì館ñŸú…/|aª¼»°ñ^$$y›øi àš’–²ô= YªPŽeK"÷ Äï'ÛϾ†5¯®l\{êÔ©ºáÇw“åþC;—ƒ¼‘ï[}‡qö® -YMHP²€€tº£n6î;eLÅ ´@fú×þßÿýß´ïÿûXæ‡V?6ø‰Gþð'ùsÌ_[þJ&E €L¢}&/!àuª4×ßxã?# KOÇ!ñX¼xñ*Ìôä‘G‹gú'BþèòÇd?ÑÆŽhÿ{Q¼TÒ€é@5±4ù34 ßö·Ý×°bÅŠƒK–,Ù#j#KÓ·v¹I‹!Ú€/ îÅ<E@È}¤Õ?òFãÞü€12É7Ýòâ‹/.”ý¦Ëަ«%/¬ñg÷>Zþn¶üAü<8Þ€ï<¾ÅK%]¨.dO—*´D÷ H Èš¨"^¡¦ñæŸoćÒ>Ö’É\¤2Ño†|Î÷M9å¶¾lùû‰ß&vùÛ-û]g¿“AC§„€)ÁZ$<ð±V øÿö92çºaåÊ•ßxã]»v5ò~V)í!/›÷¯cGÙ¹DÌü¯UE £´“ÝüÞñã^y1ze$ë¿üå/s0ÞÿÊ+¯¬“ ýãývËŸcÿlùã%a·ü9Þ á;­éL3‚€9n& ÿƒÏshHÀöÇ9„~ òý€cO?ýô†¶mÛÖËRÁÊ´|Q°)Ϧ_ér4=Ï7#Þc|fxïÆ3¥±Ã©[PÂEKûF\oÞùkcú\.Mù/¦YöìÙ³÷þûïŸ~ÇwL•wÍÉËüØêñ“ü鯵XäÂçÁ÷µ\RÉ$jdíØyù{øg€ní@Š O“Ï ïØ¹sçÁšššŽr¤o©`s]œ¶eÑo ¸ý&ʇ…–ë°@3.ªt àõ,úüØxc?eðßË„,Z´hÕ~ðƒb,’üÐêçú~¶òÙíO #ÀOþöx?[ÿ(>ß_p«d52 xœìüF€?ÿ$± „µ¯Ÿ’oX°`A­ìèÊî}""þC?ïT#Ã0^y™°Ì8§ðPQ0ðÊ*Œ{ùƽâ{ÆÈf]™†††Æ'žxbŽLô›þòË/¯•<±¾Ÿä‹üy3ýí.Îöç; Uà{ n•,  @@“e,#Àÿgá¹_#IûÏÔ ]vÇžyæ™u²qPE—.]Ò·{ +„®ÈªqÆýAã9'LdÏ*éìÃÿ^EPRB m;Óˆýûoü¹1Õ3ÒÝrnÞ¼¹ö¾ûî›ñÕ¯~u†¼KÐåoÏòGþ¶`“¿ÝåÏ÷uJ°h¤pP Ó•ŠMôÈÃ>çf8üé°J`çºuëöTVV¶2th½®°±QwÑ"àõb¯þ/ã]úõŒMð#Ø<üûßÿþÕ¯ýë3æÌ™³AüýòÑ“ømm·üu¼Ÿ€æ™V ÷o˜ß %mk’¼­í^Ô’áäOü¥—^Ú*Ë÷÷ìÙ³]ÚwôcÜE>24êÃb UCÀž MÄÿŸÆ{Ç7‘ÿD¦;úÝ{ï½3~øÃΓwÂ>Éßžè‚gKŸšÆ€¿Õï42ìwœž~ïÀ­’c¨c7$ÁâÌ©m²‡_¬s$Í?'þ¨§dœo¿ôl)))©— ‚Ý:Š PƤËà3†ÀáM24€wŠ"PØxÕÃMãUw7ÿàŒWvÿþý~÷»ßÍþÆ7¾1ãÕW_]/ÀX?Hž­z»¥o»yÝ¿Ìïÿ;‡ï&¹¤’«ø[—¹ZN-W¼_ÐXÛ #n|G[9d~ô@÷¾}th>Çuø#,H¿Óûßÿþÿú¯ÿ:ñª«®'çÙ‘ MäíߚȆybªà}¢¢øXÏ Kåƒ=ÿlL¯‹²V)1ø—ÈD¿×ÿú׿®’B ÅâÇ6½lÕCƒôIöÔ$}{K_üIÙê§ ^Úêù Úwéì2Ò8Û÷ÌŸÎßÀ?&ýÉ¬ÔøŸ\±bÅùºàF×uÊ@gÙ7 “?ƒ´Ÿ—ËfBCn“ ƒ7J{¢Î86‰FñTÆÿÆþ1Åñ—ÊžHKÌðó7¿ù 6ôÁf> ’9?žœáo“?{IøÔM%Ÿ äS™µ¬g#À{mè `o{hàÍËàuê²T‰!pÁ‡>ô¡ äãBUggé3itlyÕD–ÿÉD6Î×áLïùÅF R"›]]bܱ•0'IØàÙÙëcÏŸÿügÿ››6m¦ ~:µ¿ÅpÃP ùc‡Mü$}j¹¬’o<ò­ÜZÞs @·{h°…O‚×€ë:ˆ \sÍ5?õ©O—a 2ºwÀ¹õŒúxu;MdÅÿ“ã9ãÑÕq`Rï4"à•WÊøþmrü£qʪӘSbI××ןîþ7yä‘·äã=%ˆãû$t›äc Gò'ñ£»ßßå¯Ä/ ä»¨ïwðìòó~úè€!@#€²· žÓH`x tüøÇ?>VŽó&Mš4Fγ/˜$¸åeYõWéX í4ZT4!PÒFZûwÄûéw˜ØøKe_fÏž½ì±Ç{[Ž¥RLä³»ûAìñÈŸ×84 âljÄo“¿xëD?€PBÂ(„ºhšà=¥Ho‰ß Mƒ¡¬sçÎåŸýìgÏ—aóÆŒ30g€Ç¤Á5b¬”^=h©(á àU 4îHií½Ý8+ÃI4„TdgÏÒÝÿö<°øðáÃøp»ûAä$÷Xäo_#ùsœÉ-}âTò…"$‹B©Öã ¼·Ð8üF{Ð3`= ¿¦ #¡T6ê!{Œ{ßûÞw^ÿþý{‰_îȾ•&²æoÆY;Ý8‡wçN¹´$yƒ€×Y¾a1T¾È7ì½ÆTŽÌ©r˲¾O?ýôÛ²¦Éúõëñ€c’ºõIüÐÓ÷k›üAúËîþXä/—•øB¡ I¢Ðê¥õiB€÷—F@,C€ÙÕOc ^O®3,æ”Nœ8±Ï?ýÓ?{÷»ß}^UUU×Ü_2;^o2Ö¿ªË sëæä\i°|Ï|Eé÷š(åƒÝœ;²gÏžÏ<óÌÛ²“ß’×_}›” Äq~¶âmr÷·üya¡µÕ/ « еþÅRoÞgì €æÁX†»7€hì&X*û øØÇ>6öÖ[oWQQ‘¹ï˜&z1_`§ì6¸~²q6ÌÒɃ‰âVàá¼²JÙ€ê*ã¾É˜jÙ¥/GÆõmØ:täùçŸ_ò‡?üa©¬çß$×@üÜÅ„N‚·‰ßv3‰ŸäÏî~ë·A/7‰¡ªZôU佦MCF@*†€mœ6n¹å–!ýèGGßpà ãd¾@iÎ"¿ûMÙvxšq6Î6ξM9[L-Xøx•Œ7p’lÏ{½1=.?ƒR”qýcS§N]òÇ?þqù /¼°N’Eü t’?»û!þXÝýœÝORM4™\D€¤‹eÓ2¥Þs4Øà7ØåÏ–¿Ý+@?Û@OH¿£ô ýÈG>C`lNRXçH­1›§gÓ+&²}‰t¨â=ªR0´mgÜÞç é_iLÿŒWÞ;§«ÖLüKÿô§?-—–ÿZ),Zû ŽÙ³5Oâ§¶ ЈÇ¿MüÚê`ŠUHÅZÿb­7ï;j? 9< ?žf8'`h ãÍ7ß<ôÃþð¨›nºitN øŸÙyÐàÃD²é³m¡¬(Ø S ´Aä‡)§ÏÇxUòÙé>·ßMàÉòÎ|‰à…®þÉ“'/â‰'VÈ·9Hüìê·ÉŸ„OÓ@ ñ“üAø0ð@ÛЧ9P("!Q•µª¼ÿ4 Ù#à ©ƒüAôñŒ^gxhôt¸þúëÁ¸ñÆGËdÁ.â—‚å…Ûæ§v‹e¸`‹,’Â{T%gˆDŒWÙÏx½Ï—ãb!þ˲º²¸È侃S¦L‰ÿ´iÓÄâŒNì³[ü$ÿx„>µŸøíV¿²7¨@Ó ´zZ­à3`kì ð °¥O²e 0 4ŒÑË.»¬Ÿ#Ä%Ë{&PÆÜ rR>L´}ž‰Ô.2ÎÎ¥ÆÙ»^^»˜ˆ­’1Úu0^÷ÁÆ«+]ûSs©˜¤Ë>¬Œd9ß.!þÒâ_5wî\±,£]ýhñ“ÀÙ’'¹û úÛá¤o?¬V¶òýZ.©|é[½µ¾ç"ÀgšG¢†@¬úÅ2°|°£l"TýÁ~p„L!îç)O|°º`ßr1Þ0ή%2d°V>Z$ïrý”q87Pfå{•}…ð‡¯ç8!ý ².tNÎÖO´Â²Ï&™Ô·êÉ'Ÿ\%î¤+’äm:[õ±ÈßǸñˆŸ-“Ü*EŠ_úEZ}­v øLЀ¦!Àa»G€]ýþÞô§!ÀÞhª««»Àï —Þ‘%%%È/¿¥QÞËû–‰1€c… ¬7Î1 Žc³6•¸t,7^Wéʯ”Ö}Õ(9dÇéJ9Jðøä·466ºÒÊ_)ûõ¯ñïܹó Ô¤o?HÜ&u’>üünø‘ô¡Iüv«Ÿ¤O§–à*ÅŽ_öÅŽƒÖÿlì炆Hn?Ü4¨Ið$þ–4®Ù†Œ„¨1ð|`ø{ÞóžaW]uÕðîÝ»çÏ<©@"âÛ#½+åX-Á&ãÚfÌ¡í²[¡|´ÍÅ;¼$ÒÆx«Œ©¨1^E!üÆë6\Ž‘Æ)ÿ“½{÷œ5kÖê¿ÿýïkþò—¿¬–ê‘ôAè6“øáOÂ¥ޤOmOðcw¿Mø¶»ÀPÖ꤂€ý¢O%¾Æ)lø|PÓ€¦€FIÆ[ÿ~Íë~Cñ1O ÃÅ_\#†ÀP™88lìØ±į°E† œ£ÛŒwp£,I£àèÑ;S·Ë˜#»eCi,žÀ6ïy íËŒW*¶[¹l¥[ÖS–ÜUÓ©—è>Æé2Ðxúäu÷}¢w`éÒ¥›dBß!þµ ,Ø.ñ@üöø>ÉŸ„NÏÀuÆ!é³ÕÂ'éCCHøÔM¾ú«4#À»¢´„ŸhûhÉ ¹CÓˆåé3, Ñ®]»–ß~ûíCe áPÖ­[·Nr­8¥¡Þ8Ç÷ïØnY¾WŒé5¨?hœ0dháäQ9êŒsR&7 ‡4Èq îã4`yx³œoƒ´Ê¬•§xmd»ùòi+ 8ÚˆI;ãµw;ù(d;¹í¥«¾½|‡.BöÒj/í&­÷jãuwܺâ”ýû÷•nþ5²”oíSO=µöÀóa‹dm8 „óXnÄaØ–ˆDÏCœ§ ¸Usà‹ýœ ê¡Ä@€Ï‹ß´WUIDATÀ9H›½ rö Ü¡yÄ2‡aáfð‹—\rIÌ|íµ×9ÿüó‹¿Š",^¼xýŒ3ÖÉøþúùóço—B‘ôAÜñˆ?áß„OÍ4 Ñ‡Ù³Õ¯Ä/`¨$‡_èÉÅÒÐÅŽŸ¿!ÀX† žF@kÚ6h `Â"ßõ®w ‘e„ƒ&Mš48/—ûTõǾٳg¯—e|ž}öÙuõõõœÉî›°Ùê'±'¢ÇNdo$}huÓ™þ*­ Ày+Áô²"pö³Óš!ÀÞ’z¢Æ€žFÒ‚ñ5„ü»É2ÂÒ+0èÒK/TYY™‹ÁÏV=r}ûöš7oÞiíoe|ÅØ/eEk¤ba“´IâÐÉ>ã1-›ôcµø%y%€ ’öK<¹˜ZhBÀ~†5lƒ€=-± 4ÚËdÁžÒ+0@V ”O”ùÅ;_@ŸÎÐqü£òéÝ2“£´ö7Éä>™™%|›ôAÚÉ¿mØ„Ït–hwQŠ…€ýòŽu]ýD°Ÿ¥D Ô r¿ëÜ6ÃèÀÑnüøñÕò¢þ2DÐÆ€L̽ÏKAUr™Ìw¤/]ü›åk|›ßzë­RRLÐéã9“ð©Iä6¹£åïœdOt”ø•Ì `¿´3“£æRèØÏ”ßÀ9çPÛ$Nr·xFÃØñáæ‰†Qc@zz\}õÕý.¿üò~b ô¯©©©,ô› õKíÛ·ïÒß5Æòµ«_@PI/öË:½9iêņ€ýlÙ†4¨Aö$t4ZÒ Ë¸4˜.Œè!äßEæ ô•%…}Åè+[÷+¶£õ=ƒ€lûEH«,ÝÛ*ãú[Å5•§wÜ#é³µo“6È›‡ÝʇŸÿœá í4˜.4{bŸ=©ÏvKpE 8öK:xjš‚">g±  m¶Mä$wj¶ü©mÀaìø~caNÒ3c F6ê3nܸ>²-qרUPßB@@¶ß=°dÉ’m²1Ï6!ýíÒÒß*õÑó I“œAØ6iÛdN¢‡ÝÔv8;>ÜL:VkŸdO-ÁTðà‹9ü”5EEà\ø¼Ñ@>¸y¸m2'Áûµm ø¯1øÛÝ4ÚöêÕ«B† zËj‚Þ2‡ ÷èÑ£ûtéÒEv¾QÉW5üU´!ÀrÚ2Єð¹³5êX†€Mæ4 ü„Ïsvº™4æ…¸0·Ý AƒºÊæCÕ^xaµÌ#è=räÈ^ò}‚ÎrM%G}÷¯\¹r‡Œß×.Z´h§lʳsÆ ¤¸ {64Hš$ r†›$ ëÔt·Dö Cm§7ó‚&éÇ"|%~H%sðœ¹5'Eà öó·}€”qNr¶ Û&q6ÎIü±Îc]³Ó° æ?Ä‹pKAg™7Ðs„ =1±pĈÕ¬–¯Úõ *™@@¾®çmܸqçªU«vbÂÞo¼±KÆówI ÿ°ä2&éÃM&!Ûš„M‡Žu œíÏsƧ¦AÁ<ý¤o“¿$yºå·Š"1ôÅ•1¨5£Và³hk¸ý†€mØ$N·ß€¿mØ×í84àG7ó¢Æ5<Úȼ*Ù–¸J† ºKAÕàÁƒ{ÈæDUmÚ´A•hhhpeÓ=ëׯß--ü=Ò­¿W¶ßÝ#ãùòA„()£…ÎDLò¥¦ŸMÒ$|øÑm¼ßÏÇtlͼ¨ýÄ/Ùœ&{mí •¬"À—mV ¡™+ö3 ·ÿ ÛÚ&m’:4ÉžnžÓ  ?ãð:Ò¦óÁ9Ý(Ý0˜Ü%Ò3P)=•bt>|x¥• ¨¬ªªÒ]  ÖdÏž=‡6mÚ´OßêÕ«÷ áï—þ>ié \»;n?áâáèO’¦?‰þt“øéGž3 j¦ÅJÊÊÊÚ6¬ÛСC+¤— « tà –%öìÙ³KçÎñ䢑Çßµk×A,»¢?(]ù¥u`íÚµ‡Ö¬Y³¿®®›í|IÎÐ Z¨­mò…ñ¨Iض&¹S3[Ûáéf>8§Ú.I_¼µµTr¼°T\GÀ~NáŽu€ŒáOR¶Éš„ŽktSûIßÎp¶Ž•‡?–…eÅu¦MMSVtc ‡ô”÷îÝ;zˆaP.½äz¹|ã L>‚„†œù(Î)Ù3¿Nfà‘ÖüQ!ú#µµµÑCZöG„ð£‡\ÇÇsH®Ð$d›èmr%éÒç6!ÛéÅr3^óŸ3-^•ó'Ùû5ïüUœE/'E Ÿ°ŸY’«_ûÉç [hÛm“z²n;¿ç(´íf9égŸÛùã:ËÕb´ïÑ£G©e%Bh1 :È÷:HïŽöåååí¥§¡]iii;1p´íرc›víÚÉ”„6Ð%‘H¤óN^Äd:ÆÙEOž<Ù(îÑ Ço¡Ëqòرc'¥e~òÈ‘#'¤£^öɯ²¯¢?.3ð£z÷îÝÇ„ÜíírA¢~bå¹MžÇsºIÀð§šñm7I;m§ãwãœù³|~-A¢E /À HEÈWøüÚš¤JM²…ŽuœE´Æ>‡Û>H̱üx-VðCyxÍ_6žÇÓõt\¦AÍt—yñqýnøAà±I‹n¯óœdˆsº¡cþ¸Lï™Óäy¬4áGò·µMú cûÙayÝÖpû–Ç_^œCüºÉW§[¼OûÇrÓ‚x¶øÏík±Ü$7^³Ïé¶uKn\ã’¥šç$_úñœº%uÍï‡tèÇ4ýšyÛå³Ý’„’>@P) ’})F­µ…Ž€ý\ÃÍsºm’¥ÛOÊ<‡¦@?û–Ã3L2ÚO¤<§FZtCÛn^³ý’u3X~¦Ùt¦¿Š€"0|a$A*Š@«Äú_Ù~tÕ(ˆ? ŽþñÎéOû‰5Þ¹íOwP21 »|±üìëêV$ð¿$’ˆªAE býçl¿ nÇŽo/ž¿ÆvÇ#[¿¿}Äͼí4è§ZPÒ€@²/…4A“TfZú?ú¯ùÏ b<^ªã´ßßnçÛÒ5;œºE ¤ûe‘Æ¢kÒŠ@Q#kÿ]%õ¢~µòŠ€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" ÿ6é*rÿ#;IEND®B`‚ic10뽉PNG  IHDR+ƒ$iCCPICC Profile8…UßoÛT>‰oR¤? XG‡ŠÅ¯US[¹­ÆI“¥íJ¥éØ*$ä:7‰©Û鶪O{7ü@ÙH§kk?ì<Ê»øÎí¾kktüqóÝ‹mÇ6°nÆ¶ÂøØ¯±-ümR;`zŠ–¡Êðv x#=\Ó% ëoàYÐÚRÚ±£¥êùÐ#&Á?È>ÌÒ¹áЪþ¢þ©n¨_¨Ôß;j„;¦$}*}+ý(}'}/ýLŠtYº"ý$]•¾‘.9»ï½Ÿ%Ø{¯_aÝŠ]hÕkŸ5'SNÊ{äå”ü¼ü²<°¹_“§ä½ðì öÍ ý½t ³jMµ{-ñ4%ׯTÅ„«tYÛŸ“¦R6ÈÆØô#§v\œå–Šx:žŠ'H‰ï‹OÄÇâ3·ž¼ø^ø&°¦õþ“0::àm,L%È3â:qVEô t›ÐÍ]~ߢI«vÖ6ÊWÙ¯ª¯) |ʸ2]ÕG‡Í4Ïå(6w¸½Â‹£$¾ƒ"ŽèAÞû¾EvÝ mî[D‡ÿÂ;ëVh[¨}íõ¿Ú†ðN|æ3¢‹õº½âç£Hä‘S:°ßûéKâÝt·Ñx€÷UÏ'D;7ÿ®7;_"ÿÑeó?Yqxl+@IDATx콜Uºþª'ç 3À 9:DA‚(É5+0 îºâ–ߺÞUï†ë媻è^¯ü]ïuw¯xq »&Œ« ¨ (  ’s2 i†&Õÿy›9X6ºgzº«»žó¡¨SÝÞó­šêó¾ç=ï« €­¶’†Â 4DÀ®¿ÛfCBó;   {°kGÂt( ø@]¿¹òYWíb­ëÏdϺþLÖõ-øÊýuíY—m«ò®ëÖµÔëZjj?·®=ë²-KuíZ×õùññ¹R×gç¾d…H€H€H ù¤ÓÀB$@$@$à;ÏßPÙ^–HK]¦×¢ÌKÝÕ¾}û„~ýú%aÔ®]»„ŒŒŒÄøøø„¤¤¤„ÄÄÄ„ØØØø¨¨¨¸èèhYâ###c#""b±Žq¹\RÆ:Z¯ Ȫ]"±–%B}=ìë6à3·ì& ¾3kjjdíVÎñQuíR…µ,•²`ŸŠêêê ˺¼ªªê >“uyEEÅi,e•••eååå§O:UZRRRzúôéÒ£GžÚ»woiaaaÉwß}W‚u©¾že-FÏ¥Êò™§Às»² 4DÀ³óÒоüŽH€H€œBÀó÷Q”hQêëZÜߥ¥¥Å5*ý‚ .HëСC:¶ÓÒÓÓS¡È§A‘O…bŸ%^–dYp.©'‰òî¨ÒN1" ” ZŒõÉÚ¥†‚bNÀppüرc'Ž£ìÚµëØúõëúé§Ç°Y†c´A@Öu-b@° ¬4X' p<ÏŽã €#xþþ‰b…ź>W¿ôÒK³†ÞªK—.Y­[·ÎÊÌÌÌJHHÈ„rŸ %> ¾{ÑúGÐ p#áU Æ‚£0‘5ŒGJKK :t¨hÛ¶mEK—.=üÙgŸA41 TÖ®­uý™Uz¬4X' {ž °o0H$@$àž¿q¢àËh»¬­Ê~Ô 7ÜÐvèСÙ;vÌnÓ¦MvJJJk¸á·Ž‹‹k å¾ûÖN©µ§D< `(8#Áá²²²C˜~p¨¸¸øÐþýûîܹóà²e˾õÖ[ûÐ.1hc€®WÔ~fm6V¬“ „ÏÎQX4Š  p Ïß1™_/J¾VôÝkŒÒ'Üyç¢ä·ÍËËk‹¹ömà¡ßÊ}Œäç@Áo_\ùY” Õ0ì‡çÀ öcJÁ~Ä&Ø¿{÷î}0ì›={ö>xHl1 hƒ€¬e‘øÖB〕ë$@$@!CÀ³ã2‚SP  Gðü½²*úçþfÝxãí{ôè‘‹Àz¹ÉÏ…‚/K;(ûmEŒõ‰Œû`Ø‹e<ö PážM›6íyóÍ7 W®\)S ´a@hð‰0w& °Ï•d¢ $@$@Î&àùÛ$îú1X´¢Èù­Æß¾W¯^rssÛc4?.ûypÙÏÃhº³ñ±õþ$¯€c˜R°S vÃk`÷ž={ 7lذëµ×^+DFƒÃ¸–Õ pÛb(°z Xi°N$@$Tž¬  Ë“ 8Ž€çï(úVe?æ®»îêü£ý¨#Fô;µjÕª#ýŽˆ¨ß#úYŽ£ÅÛ†<й` ;>¼;>ú裳fÍÚ!Å  R—ÅZh°Ò`H€H `<;^»0/D$@$à8ž¿92¢¯~·Òÿ«_ýª×àÁƒ;#^gÌÓïe¿3”ýŽ˜ž/ß³€­ ÌÀvÂ(°ñv áö+Vlÿãÿ¸‚‹A@´ÀÚ¬4X' hž±¹OJ$@$à8ž¿/’RϪìÇL:µ'RëuíÔ©S¤Õë’œœÜsõ»8ŽöW`ÛÉ“'·!má¶;vlCÊ­Ï=÷ÜF4Üjº¤-´¬4X' h6ÏZ³OÈ 8’€çï‰(û±XÜJÿå—_Þî–[néÑ¥mÛ¶]1²ßÊ~7Œì‹a€…EžU0 l§Àæ}ûömÝŒòꫯnúðÃ÷„6 ”×Ö­lh°Ò`H€HÀgž6ŸOÀH€H€GÀó·C¶EÙ×KÌ#<’ñÅw‡+ôôôî¢ðsξãž6ØS@ ÇŽÛŒ©›¾øâ‹ÍO=õÔ:œB b Ћ§ÀsÛ‡«rW  §ðìÄ9­ýl/ @ã<+$ŸVöc1¢ŸùË_þ²ç€z¶k×®gjjjŒî÷äè~ã`¹ ÔG ÖK`ã‰'6íÝ»wã7ß|³ñ¿þë¿6ÂcàŽÑÆY×xœƒ Ü$ øž€g§îûoX# p*ÏßÙ…?NֈƟõàƒöºð /hÓ¦ÍHÁ× W§Âb»I P0m`+RnØ¿ÿúU«V­öÙg7 û@®/†€²Úµ§Às;Pâò:$@$@6$àÙɳ¡ˆ‰H€H <dî¾[ᇂŸñÛßþ6àÀù¹¹¹`„?ŸÁúpGx h„€„‡Àº={ö¬_¹råº'žxb Gq˜6Èôk¡1ÀJƒu p ÏŸ°É$@$àHžïÿ(P87Êÿè£ö5jTŸŽ;æÃÐú{:’M!D™6°fçÎë>ýôÓ5Ó§O_ ñµ1@Ö•Í¡AÀ7I€H Ü xvý½l 8•€çû^¶e„ß=Ê?~üøÎãÆëÛ³gÏÞHÉ×'%%¥Odd¤XH€B@UUUyqqñ¤\³qãÆµ¯¿þúê×^{m;š¢ 2eÀÓโ-§È$@$@ ðì6´/¿# -žïxåw+ýÑÑÑéO?ýt¿Áƒ÷E྾pëï‹Ï²C«y”–HÀ[1]`5 ®^±bÅê‡~ø;|v Ç‹!@zx “û‘ @ðì†pS(: XßëR×sùãn¸á†.'Nì‡QþþYYYýe”ŸÄH€œI@¼ŠŠŠ¾…wÀ·sæÌùî­·ÞÚÚ ±¬ÞÖº3±Õ$@$&¬Å0i›A$@Ž"àù—íx,î‘þÇ{læò@äþþéééýcccÛ:ŠK$Ð(òòò}ÇŽû¾Eì€o¦M›ö ÒÆ€Ó¨{<·½w  °ÏŽ£=¤¢$@$@ ð|wG`g·Ò€}Yüu!"öhݺõlÀ\~ùŽ…H€%€Ø§Hð›C‡}ƒÌß è*lKªA1ˆ1 Úã$4xá& Ø™€g'ÒβR6 p2Ï÷u$`¸•þüüüvè¤ìÓ§ÏÀììì áÚßÏÉ Øv ÿÀTï<¸jÍš5+a\\¹nݺ½8»6Ty\‰Æ Ü$ »ðìPÚM>ÊC$@N&àùŽÖJ<Üú;Þÿý/¸à‚éÈ4}N~LØv I3Ï€•ëׯ_ùç?ÿy%¦ ìÄ•Å+@sx hÏÎe³NƃI€H€šMÀó½ü¥òäɃ0âQ«V­%$$tmöÕx hÒÒÒ­‡þ_ý÷ÿ÷×44"! ðìhA^’H€OÀó]¬çôÇ1¢”þÁpï¥ÿ"*ýŽV€lG Öð¦ | cÀŠ%K–ì‚Ú3€1lwÇ( €“ xv:Ì‚m' @ð|ÿʶÌéOÀî¿þë¿^Ô¯_¿Á999ƒ¡ôw¤`¼ 4•Œ›8°â»ï¾[ñ‡?üá+xìÁ¹J±ˆAÀ3F€çvS/ËãH€H€¼$àÙõò0îF$@$Оï\ÙŽÅ’€%~æÌ™£/¼ðÂ!mÚ´Š@~½›p~B$@¶!€‚k÷ïß¿lÕªUË'Mšô #€ʱx*ÿžÛØ……H€HÀß<;£þ>?ÏG$@$ ”õ]+õ(,n¥ÿé§Ÿ 7ÿ¡¹¹¹C322† „#£G.ß³gÏ2LXöðÃ/Cµ1 u«òo­‡# ¶‰H€‚JÀÚ) ª ¼8 „ëûUê.,n¥#aù·ß~ûÐîÝ»KOO™fmgsH€H NUUU%ÇŽûróæÍ_þýï_ϧuØQjP·¬õ:ÏÇI€H€|#`í úv$÷& ð$àùN•í8, ½{÷ÎýÝï~7 Áü†egg‹‹‹Ëó<˜Û$@$à$eee»<ø%‚~ùøã¹víZ/  <•Ïm'¡b[I€HÀo<;«~;1OD$@"`}—J]R÷ÉhÂ3Ï<3.þÃÅXjjê1aSI€HÀk'NœøS¾Ä/zè¡¥8PbÈR…Ūü[ëøŠ…H€HÀÖN«/Çq_ p:ëûS×ÝQüoºé¦î÷ßÿðnݺ]’••5.þ‰N‡Åö“ €70EàTQQÑÒ-[¶|þç?ÿyéüùó7ã8E@Na5XëÞœžû €ã èN«ãA xIÀúÞ”ºè—ð—¿üeôСC‡#Šÿ%IIILÝç%Pî†iÏ•QycEJUAý˜RÕ'°]¬ÌjL6+°uM¥r™gð⦙5e4ëRW8OMmÊuS¦RËR[ÜÛéJxœ U¡ êzÛeÎ-ê{Ôˆ(UcÄà+lGÀþeDã3¬#S°ªÌ¨tü…db; õl¥¢±¸ÃaèkpMõ())ÙŒ,Ÿ/[¶lé}÷Ý÷ öÔ^ X?6~C$@ °vdÜ‘_’ €ƒ Xß•ºîí¿õÖ[{"¨ß¥={ö¼Qü/‰ˆˆ€6ÄâhÕ%Ê(ߥ~‡2 Ø«3 §u+óú³Š<² SâEioL9¢bd 0(²`Â``ŠÁ‹•¡TL¶2£s`,è¤ÌØÎøž12Ãåî7µÕÕÕgEàó7~Ž Ÿ½òÊ+q.z4(#p4Ý‘u46žH€ê!`}GJ]†AÅ?á¹çž‰ri»víF$$$t«çx~n*ö(£lümPì÷(ó Fî+D¹?‰qËd¤^FäYüGÀm0ˆ†ñ4#“aÈPŒ*&‚.ÊŒëcA®ÿ®Ç3Ùš@iié–½{÷.Y¼xñgS§N] aÅp ‹§%Í)V54…H€¼'`íÜz÷$ ð%àù^”mÕO>|x§Gyd"úÀÜþ˜Û/þX‰À™Beœ^¥ŒÒMPî •ëÌaŒÞ‹+>tŒš3h©Å­>œÚòmÁôþLñ'iD¥¨šèVʈm¯Ì„ÊŒï¿àN!ßB6à‡+ ±– sÀ’§žzjÉÒ¥Kw`1Ȫ§òï¹ýÓq‹H€DÀ³£ë ¦³©$@$ðÖ÷¡®‹‚Ÿøè£7nÜHDò‰HþÐ&XB—@5|Ä;½#ùPòËwcÿÜõ¡ä»çÚsô>tïm’‹A„x .Al­q ®;|yúÁƒ ç–P%€ ß"ƒÀâ×_}ñôéÓ¿F;Ä žR¬Ê¿µ~ö[þO$@# ;¹k6›K$@çX߃R×nþ‰³gϾbРA£rrrFÆÆÆ¶9w+ö'€ xÆéµÊ<µ£ù” оY{2’O}ûß¿@J(ÆñˆÎR5±yð襌ÄÁðè}6VA eᵚE ¼¼|ÿýõןÞyç q21pz@³¨ò` p#`íø†[ÛØ ¨€õݧë˜d¬’.½ôÒ.¿ùÍoFöêÕk‚úDP?‰òÏb[Ñ/[¯ÌŸCá_¹ù{0š/sòeðîú¶½m!!¦È,Ä0co þe¤^ ==ì| 4°AoذáÓ'Ÿ|rñgŸ}† ª ‚t¸‹ÕÀZ¯ýš+ _ºã¾-dËH€Hà{Öwž®Ã/X% ¸ãŽ;FwêÔi4Üü|k¶!`–+£#ú'—*³t#”ý½H™×}ŽèÛæ9Bñˆ’©픑ÐS™ÉÕ™4ÞÈhÀb;˜ðÍŽ;>™;wî'Ï?ÿü7P<±Ó]¬Ê¿µ^û5W$@$~t8üZÆ‘ À÷¬ï:]—hþ‰3fÌ9zôèQyyy£ãââ)ì{fÁ­I*½âO•qêK(û[•TzªRúíì£÷ÆðêuÀk%*I™ÈN`$tUfâ0e¦Œ†£€¼fXì@ ¬¬lÇîÝ»?Aùô¿øÅbȤ§ˆxÖ‹µ.ß± @XÐá°jC$@µ¬ï8©Ã§×Æ/iΜ9× ÊL½ Ó.Ä[ˆÓ‚yW+**Žœ7oÞ:\E ÌÐ2¸yV Ðå ]ž—% &°¾¿t=gK‚Ò?àÇ?þñÑÿG)))HæÍÒ’Œ2(üGÞRêä׈­ùû˜Óï¸âVè1ÓÄ…E×Ý£ópB‘µ+ J¼(÷²Meîχ ð̘b ¨Á³ã6 Ô®Mxc»?—umý;`Cž™¸¶J‰‡@æ ðƒKK(..^‹Ìýíoc€dC€¶dÒ# %áóÜ$@-N@wš[üB¼ ø‰€õ½¥ë’+é‘G¹hüøñ—‹âŸÐÝO×ãi< TìWêø›åÿ £ýÛ¡´é~±çŽa²­z·r/ <(ôg•z8›È6Ght³µ±ƒ²b,p ÄX u‡ à!`&t†wÀ¥J¥ÝÈ-øä•––nCÀk¯½öáSO=õ.%†€òÚKÒЂìyj –# ;Ï-wž™H€üCÀú¾Òu·âÿ»ßýnÈ 7ÜpEçί`*?ÿÀþÁY$%߉…Pú¸ïÔ&ÌŒ-þÁס¿ÇI”ø,z—(õѸ‡C •û¼½µF‚j¦L1`‘uu­¡ ܦqG%#í`O®@¦+ð'‡à=³·È’Bpûöí ßzë­…?þørHKC€½o¥#h€€îD7° ¿"  °¾§tÝ­øO›6mØu×]wFüEñïT)Ãìân·þ¢×­}Ý3‡Ð:ë`Wˆ6Ö­ä‹‚/н§’¯­mÅö’žc™n n Õb$€ ä žã˜VJ¥UfÖxNðóý„!`<¾ûî» {ì±/qzü̘§#hyìñ´\– (ütß·ÿm£„B@¦À €)5nÃ@Ö¡[ 2S)•u»2“.B;à]Ãâ3’’’ÍøþóÏ?ÿþìÙ³¿Ã Ä#@—°*ÿÖºÏ×á$@$к³ÝœsðX h ëûG×¥×™¨($v-n7~Qöe‰W†(þT>ìz·(WSàïѬ>}öïÐm°ùôü-šòÚmu+Œ#a‹lJ«}LqqñêM›6½ÿÌ3Ï|ðöÛo#¨Š:‰Eϱ²*ÿÖº£™±ñ$@# ;Ý»"¯D$àtÖ÷Ž®Ë:yàÀ]ž~úé«EñÏÈÈa(o ÔÈHÿ"(ýÿPÆÉ5P6´÷©·'Ð~Œ/"¾VÙÇZFûYHÀiÌ3Êï€ÜÆ´cAJL3¹Œ·ÁpþnéàËm:zôèWbxøá‡ß_¹rå6+†­ô뵜ÒZ—m h1ºóÝbà‰I€HÀB@¿s¬ëD|ŸôÎ;ïÜ6`À€k³²²FXögµA5Pú¿„Ò?üVB™°›Û,nüˆDîÝH€ÂO¢Á[Ê/IÍêÒ³*ñ€—€ÝtBïÌÔ0L„1`äs9ó^5¡ÕEEEK¾ùæ›÷®¿þúàp™ s±´Òï¹nÂx xO@w½?‚{’ €ï¬ï©Ë"¾ÞÉš4vذaWçää\c ø~jça”­ÿðl(ý_Ø,]÷Ü}Ë?•ç= l± –€Û Æ,â-€ø¶)‘ 0\|ÖÐß6bÙYåÀÿüòË/ßGPÛ·!«xÈ€6 úƒºl³ €_ °³íWœ< €ë;F겈ÏwòŒ3Æ\yå•×åææ^‰T, (ߢ\EˆÞô„”:Ñð¾û·Ó=‘}ÜBsøÏÞ†À ‘€CH*B1`à¸J<lä!•¢TÆU“u‡R±Ýr?šÞ̪ªªS{öìyoÁ‚ïþâ¿øgC€ÌÙ¢! éXy$ €¬sã®$@$Ð ë»E×%²2‚û]„ÑëÙÿÚØØØ¶ žÅé_V…ÂÿŠrzS©3íAá ?ÜùØmèÒoûB)œEÀ=eÆ™6`§1Ùª¦õ0Ü £`†³î‰­-//߇ŒïÁ î] ü ‡‹!€|äÈÝI€|' ;æ¾É#H€Hà|ÖwŠ®Ë:ùª«®êõë_ÿúzø»699¹×ù‡ò7¤ 3Š*uóúOm˜$>¢à‹ƒ† ?Ü~´/H÷—%†˜˜2 žXÄKÀï 3™[³/ åJ¼7ÄþËR“'On@ À÷~ÿûß¿óÁlÀ> X(~F$à7ºƒî·òD$@Ž% ß'Ö54F•üî»ïNèß¿ÿuð7ܱtkxùFå:øFü— /ÓBƒXÜnýI·þ ÊÂK“ øLàûéˆ7çž.àó)üw€¤øÌ¡j²ïÆžþ;o˜ —~ûí·ï^wÝuóÐ41Àšs.€Ž ×aÖz6‡H tG=×äµH€‹€õ="uYëM%¿øâ‹W5êú¶mÛ^ÏuÜôjtξ ÿW•*ß_ÇúHFù%5_DFùÅ­Ÿ£u"ÏË@Ë€W‘)^ò¾‘éÁôˆmƒ)ãÏNÀû†å‡$Pà¾}ûÞùôÓOß¹çž{ÞÇ·bô.ŒðCTÜ"hkǽ§á¡$@$`}hÅ_r¼%?úè£Ã&L˜p}ûöí¯Ç<ÿ,²i°ÉFÙj¥¼¨Œc_ [§§|6xˆÿ¿tÏ凲yün¥ßm·ñÿexF ;@0A™* Æ÷T‰=„#£™~±R9÷(3®o°÷% ¨°°ðyóæ½3}úô/!­d> ö¾u”ŽB‚€µSH  °¾7t]ÖIÇïŽyŒc{öì9–óü=¼{ nþðî Öh?òx«Èd÷bˆ›? €£ ˜2=  º¥,52Є"^Ù·+•~ËYO¤ ˆ`×KJ|€7¾ø9o/]ºt3ä„åæ¼i">§ ¯èλW;s' ÇÐï ëZ4É”W^ye c333G;ž’€Q¶ýfb´ :ØAm“ù·‘2Ÿ?iú¢-’±J$@ß0åýTUŒ:f0âàýd¦@àÀIð ¸à{ÁXSGŽù€·o½õÖ×7IYó@jå_¯IŒH€$ ;ñ îÄ/I€OÀú®º,âîŸòä“Oޏùæ›oÈÍͽ!2RÂij(ó þ·•qp–R§÷nM¤žÏÑ~Îç0^Ž€€;n¼ÜSà½èæø\e¶þ±23RÐ2,UUU¥{öìyë7Þxë7¿ùÍC§ðÑ ð™€tâYH€H >Öw„®Ë: Áýz‰»÷îÝoHHHèVß õyå!ô›©TÑ;EÃ<Û@”þ(Œò‹‹¿È+óZ$@áLÀ¬BÜ*¡oÖˆ1 €ElÊY×#pà$¼ßZðÂö½Tiié–Í›7¿%Ó,p$å´ûÞ.JF¶$ ;ô¶ŽB‘ •€~?X×âîŸ wÿñ_|ñHë72¨ÚäâFé·póÿ³2ޝÀ@™ Ȩ¸Óõ%c?•#ýBÎË€£ ˆg@å‰Ú˜â… ‚L%fÚ`L¸_™ ýtQ{_iñÅobZÀkN °÷£t$`ºco‰( @° Xß R—Å…%åw¿ûÝÅèlÜܱcÇáîò.3N`¤ÿKÊ8]8çù¥rNà¨óJ$@ÎÆ ÐÆ€Œo¯Ì6w+3õzÇ{;aZÀ©;w¾ £ü?þ8Òʸ§Ô`-ñ¬1¬u;ÉM §°vôÖv¶—Hà‡¬ï]—uÒùuzùå—oÊÏÏ¿)))ÉÙÑ™ªÐá=<®þˆÅ$i´QÄ¥AüFú½?Ày  _¸³ ¸=0MÆÑ€Ø kZSª¦D ÊÁ¥¤¤dýºuëæÿä'?™ô;€Bæ i¥_¯…µ.Û,$@$ ;ùl:›L$`!`}H]–(,)3gμv̘17åää\mÙßyÕŠÝHá÷”ÿ…èBU ýpº' tl¬ ë- Àåy  ð•€ib £b(uHe0º…‹:muR > Tt^ _ÌÞ§?pàÀûüñüI“&½I%H üX‰ÒoUü­u|ÅB$à4ìQ:펳½$ðCÖw€Ôõv2\ýû>òÈ#7wîÜy\lllösΖQ¶nþBTÿåht:³’¶ÏÌ#Z˜÷ÊB$@!IñPL1¸ƒ–  .¤¢T›)H#˜€ëÙóååå·oßþúSO=õ¦¬†”@ g9ðp<ÝÙw< ÐÿÖµä[JAš¡[|3‚ü w w““K ø¿ Œ’õ-àœ‹ú™òªåó $@$`"5ªª<¯€ÀL0e¦Z LÈfÚêZ¸tÅŠo Mï+L¼$Pƒý÷\ÛJv C$вtÇ¿e¯Â³“ ؉€õï^êzI~衇†Þu×]ã:uêt3‚ü%ÙIè€ÈRS­Œâ·•±÷Oyo _Ø%ÅU$”þAm½--|ižžH€‚B@¦ k]•¬ÓÔ[H˜ØvÊl÷3e¦ŒE([çyT!H`ÉŽ;Þ˜5kÖëÏ<óÌ2Poí  ßZ—m 0&Àgß\6ê  ÿæ­kIí—òÏþó'—šš: ŽãÂû#ŒNG_SÆ>(þÇZ¶­2_UÒöEH@? ³ÀB$@Î#`Ö`zzµLÀÒÒqU¢Ó•ÙöefÜ[«ó¼¬Nœ8ñÍÊ•+_¿æšk^Æ“&Þ’ÃQ+ýžkç=Œl1 8Œ€VÖl6—GÀú·.u½¤<ñÄ#Ç¡äå勈ˆ@¸y•jÌK=:O¹öÿßÙyª-Ùtw@?=Úß’â¹I€H ´Ì+ñUjÚüT©Œ 0Â"ÞŠƒJuuuÕîÝ»_—òÛßþv1š.†Qþõ‚ª»hƒ€ÞæšH ÌX•‚0k›C$Ö¿q]—µô|R-Z4©o߾㓓“1Iÿ#³ øÿ­6Ru =+2·_FûÅÍ_FþYH€H€ê%`Š'€Lp{´`:AI!ØæÇJeÞå8CÀÉ“'×­^½úµË.»l&n„$B£VúõûLê,$@aD@+aÔ$6…H –€õï[êzI>}úHº£þãEKÒSùÿÙ-«ø»â¡ø§+#2ÙQxÙX ð³ ÓÕ+1%«æ´¿NyþyÄ}ÒÞCÒ­:¨Àà5ü}õÑG]ŒfcÆ9Oô°©Î$`UœI€­&ð#`ý»ÖuYÇFGG·_°`ÁøÞ½{ß‚Qÿ^á×ôzZ$#þEU®ó ø·TgÒ…‘~ó‹Ì@P? «ÀB$@$Ð\f5¦«WÅ‚à-•Š52^Õä`Z@ÖÏ`€×!ÞÖ®]ûê•W^ùZEEE!š]Wl¡a5 8„›IáK@+áÛB¶ŒœEÀú7-u½¤üÇüLjÛn»íÖöíÛ# ’CŠÛÕÿeŒø¿Ür#þn7ÿ4táæïrV‡}¦ÄÅÅeN¤`]©ÚÎϵu*ÖŸÀ[Tú/þ,À+óú£Û(#: #þâê¯Ñûó:< @Ý ÷»×ˆÏ+™·_ƒuïÚÔOñÛaœX¦Œ#¯ãco|OœI~VÃ·ÄÆÆ¶ÎÍÍ1qâÄìøøøÓ_~ùeZë V÷1Â[F Àž«n2›Öôß°u§¼ù曇 rkzzúÀ°&PÛ8ãÄ{ÊØóf0hæ¢ã‡!…ùý†àe! ° wö€Ê#µ_0ø»Äæ(3wª2S¯õ÷™my¾cÇŽ­\¾|ù+7Þxã(ntbУÿžk[¶B‘ ÔO€õ³á7$`gV+¼®ËðD"¬÷Í™3gÊ Aƒ&'$$t´s#ü!›Qò…2¶OQÆAŒÔT!Ê¿?‹W$”~ÓýS üó•éO¼< øƒ€¼› Š´«~eØ9}ÕWÀo‹qìc¨Â •›‡ß,a\à1ئcÇŽC7(«¤¤¤xÍš5ˆÂ¨</è¾G“`ÓH < È/ @hзֵh¦©sçνqĈ·gee­&5AÚò-ñŸ7ͯ›pp#‡QPü‘ÆO\LÃÜí³üšH€B@2%X ¤4+ý.¿™:"·N7¿ŸÛn',**Z‚ò÷;î¸ãMÈ&±ª±xzèm»‰OyH€ê  ˆ:¾âG$@6#`ý{•º^âòóó»¿øâ‹·õìÙó6Ìãkk3¹ý+NeÒù=£Ô¡p^?»zº31*£ý˜çϹýþ½o< œ€ˆé~ §»¬+,ð_ð»‘ð–ò‚åååû6nÜø{î¹çëÖ­ÛŒkKôEQúõ¢Å¡!@“àšlLÀªPØXLŠFŽ' ÿV­k©§LŸ>}Ìøñã'´k×nlXS’”~‡^€ò?Ïÿ9wDÌïw+þaM‘# G8›9žì5~ÎÃqM²´~ ìSîÝ»÷í×^{mÞ£>Šù?H(Ï”VþõÚ‘ÏM¡@@+¡ +e$§Ð§²Öu‰D—ºpá» p{rrrïð…ƒÈþGþ¡Œ½/ø?¥Ÿ[ñ—ÿ¤ðÅÇ–‘ œ#`V•à·D<ül@ X³ÝýÊ̼× ßx1'Ož\ûÍ7ßüýŠ+®˜…†Ê”)Àê @#À°€] „ïÊ®Ä) xOÀªð뺬ÝþfÏžý‹~ýú XOغü'+×¶ÉÊ(zß¿£þ®xqÊA*¿ÖH'·  GwþÙ‚HïWƒøþŠàNˆ ´ÇÞS*®~c:„%Ϙ˜˜Öð8¼øÖ[oÍ:uêÔñÚžtŸ%,°Q$êä”…HÀ~ôߦu-QþSgΜyý•W^9!33s´ýÄö“Dgv!Àß“Ê8¾ÜO'¬=+A©hŒøG`ÍB$@$àxfu)ưÅ#k?3mþ&l ‚êÈ‘#Ÿ,X°`Þ¤I“ÞÁ¦xH`=úï¹ÆW,$@v  • ;ÈBH€¾wñò÷©¦NýüóÏèÝ»÷Œúw”®TŸV®ƒÏ)uàt!<35£µnÅ? Š?FþYH€H€HÀƒ€‰ßUQä_C€©TÎ-ª&{ f$z\1<6ËÊÊv®]»vÞ%—\‚yzn#€ÎÁh Õðh8[A!L€SBøæQô°#`5ÈiÅ_Ö‰S§N½äå—_~Ñþ'GE¹sÓ…Yãk0Ú?_¹¶ û iýüÝ_æøG·QFL+¸ú#µ ÔA@~#Œ¨Td~Åií~1Bã·¬d-âØ¼LÈ.ßW¶þÔ×!Hˆ}$}’¶mÛ^:qâÄl—ËurÅŠ‡ÐÏ)ÒªðjxˆÝ'ŠKVüc´Ò`‚G@ÿ-Z×âòŸ6gΜ›FŽ91++ëâà‰×rW6ÊV+Uø„2J6ùï"ît~ñgTÿ1å™H€HÀAÎf ÐöO1»+•÷;e&ôõÏ mv–¢¢¢//^<Æ€ùí8N °Ù=¢8$ ´²A$@Á!`ý”º^b¢££Û/Z´hbŸ>}&Âå?78âµàU«Ž*×Þ§”*Zˆ‹øiÄß@r„häcv%cÄߊ¶ÛÁS“ „%S~šjŠÏÆ0ýeÀoSÖ•ª¦íÃð È ;n˜°ç\vÙes*** Ñ@N »»Ì…:öCýRþP&`ýû“º^ï½÷Þ‹|ðÁ;;uê41”X·ìp÷?òwùû“RU~ ºdÀ½_:Rpߤ]³nìü”H€H ‰0}½1î$} ¿²D& Hàd¤ ¼2‰Ã_x•;vÌyöÙggÿõ¯ý -;…EǰưÖà [C6&`U@l,&E#°# ÿö¬kw”ÿ—^ziìå—_..ÿ#Â­ÕÆé p÷L§üäîo ŒITÿt  ¿T¸Ý¶‡H€B›\ªáÙî6Tû¥)f"â´Ÿ¦Ìø^~9ŸN‚)K>üðÃ9wß}÷Û‹Yìts(‹£ håÃÑØx ëßœÔõ"êÒ>þøã{/¼ðÂ;áòß)€2µü¥$ºÿg”:ˆ@H¦?:MPö%b¤¸O2–iËß@^H€Hà{ø«‚7@¥žæþý7Mª‰1;ûfU“ó~ÒÂ+[ ¦ìXµjÕì1cÆül˜¤7@“Dþ!Àž³8ò,$à ú”ÿø›nºéÂW^yåÿõíÛ·sÿÃjR qb¢û? TñJ0òƒ·_d æù#$B"*sÔß›çŽû ø•ŒÐ®D¡ñ{¤` hv @ü6žZ¯Œ£o*›¥‹_¥ æÉj³ »õÖ[Ó:tdãÆG!O]y~­}¤`ŠÌk“@Ø  ìo1hú‡MøëuÊ3Ï“»•±ó—ÊØ7 ý£²æßW‚R1¢øcäß »óò $@$@Í" ¿EI0À ]#©ëÊ~çÃð[iûH©²UHÜçCèéÛdff¸øâ‹³sssOcZÀ>´ÊUÑÚG ý³$`súÎæbR<iúïL+ý²E?uþüùw >üÇ)))}Cº…Vák0Rô¿ˆðÿ¢FEpb#¦6²?:Y,$@$@$`W5%È€ÔþÈ€t¶5í&!cÀ½ð6Ÿ±âââÕK—.ý<çâ6J\tΛàwA»>$”‹‚O@+&Á—„@ø°þ}Y•ÿ˜„„„HñwW¯^½~‹¼uáQŒ²õJíü­2J·5¿AîÙ_ü± @ˆ¨>æ·@f¦t|B™q„Hã³¼¼¼hÆ /#Uà¬ÒÒÒ]8‚©ÇÆ=HÀoÂǤè7$< ø…€Vþ­Š¿Ôî¼óÎÁ³fÍ*ÈÏÏ¿?2y€Â¡˜åʵÿ?•±ã?”Q!ÓûšS€)éüÄÝ_ÜþYH€H€H ”¸âÎþŽù!>€QyLEo*Ã<®Ì¤AðŠ‹ %uÊ*}ŸœœœaðH.))9ºf͸M¸ƒêý­}(ý×$@~"@€Ÿ@ò4$`!àùÃ%Û2i=eÆŒWM™2er^^Þ–ýCºjœúJ¹¶ÀEñø—hG3½ö\ˆ~Ó£þ˜çÏ!ý\Px p6Ó×$H`³âà·µd-âüÃÝ1-®mX ÍÈÈè3dÈœöíÛŸ^°`Á^4 ÎϾԹ/X!hýÇÕ¼³ðh M@ÿMÉZ/¢ü§½ñÆ.¹ä’»0ß¿Þ9¤×’ÚoÿSHí÷šÜÈÍ)² Fµ‚â/‘ýYH€H€H ÌTŸÄ÷áf„ ºÙ7¨š6à73}‰iÝ¼ËØãh£ä eì| ³ö5S td¢0Ç?R2Z6ó´<œH€H€lGúlÕ# ¹†st'ÌŽÿŽiÃm×ʦtæÌ™C˜ 0 ‘ÿ„ãÅ ÞÚ k]¬uý×$@>à`qW¨‡€Usµ*ÿñW]uU_ŒüÿÊæ¼!ipˆ™ë¿÷ eìúOÄí=ռƎhIë'Ñý­›wZM$@$@ö$€ß:‰m)éý ßJêÀ¦–êRey_5‡”™<?£¡@úHmÚ´¹xüøñi………·mÛ&F€ª:ð°ÃP~D¾ ÀZÜ—Î' ˆd­qùOš6mÚèG}tr§Nn3PÎ?4´>1J¿Q®Í÷ iÏWÍ\ÜýcÚ „ä韅H€H€œD@~û"`ˆˆ…  -oÆ4ºSÏÆH¼Fõœ¦(}¥ÌÌÌþðÈD|€“‹/>€UZ¥ûRzmùŠU o °÷í-)îGçÐ?@²–EYRgÏž}ã¸qã ²³³/Ãvh.rø/¸ü?[<æ06¹QTÆÙàE:=,$@$@$àdFÌÙlÒƒ¨)o:‰ªx¼‹L'1%à¢7®'''wïÙ³g^¿~ýμùæ›…#i…’µxn[¿cH üãi¿"è¿YëE jiï¿ÿþ]ˆj{wBBB׎‰¯ŒÓ”Úõ¯Ê(ÝÑd­ùO¯ô? ‘þ»A.ÿ\².…ŸU®€j@IDAT}³q¾¦Îõ–¨LtLÄÝ_ãòx< €…€‰€÷ÕG$ð>ljð{tcÚNT5Ù¿„a!tÇ‘!`2̬Íp @¤#à –Ç…U¨{ìõ‘áçN&`ý»º^¢POûì³Ï à‚ö³ØØXh¾!Z*ö)cÇ/•Q‚4M-:µŸä1f!   IXy*oY“¯g&õTf§gÎzï5ù,Á=°¼¼üÈêÕ«ÿ˜Ÿ‡$PÒyDȦZKäX;VE'ìÇ‘@Xÿ&´â/ë˜V­ZuÆÈÿÏæïžÈÈÈDgœxO;Ÿ@øœÒ&à‘C€#* £þégëM< #  h*è´Õø®, š¨ßF&(³ão•™zmS…úqUUUåHø"<þ÷ðáÃÛ!L   èw†Ø™@èúþØ™*e UZù·*þâòwÕUWõ7o^”ÿ{].WdH6ЬT®½O(c7 å57§ Å€ÝCæºØíÑ„sð   f@WEÒìJ¶žM‰ PS‰¸Ÿ(£æ 2“‡ãg=ôÔ铵nÝú¢ë¯¿>~çÎû·mÛ&Ó¬i¬}»f2çá$Bï/=<¸³ö#àù!Š¿,ñ÷Þ{ï'žx¢ cÇŽ·ÛOl/%ª@ðŸ­?Ãýç^à¹ðÈ\ÿ¨6è „¦ýóEÜ&  ' ¿Éç24qJ€>ù©R)Cq.ó Á’žžÞoذa)gΜ9¼jÕªÃh‚¤4’¾xxöñð 8— ν÷lù÷¬? RÅ_Ö‰Ó¦M5eÊ”‚víÚ]ÿýî¡U3Š?B”ÿÉÊ(Ç|Á¦™ãÓT¤S Q5åD<†H€H€HÀÿðÛì΀lî¸Öpï®fTUÆÑ·1ì/¿ØÎÞd³½$M ²d¥¥¥[¼xñ~ˆ'1<;.žÛ6kÅ!–'@@Ë3æìM@ÿÈÚº$?ÿüó×L˜0¡®e£íÝ„z¤C”×¾ß+£ðÙ¦»üGbžt[‘ø‡,$@$@$@¶% Þ‘©ƒÞM (SŽ~¤ ó¨2“áØñÐ*III]ºwïÞ¶S§N%ˆÛ´Ò×5çQ÷ýB«q”–üD€?äiB’€þ°*þRO;wîM×]w]AFFÆàlYÅelƒËÿÑÅM_þhŒú‹[áyÆó¦’G‘ ´4tcÄ@âÔœÆÅšæ÷Ôz¥J>SJâHŒ+Hќ׹sçöð8=þü]_zÝôüœÛ$öhû[ÌÖC@¿øe­1u§½þúëÆŒSW²>õkë Ìãsm¹_e{›&g$\ýEù7¢›v<"  .1份ª`¨KÿmX<£ââÉ”€˜Ø©ámø-R5ç`úf—ÁƒW¼úê«Û b]t_І- H$Ðrhh9¶<³} è¾VüeíVþß{⦅Ž9² 11±«}ůO2Xù>§\;þ€ûòúvjàs¼¢s`íG°?Žú7À‰_‘ @(@÷F²ö¸˧Z¼$ž†ãè‡Ê4\0I"u÷ɇsqט˜˜¬¼¼¼Ç¯F&§Í…F€ Þ^Ú>Bë/Ù>Ü(Ih°>ïR׋ÂÒ?ùä“{/¼ðÂûÄjrÍ«>¥Œ]ÁZÿeÓDwÅ!¿Ìõg„ÿ¦äQ$@$@$`c’&°r Ì7¡˜i)³ÃÁ« ô²”——@f€¿Œ=ú¯hºN(Ö½h">ZHôa\“@h°*D¡%9¥%ßXŸu­øË¨¿[ù_ºt锾}ûÞæÛim°wùVåÚ:U©ò¦¸üETFí¨¿ ÚBH€H€H€ZŽ@õŽâüMÐuc³•Ùe†2ã.h9ùZèÌÇW¯^ýxü —ÐF @#@ 1çiíKÀªÙWJJFÍ#`}έʿ w§/_¾ü—½{÷~ 22Ãà¡UŒ ”±ó1d»×>‹ÌŒ‚³ƒ b!  pñ¨D–Q€crAùYH€H€H€H@”÷ˆD¨À˜ ª}âa”ïW2ÑLŒà€ˆ'B¥U«VþèG?ŠA ¨]‡>ÑÅ }G±„xö!ñ „Âç^²%ßð|q‹â/ŸÅÀå+Ö¬Y“»uëv×÷»‡FÍ(þÁþ¦(UqÜwÅå?ºÝYK¿ïGó   p% €"Ý_b˜ueÊk áUÈBtì=¥â;(Û¹í÷Ufffÿ1cÆÄ®_¿~waa¡ H#€ýn%ò3ü ”§ :«ò/u­üÇŽ5ªÏ /¼ðóÎ;ßt)}àÐÿ(׎?À>]áã‘h¾Ìõw»ük4>ž‚»“ „7sS` ðuJ@M¥2Ž~¤ÌH ž' )Nééé}/¾øâXÄسk×.«ÀÚv ¬4Xy4„ü-d,ô ZÖÖ%vìØ±ýf̘1¹S§NwXö·–xc׿(×W!«óóŒè³£þâÚÇB$@$@$@).™ Ù…|™`*£1*¶(•: ½0I´%--­Œñ{öìÙ»yóæ#º®†ë>fh4ŠR’@hh¿ )úÅlUü¥wà 7 øãÿøó:ÜR-ª<¢Œ­÷`~ÝW¾‹íB`qùwÁÀB$@$@$@ÞpO ÀÔA÷”ß<Ó;•*ùÁGaZA褆 ÷E]$F€}›6m#€¤ô,º¯éù9·I ¤ÐR·‹ÂÖC@¿em]âÆßÿ©§žšŒ¨ÿ·Ôs¬=?.ßt6ØßéBåCó£Z!Üþݳ|<œ»“ €ô!"`DInoï‘À8þAmpÀLï òž©©©ùƒN8xðàL   È÷ƒ—o94´[ž90Dá—bUü¥îVþÿûßäååwï"ÿ'?U®-öW)Ai}(b±wúã›…H€H€H€šKÀˆ;;’_SŠ3Y³å5râêR|_©„ŽÁÜ©‘íóuJJÊL¤À>÷„’øŸ þgÊ3Ž€7Êÿ¸À‰Óü+Gæ(cûcøõ1 ¯ü@GçÁ ‚T,$@$@$@$à/FÔYowªÀº<ãë¹<öú'‰ÈЧžì÷1Œ½h°ß}¡Dþ#@€ÿXòL%PŸò+sþÅí?´Fþk”kßÓÊØó(úì/©{¢Úâ8þ9öäÕH€H€HÀ)dJú > R 8à‰/à¦Y¢Ìäa€¥»oöæVkH@L€=ˆ PiÐÞ·ŒÒù@€ƒ°¸«mè_Y[w´ øRsþÝ‘þ¥ŒCoûMÊÆrV-çî$@$@$@$à5ô;$ȰKRÊ”JÉdØRd:ÆíÞ½{³øp¯¹«í Ð`û[D=ˆÂ/ŪøK=vÔ¨Q½%Õ_HEû¯*Vƶ{,g¹»Q^ÿçžïŸ{ö‡Øëƒ¸# 4“€T µFïã¸3œB'õ2ô_pŽ(Óbׯ__¸k×®c™ž!pß(bÃhh˜¿µú”ÿ˜#Fä¿ð ?ïÔ©Óö¹i*ö(cË]Ê8‹¸/Å…´:ÑPþ ¦øó÷%  ðwª@L 0ËϦ ôò´Æ™CJüF€KÏN)ðò¸`î&)‡ ³nݺ]………4ófðÚ~!@€_0ò$ P¯òŸŸŸßcÖ¬Y“;wî|gäðË%Œ²ÕHów2ÊñCèKqéùþ˜‹ÇB$@$@$@A#д¸FåIx>"C@Ê€³Sƒ&¿÷† ÏСC£?û쳇–4Môð÷´lvC(NêSþ£1׿ë믿^Э[·»ê<Ò†')có/”ª*ñA: ˆh…J™ïÏB$@$@$@6!àB”TŠšÓÞ T]®Œ#(•Ø1dÒ¦§§÷…ÇiÔ|°µ­kþƒî³zÏ‚{’@€ Ð`༜Ïô‹TÖÖ%*!!¡ãÂ… zõêuÏg ÒÆñù˜óÿ[¸ËUø þL£ÚÀìÃ1Ü•H€H€H€D@Ò˼~wp@/³™UHø±Rq܈ë A›w™ÌÌÌþ£GvÍ™3gse%\hhPZ¹ ÊÅyQh„€~>­Š¿Ô~V¥¯\¹òÑÞ½{4rû|}øEåÚý'(ÿuŒëSæùKŠ?Î÷¯?&  ° à¨Üçã@‡KÕ´Ÿ¢T«ÏQk×®}Á§ƒ»Ä@nDwg±|èU_ó:Ë!,$Ðò8‘¸åó M#`Uþå Ú ^+éË—/ÿ%FþïkÚ©”kÿ•«ðÿÃOÊ¿û‹Ê£òøÛÅ+’ 4…€{à}éÃx]jÜ}$é+…J‘>¨ôE!o:é›ê~ª4Á³+Ÿ±€mÐ`›[AA,<_œòœÊg²N[ºtiFþˆˆˆˆ²cÓj5Fý­Ô¾¿ù&Ÿ;Ø_;´š³t|ǽI€H€H€‚J@ú.QèÃH_Æ—‚¾’»ÏTSW|=_NÔòûJTú¢Ò'ÅÕÒ°Xûª"€g_V>c![‡•…ìDÀó…i}¡¦}òÉ'÷öíÛ÷¾ÈÈHL6³y1Ï(c;\ڽ냠h~æÂEeã‡ù+ ú0Ò—‘>/ýô™ŒÐ©Ñ‡²{‘¾¨ôI¥o Yi°û £|çpxñ Vl@ÀªñJ]1È’úÞ{ïÝ5dÈÉ111ö…_}Z[ïSƉÝÛ‚fºƒýùh1÷öôÜH€H€H€IÀ%Ác| h”íVêÔ×P©¯À±övö„'@\«V­º>¼|Þ¼y›€¶>Ë…µÈ;Àk‘Àyh8 ?"ýrôTþSêïö‘#GÄÅÅåQ>ï.]u Êÿ]Ê(YïÝþî½´»\‚ÇpW   °9‰ àBÿÆ<A½Ë`œ9¨TÉ.ñ¾Ä< x$µiÓ¦ ‚žzõÕW·B_R=^`^Ññhpü#`õ)ÿIsçνq̘1‰‰‰]m#m}‚TQÆ–;•Qº³¾=Îÿ\~£%`,ä,$@$@$@$n $pr%Õzx7Çߨ@€ý“H(žö6DEE¥æää´ïׯ߉ùóçïÀí«¬ãê¾n_ñ#ÇšWªŸ€~!ÊZíöŸøüóÏ_}Ýuפ¤¤ô©ÿp›|S±O¹6ÿTe{½HòæF‰S~YH€H€H€H l @íˆH†  -”Ìy£ò$¦S~¬Ì´Qgmü í!STá жC‡GßÿýBB#@Ðî/Ü¢ÃïA@~)²–E”Y'L›6mÄ„  222cÛÞE”ÿM?Á̯ÞËéJ„òßûóÏÐ{hÜ“H€H€H t  ›'F^ò²xSªÄðŒcloˆÍÉËËËÂÀÕþÅ‹ïCóÄ ûººµžÛús®I ¨y3/Rý”µ^Äwï½÷^4eÊ”‚Ö­[®çXû||f;”ÿcÆ×ïer!Xldö×¼?”{’ @è@ßG¦˜5XʽkFu©2Ž¿#À¥è?¥{wLöJHHÈëܹsÊéÓ§w¯ZµêĨËÝÀ Ý^–C|‚G@¿ød­Qþc®ºêªÞO<ñDA»ví®žx^^¹|#Üþåÿ˜— ©’'2ÓËý¹ „! (ŽŸ¦L ð¢T—Áð¡2S‡ eï„PIII]òóóã·mÛ¶ËQ´ÖŽóŠî Ÿ÷? –$@€–¤Ës×G@¿ð´â/kQþ£J¥Ò¨tìØñöú¶ËçFÙz(ÿ÷À¹«ØK‘ÐLɉëJõrîF$@$@$@aLÀ&©þjJ½k¤Û°@©¢ZywLöÂ4€^È LV›JKK¥³XW Ý'’”¼¬ ð¡sâ]n›õ3'k½ˆò/ƨô•+W>Ú»wï‚àŠØøÕ ä§5¶N…S—¤´ñ¦ yQpù7˜æÏZ܇H€H€HÀAL*%Ž’wTd‚2»þI™‰ƒliíÚµÏÃ0‚Š»¨4P¼Ä Të4Èç,$àw¢x±@ Ô¥üËgò¦~öÙg“{öì‰!u{—³Ê?l>)ÿí¨üÛû¶R:   `’(ô•¼ Œ\…˜[ ”ôÉì^¤o+}\È). ÒçÕ`z-MÐ}d©³@‹à€ÅË“[è›^ë [ùGº”» Tl9ÆvÕï•ÿÓÞÉfÀ­MÒüÑÞíϽH€H€H€HÀ‰ ¤Dv”éuM™÷€RSéΠ’ú)-Y•ìY\.WdfffÏK/½ôôܹs7BÊ3IÅ @÷õÚò5«$à4øŸ)ÏX7ýR“µUùOÆËðæQ£FMŽÓ¯m‹ïÊ ‚ÔÈÈ?Œ,$@$@$@$@ 0 š¸2ÐâÅt€1DFFÆ#³U‡>}úœ˜?þv4Nç@”~q]±æÄoI hh<ê5«ò¯ bH˜1cÆcÇŽ-HNN¾Àë³aGß•ÿØÚ‘þ‰ávñ’$@$@$@¡JÀ@1¡5b¨j¼!b€—kz›6mråêЂ v×Ó8Ýgn¼Ý܃šH€ÚIÁñ0¯ 虬­ÊìÔ©S‡Mš4i2Ü¢†y}¶ ìh”®Æ<³ðä­Û<”qE €oÐeŒH‚ ‡U6~¨6$#(`42.Ù´ÄÆÆæäåå¥UWWïY±bE}QußÙ¦­ X¡N€€P¿ƒö–_¿Àd­ÑŠc0ê‚'Ÿ|rrÛ¶m¯±s$ÕŸ±å>(ÿ2Í‹bPù÷‚w!   F ëè³`‘íS&&&vìÑ£GìêÕ«·„ºæ:è>t#Œø5 øN€—ïÌx„wô³%k½ˆò/*}Íš5uïÞÝÖÿÝÊÿæŸÁð\âe‹0òߦ¶¹Þ½H€H€H€H€"€)ò•û1SÞËÁ˜¨$evÿ_eÆÙzv©Ú¼yó‹ˆ 0 -—ô€2×éz øßÐGÙo(y" ú”yÞR—-[6¥[·nw[ö·_õÌvelÆÈ¿·Ê¿¬¡òo¿ûH‰H€H€H€Bœº•ÒÇ’¾–7}7c󽈵/±öì[¤/,}bH¨ÓJ?YšYûÒöm% I4„äm³µÐÖ–~‰És&K ÒýýùP'†Dx±i©Ø­\›î†ò_ì€òƒ™ƒ}uÓ½;Œ{‘ xC},ékym8y¶/w¦Ð›“eé KŸXúÆ ‹î/ëþ³îXêuPääEÃc„ß= v‹ôKKä™lË:iöìÙcG]`ëtûðƒñS$g9‘½(.¼¯#ílÆ‹p    b0á-oži\Þê2eœøX™icÎfhüˆ€ï%éÛçççyóÍ7w@Pd‘ô€Tþ…‹_ ÐàWœŽ?™~IÉZmÉŒŸ6mÚˆqãÆ¤¤¤ôµ-¥Ê#ÊØz·2Ê1ÏÌ›â‚ÇVdkoöä>$@$@$@$@þ àJ„jŒ¸y¦dh¤T—*£x±2Ó¯„šmX0#;;; )±÷.^¼xD¬+÷¡îcÛ°)Ôða µ;f_yõ³$kY´ò}ÕUWõyþùçFÞÓëm+~U1¢ýÿX¥b|õ¢¸ÒÐÂ,/vä.$@$@$@$@~'PS„°yǽ:­™ÐQ™ÝfcàF<ííYöîÝûNAAÁÓ|ðÁH(žPñEŠ^ŸÝâÿ$ÐZik¡<„ÎÐÏ‘Vþµ@"þg ÍÉ¿#ÝÉÝçö¶[¥ú4FþªŒ’ ÞIFåß;NÜ‹H€H€H€Z’€/F€¤^Êìú¶õL›6mz©oß¾ÿŽêQ,Ì ,þ' £´,$Ðõ)ÿòl¥,]ºt2Òýý´9hÑc1‡ÌØQ@å¿E!óä$@$@$@$ÐÄSf¼(2Ðc옌1t/âxq¾–ØEúÌÒwƹÅUA{ÓZØä²ºï-uð™cøŒŒXèõŤ_VÉo¼ñÆ„aÆDFFb²–K2v>¨Œã_z'Gþ½ãĽH€H€H€H PŒ\ žò^ÄpÇy:³I©´«pŒîÆJÐÆ¯ƒÌFfff׿úê«[p„5( õöÞ*ë¶&@€­oí…Ó/Y‹â¯× 3f̸üÚk¯-HHHèl×V¸ö<¦Œ¢Þ‰Gåß;NÜ‹H€H€H€MÀ#@Y¡2j)3eT ¥ôêz2p†Ì9mÛ¶=°`Á‚BTi91,0XmšÆG}o6¥_+þbˆ½óÎ;N™2erFFÆ0Û‚:ø'eìŸëxíßÕÊ»}¹ @à ø`P§6)3™^N/®Ûº}ûöÉGŽÙ±fÍšÃ8žW¤ÿÍB> Àgd<ô ÇSùĈÞ¬Y³ òòòn´+)ãè+ÊU8Ã;ñ\˜‚åVþu“½;Œ{‘ ˜€!©þ$E`ãóü“ß(ƒAžøÞһˉmÏž=]/¿üòšÊÊÊ“8ª®ÑvP½Ãɽ,dÄ–…|! _4Zù×ky–R-ZtW×®]'úrÂ@îkœ\„yÿÓqɺޡ’Pù÷ÂM   °3tKeàFúpS»žVFñGO-}k\_Ôýn½ѤÎB^ €×¨¸#èŒ~éÈZY’çÏŸ?aðàÁôO¢±Ø®¥ß(cËÿƒîoJU˜FÒÄ´®çK~L$@$@$@$`[2ÀÝß«/†ž–¡/†z=P©èý¡­Öiii]/ºè¢¯¼òÊfV_ƒtÝV²S{ Àž÷Å®RiÅ_ä¥_¶åŠæ™g.»îºë&'&&v¶ýÊ™íʵùgð ;ݸlò£aÏÆ…ç$@$@$@$@Ê…$Tî© ü˜ÕÊ8ñ±2ÓF*™n;p2°† €Ù(û>üðÃݰ ‹ve•5•ÛÝ5{ D€½ï¤Ó/m€,17ÝtSŸ|p2Ò– ·“Àçd©<¤\›î‚Íôø¹ê­Èܱˆ6øZ7·Þ=ù € ¸å°#@MŒŸ(3ýJôí—½A³sssvïÞ½eãÆEhòžWØy= ?¨‹”º¨ð3Oú9‘µ,Zù—u¢“>Ö½{÷{<²Å6FüÍ·+£tGãâ±xé·Ã~º¹Â=H€H€H€H€ìLƒäÕ{1f.†€†‹™ÐQ™ÝçÙÒ ’oÞ¼ùÅ>}úLCõ(1èE<¬^Ød!º ˆÇB ÐÚ°¬­‹<;)üñ=]ºtùqC'Úw5péÚYà¥ò·/*ÿA»W¼0 ´t_¥g ¯×H1Jw¢ï8ju]Y÷98_KŸ[úÞ¸ƒ€w¸^‚SÂõÎú§]u)ÿzô?ñ¥—^º~̘1“£££3ýs9ÿžÅµ÷ß•qäãÆOjDç!ûÑÖ8,îA$@$@$@¡F]Z ð¬J±4¬Üåû•aRfÊ(Û5ÒårEdeeåuëÖíðÛo¿-î­õÍmÐ}xÛµŸ Á¿v–@¿£»ï؈“4 Œí“7x{Y?î'}wéÃã”’·P:Ázу}r5­HÅayºFÃyÍÕ/½–„<qÓ§O}Í5×LŽ‹“‰Nö*®Â_#èß—%/pˆ.é]XH€H€H€H€HÀ+èCÊôQóö®ßsÞ¨€ r¯2SäÕYµ“ËåŠD<€V»-Z´×/€ú(ÁxÛ À6·"à‚hËŸ¬Eñ—µ<‘ùùù]üñÉYYY—bÛ^¥èÿ”±ÿoÈ„¦¸²Ñ¢¸Föã×$@$@$@$@$àAÀˆ<;ˆd–z|á±yz«2£ÑßLèïñEp7cbbZçææFòÉ'k@¦ˆ@ôZëÁ–W8QüXœG@ÿÁËZ/ò,È’üâ‹/ÞÖ®]»±vÃbœZ®\…Ï5.–+­Jh|?îA$@$@$@$@u¾¤ô))Ò7•>ªÝŠôå¥O¹’±è~¾î÷[u»‰NyZ˜ - ؆§·þÁ[_ò,$Ì;÷ºž={ÊËÂ^¥òæZ= Ûecÿ‘þTò¹² @sHŸÒ@ß²¡‚¾©±íWHp°¡½‚òôé¥o‹ËȘôõ­}«NùxÑàà€àpæU=ÿðµEPRþõ»çž{ ò¯w0<ïÚ5Õx±Þ«Œ²Ýç}õƒÜéþàúÏB$@$@$@$@þ àö*•¬ ¤¬)Wªôk¥2n„Šmõ*222Sz“0 `S©ýA‡çAöyBC^ŠlµôI]”ydI™3gÎä¼¼¼›P·Uqí{RG?mD&I÷'AÿtÙ_“ €Wá…z{J<½º‹QqDÕ•™2ºî‚ôiBBB¤ô®xá…dž‚Îoh ’±¤ûŒËŠÈòÿ³÷&pr”uþÿ÷©žé¹'sd2™\“dr_$!€A¹å]ö·(èŠè‚âù[Vî²ê®« "ŠëßÅÅUWW]ää  \ ¹ïd&“™dºëÿýV÷3SÝÓÝstW=UÕŸç•ÊSU]õ<ßçýTO×çû\åA@±%–Mê^oõ?üá/íêê \×µÿ¿‰¶Ý7B ±ÿB–lø>3yÇÍò€;~ÄV?sò^ß ïøò®Ïù°'cðý_t€Öb‚ì#”ô(ƒJNQÁu,_z©ÿê|ä#'\rÉ%׳‡pV pô½LÖ†¿!Jèr%«œ?ÈÜ@@@@…E"¢MÀ-þe_;¤î~ùË_^ÙÙÙyYШ…øçUM þƒVu°@@@¢K@Þ=•¬¬W ôm&µñæ˜ùHÞùåÝŸsoàM´€nÔA ÓÚAö"H@Z€¢M@¡u,_t©÷šÏ|æ3'Ÿ{î¹7ÔÔÔkêü]w“µí{…kEº`)÷    ~pV8Ì9æ_žZÞHv¼†à[á§eóâ!Vsss[CCÃ+¿ýío7óź@Áûða´ˆDˆ.·Oöµ§/Ç'_zé¥ï Ú’êðŸÈÚø•j¤âBø@@@@ÀCJÚÏø´@wZy· RwÑ¢Ø.iÔú [7ÉlØRBp”fÀ’Ò_b‰Ý›ÔyÃÏþóK¸Ð;es¢›ÔËæH…&ýcóG3 k  c@@@@¢E€µ³óNZ@Nñ;­ónËï¸A ¢D °Mz(€[+¸5D̆-%"€!%°dÜ_\ý…Ö¾šÛo¿ýÍgžyæ UUUÁ™ž”ª×n$Õý|a”ª/¬-| >Ï H€JÞ ¬ 0ÀŸõ¿DÔrŽçÖŒ%ƒ¦¦¦I¼2À+¿úÕ¯Þàûd(€„ì µ¦H}Šÿ#A €Ë*åC!R­ÿRÏò'@ÃE]ôÎÆÆÆE‚³ëR{*l’3éJ°fS-l0>ˆ4Å寧©`wÜ]ß*xߊMÀùJ/Ñ¢´fà]„¨€ z5«=u»7©ëöòýåŒ3¤ËO`‚ê}ž¬M_ÁžDE–üC Pù=•ßU k“Ìð\+üÿH4hÎCüÇo,Gñö D‡@.ñ/u,â¿æsŸûÜ)çœsÎõÜõR`Šœ8Ìc£®%ud_“¸ÖÔt1 \†@@@@@ÀYÀ–¡ÉܹÛÜ˾çD­ïà÷Z6Œ «ðÄ€¯üæ7¿Ñ«ˆa ŒêñÄ ôðk g€Ô¯Ä⨿˜w÷YÂû ÖŸ"ÕûF{Ø|g¹?)€€€€‘¿«:+èö¸á6Ê;¯¼û)ˆ6À6É8[yávkˆ ™ [JD€ @2ú¯Äz“ú•/rýOúÓ+¸›|¹ÔþŸíúYa{T+—¦ºð5ø@@@@LwVP(ð»¯ó\èŸ? Z³ÕN݈¨5…X¤µ†ÏÖ!»R@³j©‰šKOAu,u+_Þª›nºiõ%—\r}mm­ô£F8²¬ ïç^RGòÛãLª2ÂÑüwãð—€Óp%KZçÇUÿ@v+¯ “¡÷æƒÅ¡¥¥¥Ù¶í}ôÑ­lQ¾UÌ Š&€E# Dnœìk¯8®ºêª‹y©•°Ô1"Ijã-DG ­‰g?cp¦*;X    hÎÄÕü.›/ðҀ굛ùÓ<óä»ÏÃó¢D3p…Vpk­AÒ^€ÀKºþ¤­¿ˆ»7ÿuÿùŸÿùŽÙ³g_ä)£ÌeçÜõééóc錡ÂãY>$‘ßeÕÁ?ñ;q‚hÑlÏh88€[_ˆ¹Z{È>B `@+-Ëd÷—Röu×ÿø»Þõ®¥ïyÏ{®ohh˜›u¹Ã¾õÜõÿcœ§ã5­5g#r¢ð+¹ªàåMEœvË)DÁXêšGTñªõ[¶lY÷ÜsÏíbÃõ {öªyË„‚Oœà×Q! uýI,Íåz“¿6MO?ýôÍ‹/¾¡P¾~f÷“Z1©C¯çÏVI¯£öüŸã ¼¨ÞÁ¼ÖÚµ3É^ôvT彯ïXüuåÊ•Ïùîçm€7qèM;tÌ!„‰úX‡©¶2mu‹Ù×›ÔiÍ]wÝõ¶®®®@ÍúomùBañO2V*ÐLÔ8ñwÛüâ^õ¾Nòޤ B´ÛTÛh ­3t,æÊ>B ÀÂJs™¬¿„:–ú¬èììœú–·¼åÕÕÕ“]×ÝUÝmcïfÞÀEPÒòG2/"|    2£xÇåwdç]9 % !ZB4›$=‹ó9b1Ì ¨­±Ð ε"øu}©G½ÕßsÏ=ïèèè8[_`<ØOêÕO²zQ‹œ5Só{GsÜS     ²ºU¡¥­y…,yWæwæ Ñ¢)ØžzÞ´Î8[‡ÅdØ1J˜p” t™þÒIìÿR—5·Þzë‰çŸþ UUUYCO–üSÝÏ@Èü£XàV|    ' ]Gy;’ÛÒD/;65Ÿ™ûsgyiÀ‰¬)^xðÁ·rö Þrû×ÚÄ€…Èr<Ä‹ƒNÚàvÔñÌÿñ¬ÿ‹ƒR$uà¤vÿº€9•,þ1é_@ø@@@@ œ•®øÝ7OwfywJM!Ú‚íáÖºÁ^n SaÇÀ0X¸T{ØÜ±Ô¡lußÿþ÷/˜5kÖ…°3e‚týýóÌáb`Ü>ø@@@@ :ø•Ýy÷Õ¯òÃKæ¼;h(€h Ñli¶@Œ×ÑñðáLàÀ¸*Ñ ù‚ɦ…¿Ä•k×®í:餓.¬¨¨q:êOq/§}ùmQ-üYuþÏñ €€€€DŠ¿û:ïÀy ÅïÎÎ;tžý>-ÚB4†h Î[º/¸5ˆÖ%~›…üŠ €9Š€çó­Ú³æÿR²5|ï{ßûË9sæ\á³My³sºþ¿ñõ¼Ÿ;«Š8Ý t± \Š@@@@@ 2¤¬·œ%R½¯ñÔ{¬·«çäüÜï“uuu3-Z´‡—ü#ç­'1Ðóè/õ~WÌ8óƒ`œà|¾M¡$–M{Þ¤þj>ÿùÏŸ|æ™g^Ç[}¶+wvÜmÉÚð>ž*Dþ°å l¶êàðøå¢ƒs    Q&À¯óª† ØÃ›ÖÏ™åUÝO=‘GöZÁè-ÛØØØÆÛK¿ùÍo6³¥˜0³ºBu¤…e¨Œ.Ccµð×±8D=˺œ-/¼ðÂçgÍšœÖÿ×>Xxâ?5™Í–aD     P®±þßž·ðöÄ·=뎼ŸûýÁk¯½öÝ |œóÝË›t_G€¬ó-^ ÷ƇA% B!ØÜNÙ×­ÿËÄoŸ>}ºL̈0ò¬ÿ l'Ä * F€€€€$ ïÄònœ;mUÑ¢=ØZ÷„€¢I²õJîál ÀˆjÑÝò¯c©·Ê5kÖtòövžœ#ŠzàÀ³þË’G,,.² à¼XPVÔâwì Ñ¢=Dƒ°=zB@­OtSaC„]N>’/’‰EôË&u&[ý÷Þ{å¼yóþ‚÷¬M·u¯+` ûWùÿÀ¸€€€€@ Èk~oÝ¹ËÆsj©Äv²›ÎÈý¹Ïgkkkgñ0€]wß}÷3œ5&ô™)²ƒ ½IÃ-þµ@‹ÿê[n¹eõùçŸ}UUU›7Ù-UÕó©2FI†ÿä M|²1×8    eL@¦õ’wè<h÷¾B4aQ|Z ñd€­±Xìù‡~x+$óHÈZˤ>Åÿ!€!©Šœ†È'{“:«»üòËÏç/ߢœwù}Òî'ÚøiÎUæÉīْëœpÞ•å9WH’zßµå;A4ˆh6EÏ­Wä! àfŸ¿4²/õ¤·š;ï¼óôÎÎNùÒ#lû ©^Y$W󥓂»H¹®Ã9(W#¼3÷ñ»6¿s%ˆMÂöÈz†Z§Hì~éwïÅô²·C* !˜ä ãÞ¤®d@ÝÚµkϯ®®D×ê{‰¬­ÿ^€ týÏçÍ,p>²" ïÌòîœ;X[¿Ë£^Êý¡ÏgE‹ˆ&ál¥€h-þÝúÅg«ÝhÀ0Jþ^ãö”é/Ô“lu?ùÉO.™:uj@Zÿ¹;ÒëŸäîHGó’?bÍy>ÃiLòñÌàwï[ùó|Ãn3SòúH4‰hÎGp;tönm£Ï!6Hƒð d­…¿Ž¥ž*Ï:ë¬Ù+V¬8Oq(p¯o©Ýß%Õý\žüÄDtýϧA@@@@ ÂïЪûy’wð Ñ$¢MD£°=²Ô—Û uLL… .p¸``W {ý…‘XêH¶º}ìcç·µµ­ €DGwz㟠˜‚®ÿàà#ÈC ðPçœßŃD›ˆFa[rõpk› ˜ ˜– Îcàþ‚hᯗý«ºé¦›V]pÁÁYöoã-¤mÈCOþhMâM)Ïe8      ƒ@5ŸëåM¯²çº$ÉÃonä‘¶g»NšÛmhhhN&“ë}ôÑm.ƒeY@÷Ò€æª(#gôÈÀaü@¾zÓ-ÿNëÿW\q^P–ýSÝ“Úó`Xb>ºþçƒÓ     0 …ß©å]\ÞɃD£ˆVa[ܽDÃh]#1B@HÅ ˜'àþRȾþÂH\sÇw¬éêê:×¼™lO>B›þ¯ìä1]ÿó€ÁiBCø]\ÞÉåÝ<A´Šh6E/ èÖ4ÚB·æÑçûLŸÈN¾îMêF¶Ú3Ï<ó<^jcj{ýûhç7Hõ¾‘'¿8ŸÇ¬ÿyàà4€€€€Œ‘€¼[Ë;öð༓ó»y‚hÑ,lK-oZǸµ Ä*ŠmÀæ+B$Ö_=ö¿î»ßýîy«W¯¾Þ²¬Üß|?í?º¬ ·ð4Nfk*ü´y€€€€@Ä HO€îœe”¹ì6î(kÈù¹Ÿ'y.€™‹/~ýþûï…óÕë„ënÃ:ÖÚÇOÓ—‹€Nóä‹àÞ¤^Ä Pó¦7½é슊Šzó&²o|ž—=œÇ”F>/œ@@@@@JG@Þ±'äNŽßÍwôÜŸúzV4‹hÎT†ˆ–MãÖ8ÿ Ät€Àl ¸¿úË!u"[Ýüã‹:::Î1kb*÷ÂÿI«KÌ„     A2 wOÛ M(ÚE4 ëžPë]/n ¤Ï!ö‰@î§È§Ì‘C@!$Öâ¿bÕªUSW®\y®â`œÓˆÿµrÏø’Œ× ˆ(~×¶ø›vä(_zBÀE?æöv³òN´‹hÖ2¿{òÉ'_fc“¼I÷Ù´®ÑÃø‚ß0€ßćòÓ_Qβ¯ÇýK\ï½÷¾kÁ‚Wñ¾ù°ó_ÉÚý뛿42~Æ|8º›¬­ßÎcû*’â‰Dðœ€óî» ×Úzûv{nÂh2-#š†¯­äM4Žh·öáÃÁcÙGð‰€T‚úK ±ÔƒÞjoºé¦³Z[[7cVf®Ö–/ Ê<9x”,Òà%Ø(é⟧÷í@/9ïî%Ê©˜dDˈ¦á4Ü˺ÚPL6¸wà´"oq?ìZüë¸òÊ+¯d‡Y0ZÿÕáçˆvÿ"Oqy6Ò¤Ìü     àç<Ïê[üîî¼ÃûfLþŒDÓˆ¶á+ܽ´@ßèÖFúb Àà!ÜI˃îÞ¤d«½á†Ξ0aÂ1îõï£MÏÓu$räǦ''æ8S     žpÞÅshgyw—wøÑ4¢mØw/·ÊQ€qr ‰x¡ O?äkÑ/u [Õ7Þ¸’ÇÊÜPUUe\]«¿$%ãˆr^‡ÔnÈù N‚€€€€xM€‡(™`¿XFª;OØET=gØg~Ÿà [Ž=úÌc=ÆF‘nYtO(&iä·ye™zø_íò€goNëÿW\qVCCÃ|ÿMÊÊ‘—ýS›þ!ë¤>d_fý×0ƒ€€€€€Î;¹´#jÓ?rƒÝÀð|>#ÚF4g«{dë ˆŸë$÷ã³e’~¸%Îný¯þØÇ>vü9çœs}<o1Îc×7IíùßÜfØÒ9¡:÷g8      à‘,çTïðüºÉ®äeëŽþ™Ïgêëë[c±ØŸzè¡mœ5zøÌ?;;ôÈ&âí±|KÝ›ð'LíÅ_|&w‘éò6ûQ¤>°Ÿg½+Ï…<ÙºþçaƒÓ     à3çÝŸá¡kjjþüÀl嬥€Ì€¹|®É=üƒ.â_oÚ qÍyçw&!fúgJžœú_%Úñ£Ü:ÞÅ<Ëä¾gA@@@@<' ½tó,ϽãÇûµc=öï9Oôð|:/銎à í\Ñâ_Ov!Ì«o¾ùæcÏ?ÿüxæÿfo²mªIR¯|”Œ½Í6áMòX_Ȱj'“šr6źþšÔlÞZO&U;‹]”ÜÛ'ì!ÞBªq)©ö·‘5íB²º¸\6)žSÀ–9@@@ êlîà­xˆœlÙ¡ãm—òY-S²/ðç˜Whµmû<òÈvÎ+øƒ}0³µ?hF$w„­Þ†µþ?ùä“^ºté ¦K®öÝOêåÛr˜Á¦'¸;0Uæø §@ÂDÀªæy<&LVÛi<žŸÇñ—[°RrÏCD»"{ïSd'Ž””@@ ¬°ømáïEoÏùÏí}‘qëÖ­ûêªU«x\zø]èà qíX‘X·ük'@ÕûÞ÷¾e]tÑõñxœ§Ñ6x ­õ2wýà C²ƒÍ-ÿ˜ø/› ŽA <bdMKù²zpßç9ê–-¨4„¶··ï¼óÎ;ŸbC¤kž6TÇFí‹ræp”¾vµjÖâ_÷ÖñË/¿|Áe—]v}uµ,žm0ØýÜúÿaö·õ7Âæ5½mLü7 ΀@p Xsx\ÿµ¤æÜ范§¾Ã#ÖV¼ç@8‰¬Ž3­â¥í$†ŒÈ €€„€KiåWÃßõUïKd·_ÆŸ™]®¶¶¶~Ë–-àỨxâEük€Žµ¶ óp˜@éëIR½énÿÂY¶ú¯}ík—òòæÞìú&©½°IÙ×÷Nš™mŽAò°ZWPl>‹þÎ÷Éd~蹓V¾Ob5Î 5õ^ú°žÔ¡‡xœÐ`œàòÜæ~`‡µþó—‹æÏŸÏ³n»î$µï¡áFØ5ÜéÆðª„í«q·øßÄ-þÉ­Õ2WBÉ p—IÕ°˜—K|;¿ŽT‘êÙÀCr,§TòŒ‘ €€”šëj™ Pe-‡›ì#»’‡ÔWê Ç”÷˜ÒÙÙ¹éÛßþö³|#zŒ‰Þø.F€ñqËu—Û35ÌÀvë‚ NÏu£¯ç=dmËÓúŸD뿯uÌ@` ¬ª²|˜¬å_&jZ9†;qé¸ H€©—’uÜݼzÀÛøå ?™ãf‰A@ÌÈóŽom»—{ô˜³+³h$ÑJ|(ÓòcëÖRé«0ÆQƒ(6F€b Ýï~P³[ÿë¾õ­o½}ùòå×]nhoç¿rëÿ£Ã3·ë¸õ¿qøyœ0J@Å*ÉšÁÝÒÞFª~®Q[Ê6s‹{´œè,«H}›Èî“‹@@@ ,XòI•5Ñ-O|kW°l©_m´ uuu]]]¯|ÿûß ‘.wz@µ/j™£9£45Z¨õ_W¯X±"­ÿÛÿ¿%fó“èúŸ N€QVó2Š­úY×°?œ'èD0K ®‹¬¥<ï›Ȫ„ÃÔle w1H6ñånÉ’ºÛm€^i­TÍV‰v’Íݸš26Wô'ˆGM=Fªà…îT?´ÂV¶Ú{ï½÷ìU«VÝ`q(˜Š×îüzžÖžèJz €‚€ª¨'kîûÈšý>¢ ^«!P;T 8²ƒl^1`¨¡"PfÂp`¢¸A]æp‡€ôà%g-\¸ðÅûï¿ÿU6O&,Öôp×U‰ö+J”’IÐŽí¸zõêÕ§Å8…$3ÿoÿ&°‰InÉÂ×+œÿ Xm'°ø¿‘'ŸO=B` T4’5ÿcdM:ƒ’/þ%û÷ÖT  $7úźy7™Dz$ÛþŠ?ã Á ÑJ¢™8û_ò&Ëh=%*E4Ô C(E0+JKQóiÈ)A?¤ëÖÿš;î¸ãäSN9åz~¦Í}£Äº]wå™ùŸÅ²V®@0H@ŪYPr«ÿ¬ÿÃA¤B(ÔL%5ù­D}›ÉîÝ “a$€€@¹`ÙâôèË ½*y¨aýªÌó>ÕÔÔt´··¯ûùÏ.?¨¹zhg€Ï–E+;«ÅÐ-ÿ SWvÚikãñ¸Ùéõí~nýÿ^ŽR²Ÿ"u®s€Á)ð•€ÕØÅcýÿ…¬ös|Í™•ˆ€ôXô)^¥á$Ž,7þ9m•™ZÛÿÛØ³†d^âù‘h&ÑNœQonMåÖZžÛõ Р¸–‡Q‚û•}áZ}à 7,»ð ¯¯¬¬4;ÃÞî'µç×bgfHHc³2 ”Å3ü¿…ã­Üåθ°×¾ªŸÇCÖxšì#Ã^Ø  I,_¤ÝÊêè#;Îï"uÇ-5¯ÐÔÓÓóÄã?.Kî$xkõ&¶¡€P("ˆXE(Ž@.'€ã¸âŠ+Nã®,³‹K¾Ø»Üúÿ‰°‰Xö/œHKqÅâp—žèOÉŸ „H¨žNÖŠ¯¦‘(   9Žþîamû6U4·¹ ÚI4[ ]êÄHÑ«¢·$– µWêÿ™€9æqCÆÃ'¢~0…iûŸ2{öìÓLsRû~ÄcS·7ÃiýÇ÷g8œï X5í[qÑÄ·xŸrðŸ€UÃKÞJÖœkH)̵ë GÂX8Z ëªþã«ZyðtС~8¥«J|Ñ¢Ekõ¦buàפ½><{´þg‚3 à«ãT²–ÜÎþì:rC Ð|ÅVþ#YÕaŒ–09zˆv a:¤µ/M08 @´–Ö]Ú<9F#8ÆÌu¹~%Ö¤ÄÕßùÎwÖ¶¶¶žêºÖÌî¶;sä+­ÿ9ÀàxH€'û›y)Yó>Ê?]9¼í挤@ v&Ï ðe²fÀ˜  iŽ&Èñ^’SCøKM´”h*ÎU÷pk.­Ãü5*"¹ÁP\Eê‡O?³ê¸ãŽ[‹Å*‹Kº¸»UÏc¤ºŸžZÿ‡3ÁðK²æ¿Ÿ¬Î«=ÌIž@¼•¬åÜ yqàM…  åB€%L®^¬!DK˜ ¢¥DS± zI@ÑY¢¹ôfÒ¼Pç=|úÇPÇãõC'±<ˆ² GÙªo¹å–guÖ  |l,¨Ÿ$Õ·5+öð%[ùœ˜Ž à5™N-üYígzÒy&½…¨ç²o ƒÅ°@@ ò¸ÍÒ:Ä¥Ì÷?À¿S­-=¯ Â則~x;Çî%ÚöÌE¼"Œ€vh'€ÄU_|ñ©ÕÕÕ2k¥¹Ð÷©ýOÏ­ÿÙà xD@ÄlñͼÜéå€dCI€Ÿ kñçø¹8)”æÃh¨`I“«Àþ§HõæèMìcñES‰¶â,ݽDsiæ£5ÑÉ €±Õ¥n:wDz/+Ö¬Y3yúôé§Ž-ÉÒ_mm—±ÿvVÂÜú±ÿYLpÞPV¥3û;µžâMH5ÜT,µL œá®GX Q!s.›ÔÎo/¡h+ÑXlˆLV-þݚ̸­a1@@"Œ€~Ðô(±lÕ7ß|ó›yÙŠcK®ÄWÝM´'Ç̉FRŽO Û1Pâü‘”;‹[þý-ÏþŽù ðì oå—Ÿ${×ò_†O@@@À6kŠíÍÌi7kŠ©Üû¾Rô·™ ÚJ4±Í¼‰î’ñ ˰Ñf8 a´AÀ!ŒŽ€þrµìË&üô_ºté›ùØlØõmþJɲ§'pÖúÌ:CÒPù¿‘Ç̡忴`£š;ÝFjâ±Q- Ê  ¶L_&Sš¹‚=@Öλ]'Ìì¦5–, ¨u—ÄZi£ÜZMŸCœƒ€ÀC=ý éX?„U_þò—Olkk3ë°ûùKzÿðÒ$¸õ߉á`pJH@)Ró¯'«íŒ&Ф"O@æXôiRM #_T@@ ¸œžÂ¬†…?ævöÞa§ýeʳ­ÿ²,Çî_ /ErÂðs8 PjÚ9D“N/IZHrPd-ü©ªÖÜã,€€xI —–ÍaxI@Ñ^¢Á¸èÒÒ)š,—Vƒ3 À³@8®Ü–0“­êºë®[ÓÐÐ0ßuï»j/ý7p(3_»†¿ 2A&€@© ¨†ÙduÝPêd‘ 'PÙHÖâ[ø<~ª‡ÃÁ/ 8Z‚5EF`ÍáhŒ“þˆö ƹæá?ŠêÀ[E~HúÊ%þ…[|Þ¼yf[ÿÅö÷ //ý‡ à‹Çý/þ8ûš1¹¦t‘d.ÇšyQ®Op@@¼%hžþÎ ?çó™´ËàÖlb‘Ör>[üìà(\GúÁ‘XXé¸êK_úÒª¶¶6ñ> ªç R‡^ÍÌߎ“ÊöÖe^#qPs¯!ª–^g àk浤çú—!r& ìjžf,sª3uè b2ˆ-Æ6è^Z£¹µ›I7#WØCjσY™ÅØSÇëv&³Nã@ 8•udÍÿHqiàn(†@õR]W’ý⍂{A@@`L”UK¶Í’Q Þ'Äž¾‡§á37Q­h1ÖdßZ·nL†–àM´š¨ ­Ýx× YK¥éÓåc kîº×Žý +q˜Ô|õ«_=cùòåïÉ}«Ogw|“ÔÁÇ33ãq:*Á]u@JJ@-x/© ËJš&±P‹ˆöý×aæ—.ðƒ€#Ÿù?«Ï•[’ì8kŽúã]çüÝ­®®îhooö¾ûî{™s±V ~ó)7¶™DüKpÇnG@|Ù²ef[ÿÙÉeíúaÊÊÁÿ©$&ÿÄ(Y‹Ýš|n‰RC2 P  °€{¢Ä°ÊK1q/€€ÀØ([F=gÊFk¯Dæ4¼-­R^Ödîab¤[ÃIvú¸”Y‡:­Ìš uQJj¼~P$Ö›°ª¼æškfOž<Ù¨@|¨gfÒõÕ™ G P$XœׇŠL·ƒ@ ÔÎ$Õya DR   0щÚÌ‹X‹8š$ó¬¯G¢ÉD›q¦â!¤u›[ËùjS2ƒbÌ_KúFz‹_vÙe'ÖÔÔÌÈ›Ÿìúá™$s,Ó1ü*œÕÉ“þaÖÿ1Ã¥~°fü%©š6?²B   "KkäÒ$>òM&ÚŒ³ÌÕ @;|´(YÁYOúAq‹Ù×€Êùóçmý§£»Ií{,Ój^¢C%1Ÿc&@‘ª[Èšqe‘‰àvð€€Å=Sº®ö a$   ¹ 8ZC–tG“°61ÒÚL÷ͦµ›Ösbžì#¤ À0üQЈ~h´øá _XÑÒÒbÖ°—[ÿí¡Y8ós-Ï1¼\8 0ªë*výeþÐáv\ Þ˜t©æ…ÞæÔA@@ÀM [sˆ&mb0ˆ6Æ&¸{h'–imgÐÊ`e @îúÐă^oòD^wÒèL{ÖÎgZlóÒ‰šÌs8(Š€šÐEVûYE¥›AÀkÖÜ÷qx¯ñš3ÒHp4kw°vþÈ}èû¾h3Ñhœq.~$sÔCPÜ¢_ïkñ/q%¯7)—± zç埶dæŸY9@JIÀš}m)“CZ à ú¤Úþ,yS.¤   \ÙÚ£o+©^¢Ö`Hk4÷0ÑnZϹcƒV'k8†×…û!Ñ€ª»îºë¤ÖÖÖ†_îßµû¾¬Ìxé¿ì/aÖ8Õ¼˜¨yÕØnÂÕ `ˆ€5ëjî§–ÙcÈd   PRÚCäÒPP»0t``O4šh5κŠ7­ßܚ΀UÁÍ€TÝè§Øý 9–¸òØc5*þ)ÑK´ïÁ”µú§ë?^ü4Ä P V×{J‘ ÒȲ€“Öø“rbí‘=üX4Šhƒ!­Õt/­áÜÚN¬“ã²"nRÜ„pÑNlÉ’%-S¦L1ÚÏRíÿo¢¬/VÝÿñð‚@) ¨–eD¼!€@ˆX³Åi…ŸóULpÈÖ ¬Q­b°T¢ÕD³± Ò:êÖrÚ*·ÖÓçÊ2ÆCfµËƒ¡7a#[ü£ýèñ&LXšy©ÏG»³&ذ+yé?ÌPîs- »ˆ°fÿEÄKˆâE’@õR“Í.PI®(€€@NŽa-’vgMTžñ¡÷¢ÕD³qN˜ pÜX<~¨+ˆ[øË¾vT._¾|õ½ýøO®qðÙ̲åwÇà9¿wҚ휯ÖqZÓ‰j’}wì·yÉOà äv› ^V¢­££Ã¬`ÏýlJÒUOOþWç:Æ.€@±¬é›îsêç‘jYb.ä   PVRZÄ-%Y«ìÍb.ˆfíÆH#·Û â_‚ŽSGeú?fK=Ú;¤yhd«ùâ¿xúÒ¥KßmòùP›>Kêèþ!µì¨:Æ€@QTí$R >Ìiàw¡(¸Ù(o&{û¯Ú€ÌA@Ê…¿3©–ÙG‡ <°›¨íò¡cŸ÷âñøÄÆÆÆgï»ï¾ œ5ç´øK+ª´üëwË;¸Ý6åHB¿íK¬7a"ûW,[¶ì8ŽÕû<©Þ×3óÇÒ™§ ÿ›îCZV“ª›l(sd   Pv²4‰:ô:Qßz£ÒÚM÷КNë<ý²§c£¶šÊ¼ÜÂ]?îC¸ÄÖ®]Û>iÒ$™LÂXP{˜™·3ùŸÌm P±8Yç”$)$Æ L9Û¸ 0@@ <¨$k’¬É­ÝYÚÅg¢ÝDÃq¶îÕ´Îk´öóÙ²àd@ª.ôC!±0‘-~ýõ×WWW77u‰‰ÿ¹ÇÊž_efŒ±ÿ™Jjÿc®ly2§ì15®O±  0vªuåØo 6ÍìË®¨ ›Õ°@@ ¤T"³ÑRí”ÛÖ+h:Ñvl€L¨õžÖ~Æì2q¹õ+—Š— ë•«V­2ª ÔÁ2gÿOðË›-f–UÏ©#ðŒ€Õz¼gi#a +Nªy Ù»ž ŒI0@@ Âl–T²jY¬/UHY €µ=á c…Nk»‡Ù­÷´þÓqÙ åteëX? ÇxÆH£Ú›Õý?™éI+·ÊByA ä,v·ÀPr®H0˜ZŒNiL&° @@À;ÙÚ%[Ûx—sΔÓÚÎ=@4ŸÖ:ÎyoTO–£@×¥T¸û¨¼í¶Ûñ8s§ûÿ#Ú>Ç<5 ÃV@JE@Mèâo>¾W¥â‰t‚MÀj67¢-Ød`€€€RÚEdV*¨ý¬m m'­á Aá¯5`ÚÊòŠÊÉ ŸDíéѱ0­ríÚµ++**Œ5¹«nîÂ]eƒt¡qžÓÁ3Ø(–À„ÅŦ€ûA <êçð¯[]xì…¥  !'À+ájh‘aÝ¿3V&Ñv¢ñØqhݧu ŽÅ>Ù/‹PN©P]±º²u,b+LÖºÊî"“5‘†IÛ7D…€Õ´$*EA9@`x"Ù Fq.ÈÒ0j¯¬Äg.¤5ž õŸŽÅ0Ù/›Pn©X]Ùk/PÅ\0¥¥¥Å  It€gÊÔÁŽñìÿÒ@ tøk?á˜Ò%‡”@ x"@ð‹€r&1½ŽÆa­c(ˆÆ­ÇÙËøZÿ¹5¡!ËÌd[nwEKÙµ âÝï~÷òêêê©fª 9ô'¢#û†²‡øb=(U×ÁÀ&”(5$á `5ÊÐGð‹K,·–aãh¿²ÏÊG4žh=>­ZºµaÖ]Ñ=,€®\©I½¯+^T,\¸Ð`ë?uàW™OYö š™Ÿâ@`<fç.Üá&Ð0?ÜöÃzðÈÒ2j¿Ùai­§º!XëBáëÞï1X\.DW¬Ž¥üVœC[[›Q€½ÿ!m#Ï”)ÝÿãCÇØ( z8J©„Š@EQõÄP™ cA@ÂMÀÑ2¬it°¸´Ž>éc,ZO4géè?޵Ա֘ͪœºru,e—ýÊ/|á Ë'L˜°ÌXUÙÂÝb^ʳÿ±À”€@ i"©0P ³Âd.l=–Y®aêÐFî¼ÅX©Dë‰æcôr€Z ŠÔ›1ûüÌXºAD=dW¨kÏÄ«W¯6;+Ø_²öP= ðҮá° P†¹EÝŽ›A ´Äùµó‰ÐšÃA@BH@4M…^âœÅhž¶«$­ùþÀ¸µ {vBщ"­Ä¤ðå´#ÀKùcÓ¦M3êPûªÛ"eW c@ 4*ùG¨jriÒB* 2ªnZÈ,†¹  a'àhÖ6:¨ý¿Ó»Fâ´æ“q b”[ê}#vùéPø³™ütåJ¹e«¸ä’K:šššÌ9=< ¯ CBZÿÅLRP5“J™ÒPPµp„ªÂ`,€D€hÑ6é ü™{ô¡ï±h>Ñ~œq®É}·ÇT†Q •´þîØq\|ñÅÇð|ÆšU÷,øÕ¿t•A(=êöÒ§‰A ,ªáð¥ª,~­ª¬#UY˯—õ¼ßèótÃÜß0Ý»Ïâßy541–cW²?õ. QõËñQ~I>rìŽvó¾¹—f_Ø!hp`Í#ÚÇn:×HYEó‰ö»ï¾û6±¢ÝÚPïK÷Ùì0€¨;¸îœ Ô±T¦T¶Þb¼$ÄRùÐTPûÊZºÿ'å!²ÏÛPY±~¨ÀoäÈ/@â-,@«Y\Q!4%>Tí"éQTÚ¬nC¨æM†UÔy[¨£ûÙÀ[ß6JæÉ´oç}ÞzwÝ·ËqxkR±mcË0•j¿ï·D†byZûýŒwµ”X‹¹$Òâ_ X]‘ºbÝqlâĉæfÿË<%ÿ§‚«‹Œ>…@ Djø¥ʘ€ªm#»{SCѹ_5Î&ªŸIT;ƒ¬:ÙïâÖü cHăK+›ØÞêf:o®ÃràžÝ(Ùó2Ǽõl$»ç vüô »'@@À7¢qÒ“ªƒOmêLk?é†åÖ„îýÈ·Ä–ƒÀ]¡ÚÃ#qÅ-·Ü2ßèò}ëÙ[¿{è»7À­3 žpZéð Ø–Š{Ƙ3E["K ÂpË]dÁ¢`¡!ÀÝט¿W³ˆZVÕÂB¹i¿úñýÈ~õá^ J¶Ég§J)=xâ¤8öþ™Ü[À†C ² † ˆÆ±9–ÖÕ¢ 9Dû‰dÀ³ŒE4¡lZ7J,AÇ‘tDÙª¾¡ tW¬TtlÖ¬YKôE&buð±¡lXúoö@Àqî6‹åL Jz”i¨n%5ñx²ÚŽgÁ¿Š[¢<«tÌÒS u Y¼9á(O6¸ç±Ô¶ûÜ;ñ@ÐKû@ÂF@´N,5I|”ìö¿6V‚´”aùÄ$…¿^)«ÿÚËc577Wñfnü¿ÝOêà:]<>­ÿC0°q³ PÎÊì; :‰ÚN kÒ)D fºš†æqãÕ Ôä·:›cs÷zJî|˜ˆ7gІ‚–€hAIb-DÊL¨h@Ñ‚ûöí“™qµ>Ôz1°KeXÔº"ݱTrÅ'>ñ‰%ÆÞT7·þ˲?é 0 F< ÀLOÞåA©$Œ‰@ PõÓ‰:ÞBÖä3¸{©,õŒ0.ì0±ÄiÒõW<‘ O*¸ý×d‹CàÐÖq%‡›@@@´ŽMûS X‰²ßlŒh@Ñ‚7Ýt“tÇ–õØÝZQïG¶@Tºâä¡Òûën±U«VîþÿØ– I{(Ëc €xC VãMºHBD@Y¼Sˆìµ©U-¤:NaÑ&·ôÏõm¸p”êç’5g.ÑœëxeçS΀­¿Á0QâÃe i¢uDóXGœêàCÆb@Z >Á»n¨u£\"û"÷ÓU@ªºr‹QÚ±éÓ§ó4¿æ‚}ðñÁ§ ÝÿÍÕr.p”IM£˜ˆ 2A&òk;ެéoçÉüx\ÿÐ/jdŠÈ‚4,âž‹Øð^ð%·üŒç ø›¹÷ã@â‡Q z2 í°þÁhqÒZÐ=€n(ÖN€Èþa+'€öîXµMMMæzÝEêÐÆÁ‡^ ðKYd±ÁbbÌPèac>r Xmøkª¹µê[Éšv!QU[`Ж!Š_ÛO'‹7êÛFÉÍ?"{Ë/‰úÓÝ{Ë  0¢yìÊÔ•¢…lÖDTiæo¹hAÑ„7nìe‹²Å¿nýM±BwMߊu…¹c)§®ØŠo¼qQ]]ÝSµ¥>ÀY§—Û±Ùñ$Ýa@¼# /« Pî,iègPMó)¶ü;ùûduýˆÿ U#ϵ`ñð€Ø)÷‘µôüÄbg¬ƒ- A"à {Ö¿E¼0 £‰Ì(ZP4!ç./‰¢ÝzQŒrkI9ŽLˆê[±TX®M*¶âØc5Úý_u»º¼ pWO ¨XÚÝìi.H‚MÀîã––0¥xé¾cÉšu/ÝwL˜,/O[eXFÇÙÎF{£äëß'{· @Ñ>•‡œ¢‰ìÖK\ú»›Ö„s®º¡8—~Œ\?í¨:ôÓã®DíÕ±¦L™bÔ@ŸÑöaù¿!Ø‹*8//U3‘ÿØóºÓ¼Ô”³Åd˜¬ñÈ ^Öæ‰aŽäùXyãØîÛÃqwTÉ \ à{ÛO)ùÜ?ù–_QY,"O&k滉êf•n6D …—_äÍYAàõï’½íaþûžîùhÈ$d  2@Ú¡‰ ˜—Ö„ƒ‘MpkGù“eTîÊsï[S§N­áu¥»‡™Ð¿‘ÇÈíHçÍ­‰,dÆ*ä Ũn実]Dõ³x’¨TL5SYèÙËe€—hí{ƒ—ŸÚDÉî < õËd| cM‹¯1¤P&’Y€½xWðKËsu¨)<›¿,=‡%ü‚__£±PVXò)¢Y¯Pòå»y)ÁGٹƴÑÀ5 i¢}¸ó?ñßÑDG·±CÀ̲­¢ EnÙ²…_63Ä¿[?FîVÔRYî +O{v*>ô¡-ä1¼ž™ º?”±3ö?Û䡱& ‚â R-¼5-÷î…]fð¯Ÿçl΄SJß²÷>Mö¾?ñ,Ôd'Á>ýɰØèv'@ $7|•ì×îxQÙÞ~"#gá_×p[aÞ¸Ôu‘uÌçØ»ž’¯|‹OŒ+Ü ¬}Ü4–z7S=¿'»ù"#M(Úð¦›n’ñÙGyspÛ$‚-2Ž€¨9¤¢´èÏÇV®\¹Ð]›¾ïcü¿ïÈ‘a鍯™D“¸k.oT?§t '¥ê©ÜZ(Ûy©»åÅrç#¼4¯+ÛÍ=ÜÁN¸°eA ¹þ‹d¿ñ?.«j[ÁÂÿZ¢³?͆%㸞­åOtðYJ¾ø¯ìÀ}>J¥CY@FK@†hÀÇ9ÄÜ´6|’wsiG}.2â_ÊE€”K‚®0‰ukÚ´iFß2T÷Ÿãeù?:iéŸÂË=M9“¨6À­sòb)"¢‹ÅDÏË”Üös²·þ–»—qÏ€¤8u@ \Ø”|þv²7ÿop \;…b ßKÔzRpm„eÞh\BÖq_%ÚñkJ¼ô ¢Ã!› Ò;2HÊ‚€³ wpB·kn4¥OkÃA­È&¸5¤‹¼Ï2Šw¥iñ¯c‹×|\à=Ö<9ÙÂb$ý#'Ëÿé…0ó\ŽÓ `’€tï·f\@4q ›!_¡î`ͽh Œ°3àW!2¦‚@1Xü¯»-5éZ1ÉxuoE-©®ËùoË»øÏ ÿ"”7ö·P¬íd^1à^ªrw Æp­ò~ Pú²! H´âš}[¹óývž`²‘â§µ¡vhÍ(±{‹T€(ýúj…¢+N*RÊ'›8:â7ß|óÂ3Î8ã‹ûÔþ_Ú÷»T¾‰~æk|·‚@A²ŒÓÔµ[ö Rü‚î´øë¯VÁ;ƒù!O*Fõ³IM>=˜öÁ*(1äŸ?Möö‡Jœji’SÓN§ØŠ¿ãyCŽã×*#?Ã¥)R)-ùÝif‡óÔ·q#ÉNîÁµ±´é#5`°¸w¦l껈jÌÌÑ^QQÑ:00ð«GyDZię,Y"›ˆ~÷âb.‰+D­€TŒ®½¯ãØI'4?‹+³ê–á%é0 û½èˆAÀ göíÓxöí«½›ÌÏ`ñ5”§ÛÿöƒWTéî¿ø&"y —@UYË>E4õ1J<ÿ>ˆ¡Ð½Na”ÁyDŠFdCdR­u,öéýÈô0&†…¦‡AW”ÄÒÌ [læÌ™æºÿKaÝãÿeò 5i5Yó¸«|íŒX@ÆC 5æÿ—ã¹Õ»{T©Y±cñ=üúÄÝ=@`4ZO ØI÷Pò¥¯‘½é¿ùŽÈ¼s¦ô¸ʆ@j9ÀTqíCCs¤™ÖˆÒk\ëF·–4a’§yFÍà®,-þã––ñî˜ {xŒ Ï !É/BIyÆ@À †i< ×û‰¤;.€@h $7ü ¥`‰ÕÌ˾-¾Ùüj!¡­Õ27ܪ&kÁDSΠĺ/pÊæ2‚âƒ@ °MÄÃT//í,Z©¢ÕHAÓqP3²âÈÖ•‘ñFJá¢ÜæxrÞúÖ·¶644s¨CÒý?ýÜÈÚ— `Š‚Q󮤨›î†ø7UÈJD ùúwÈ~å%J­ÉÄ,Rsy’¿Õ<³»é¥BKP$a˜¯{Ó7IÍy'¿ŽGõ•Õ0cd& j"›Ô¡'ŒY"Q´"àèFŽÝZÒ˜]^e•¿¦º’„“ÞwDZw¾ó ª««Û¼9Rºªû©¡K°üß ìùJ@5Ïå—©#köÕüMA/_á#3(1{ë‘ý;ò‚ê&SlõÜåÿZ¶H~‚@ x(‰5ç:Šÿ%¢ºö$ˆ$@CÀ¥‰2´’ÏŠF­ÈÙÊ˱[Cê}±È½/Ç¡ Qqè УcíʼnÍç /2Û=ÌV%«÷±¾°· \Ê­rÿÊ/P¾d‰L@<$°ûaJ>û•Ô<Åf3Ú¤ÕŒ3xÜö]DÜb‹žh:†b'ÞEjÊ›=I‰‚øO@%‡zEÛ=fçHkEqhý¨õ¤ŽýäQŽQŸ@W˜5uêÔ¹19Y{€»µ¼’ºÎÿ5¿ËÈp…AUM¼ôÖ'‰š–4Yƒ”Œ@÷zJ<óyÿvÉ’wB•5[ò!"^Ï<'PQË+ÜFvÛO)ùÜW‰ú=Ï€xH@æDÓó°V²Y3÷ú1ÒZQDšÖÙ± ³<ÉÓ aOŠ2ØßPW–®@'6:þ¿—=ZÉô”³ü_^Ú¼©¤0ªe!YË?K73©JÀpÀ?¾m”xêc,|úÌ—¥a;ùï V1_efê8‡b‹)ñÇ[‰z6—YéQ\ˆ™€'­¤X3Ùu+0­EGfhH>–s$Ž„ˆ“†=hÁ/åpWìKùbøÀf×ÕÕÍ“ LûÐ3ƒÙÊ’ à5ãmdÇ]„!þýÀ<@À{½,þÿ–W”Ùï}^#ä ¦Êݱÿ âNøØCu3yN›ošz²‡™ iÏ 8£©\ÜšÉó|³2­(š‘Os·„A'€[[ÊnÝ)Ç¡ QphðºB²ãØš5kæÆb<õ¹¡ Ük[º&»0d²<ï?ï*²Ý¦äo€@ø Ø”\ÇCyL/‡fÅxy¿÷“µä6~=»~¾(A( X5d-ý ©…×òó¨ßÓCY eKÀ=7Z†fò™ˆhEÑŒœ­¼uŒqì¤0âm¸ÆN@^ΗÞDªã¬±ß‹;@K ¹áŸÉÞáZMÆ„¥ñzîòÿ¢æ&rGž —€Õy…³ìdâ’rôPÞëð€@ $Y®%Y’Z–²Å>ò‘ÌáIŒ9ìÞuƒŠ|¸OaŠ'à´üó¬à­'ŸRC©YÎæ–:SÓÏàÉDï ªhX…TNàgöŸ¸7ÜšBWá3pk$·vòÛDÑŒ¢9ß쉵øwkM¿Í+Y~%KÉ|Bî Ñ^kõêÕ]&MS‡žOe/ë\Úò,!€@ (Åcþy n´ü—*’`H®û /q¶Ý˜1jÎ;Éšû^cù#c7^GÜ:æ³”¬ºƒì×~4îdp#€€_X#‰V²$ÚÉ\Ÿ7¢´v|K.ÚRkJ­3ýâi>R¨(])Ù±5sæÌ.“T‡6¤²Çø“ÕÙ¼Õ‚«¸•ãìÈ–r%|ý^²·?n¦øìXT‹®…ø7C¹–€µàƒ¼BÀÕü/¯‡ &ÖJƒÚɱií˜-üÝÓe¥Ë6 ÷_uÙ×&±ÕÚÚ:»t¸Æ˜ÒÀ^¢þ©›’X.iŒôpùÔŒ·’5ó/F¸ ƒ„ŽÀAnýxé3fÇx%‘e"gVu3 W()ù´ß'@I©"1ð€€ÖJ¢DC iíèèH6Á­-µEní©Ï…*–ÂE!HE¸7)—S9 Æz¨Þ? ²U² ”†€j]È/4·”&1¤ ½”xæ3D‰ÿmbñï¬$2å\ÿóFŽ à!5ý<$à&8–ýØUW]5½¶¶v–)êö¡çRYÛŒ9€©zˆ\¾ÕÍd-ÿ,Ks(H®ÿ{¢C;ü/RZüc>ÿÑ#G¨ŽsÈZñ ~;äqÆ Á# ZI4»÷Ycö‰v ÉÈ‹l})v¹ÏÉqèB˜nØîŠÐûÖgœ1+‹U¹/ôs_–ù#88â_ÌB" (‹b+>Io-2!Ü 4ööÿ%{óƒþ›ñï?säh„€j?Íéå'€üÈF ÀZ)Ý`ªz_áZï>í(’s¬u¥;ö.sŸRŽ‚À]!z_ÊeuvvÎö‰cÎlÔ¡WRç“hýÏ 'ÇL@ͽŒ¨iù˜ïà 'п›’Ïý“ÿFªT·´üû9"À«æXËþ–_ëå•@ PÒšiPC2.­!=É&h}éŽ YVšlþ  þëí®½oMš4iVi0#•Äa¢¾­Î©1-&´‡ý¸%pTó|²º® œ]0@ xÉuŸ':ÒS|BcIAz­ü8– 3\ j2O¢»ô(%×}‰û'#Q&¢@@4“-󦋆-«1R¬´†€Ö•îXl’ãЊ;)X؃T€]1Ú[C<‰Ã¬ÔGþÿ¯úžçLÓ?*XÐÿ ˆZޱ8·XðØEç1ZáP(oöæ’½ë>CPd-ù Ä¿ÏÔ‘]p¨©<'À¢÷Ç X À¢_¯š–$uØÜ<. ©u¥Ö™RKZ{†¶ÆÂêЕ +À}ìì/_¾¼'q˜i¬f¯Oemóüé -ŒÙ‚ŒCO@͹‚¨Væ#Aˆéúÿ¿ù^$Y]M;ß÷|‘!‰€šq ©¹üûŠ  ¢™D;Iè37€hHÑ’lÅ0騖y>}*Á.€@¸ 8³þïøƒ¯…PSy´Üõ@`€µèä&¯<Æ€€Aií4¨¥ ™’Ö’Ž®dÜZSﲬølÃ<  Àw]N<}útñÚ ª÷u'oå¬iiÌ drªãD¢æ•!/ÌF`à%Ÿÿg_§R­‹xr‡;…@IDATâ3žô@ ‹Ï‰q̧)Ù÷~²÷mÈú ‡ ~í$³ë‰–’ØTHkÉ }™e‹|fÒÄ,sFÅNE577Ï=†_™8ȳ9ïM%Š!%†[FÉY1²ÞPFFQA |$7|Ç7î÷¯Àu“ÉZùwüFf¿¿¸S°ªÉ:öv¢š‰eXxD@k'ÑR¢© …´–Ìv¸ YV|¶athðºôúXwÑXñìÆêð )Û’˜PWâ±PÓÏ ªž2öq€@° t¿@öëÿퟕµ[Åâ¿r‚y"'#xkú»bfé±0"ƒÍ Pr2 h(ê°¬ªf&¤µ¤èÌ ÉÇrN­Cõq(b)PXƒ>,^µjU}MM1€­ÒýÆCÀªä‰‰®ϸ@ à’ÏýwLúc¥²(¶‚»ý×Íò'?äa'Ð0——ÝýÛ°—öƒ@¸ ¤5”}ø%cå-)š’ ¦5]çŒÙWLÆav¸Ëí®ë /ìŒÇã-î üÜ·úÒ+$ÑÕÒOîQÊKÍàÖÿ*c‹XD %Ê"`oûÙ{ý{¡Q ßC4ñ¤@1€1 tª}-/xiÐÍ„} ]i 5¨© ”T´¤hJÎZô²[k°¦´Y†Ùà®÷¾µ`Á£ ¦Û½¯:µäLXÚúBjå@€[쬙—•CIQF(/É>J®¿Ó·2«É'ðß,!êpd)ÖÜëHMZ©2¡0 ZCiMeÊî´¦Ìv¸u§)ÓŠÊ7¬MÔ^‚»dß© ÎÎN£ux£c „oÊ|üo†€j?ž¨Öè#l¦àÈ5DxÒÛþ=<Ùé>¢n^Ǿ‡ìÄ!ž¬§Ÿc^Ó>O÷vUÁ=éT%ÿ㸢–Ǥ7ñ˜[Š7óùèÿ½L¾z/Oü—ž ÖëÚ®kçnÌ·z ÒH•¿‡èðîH—…ÀHO(šÊä4ûiM9¨1™“[{ 696i¢Ø0ææ7..Á]Îþ„ Ì©§ü2Ì3;Ëv˜ñ¦àâÿ X3/ö?SänöÑ¡×Éîá­w¿ün!êÝAvß.ýü7®¿‡¯ûï]Á;âuì˜@ªšgà®m癸;HÕòV?“ǯw±{7î¶0|ûý»È~õ>ìæ9Db+?ÇNfŠ 0~•<‡Æ§(ñØßð¤d‰ñ§ƒ;AÆFÀ–‰ÔyM%ÚªÂÌ$¶iM9Lk¦ £µèØÊ€«Ã¦PÝ øÜǃûuuuƪÿ•Tµ:“W|Ý @õÄÀ¨ë jY8³`P„ È2;Ÿ§äþõDݯÝý‹ý¶Ï/»GØ©À›ÝÃΆtú ÊU^šK5ðŸö sI5. Õ´˜çɘ¤/ |œ|ù.~‰éóÅNkÉõD<‘€@ 4-!µà=d?ÿ$†$@FM Á2µ"A¢­ìŠ•£¾­”¦5å Æä´Ýû’•>–ý¡×9 p›ÀÒ \ï+ž°AqeMs_èë~_Ú€ }Å•ÌÔô³¢R”#¨z^æIèþHöÞöódt‡wÕR—]6jÛx3«@¿¹iøƒqkkë”ñÂ(Å}ªo»ª¸õ_V@ÑPŠTû©£½×@Š@ßVJnþÙ[~MÔ³T èï&{ã/)ÁÕ´’ê8…¬r(Õ+àµñÄÇ‘Õu ëcÆmqòÕ{½oý¯n&k>ºþ»’p#AÀZÌCv?Ã+«ô‘ n(D@4•£¨lä!{2ÿÁ¥-‡éNÿ­)MŽa¨ž _[\pÁ¤ÊÊJc=l=`+”æñ,“T ‹eB©üйÿO”|ò&JùÄN˳3¹_)ÓFZÅ8ðjÊð·öíy¼pZ<¬½ég…¯)öS«‚¬E7› î(kñùÍ4Œ¯Ó%(<’¯ Ȫj¬­ìþm^çT0ý´Æ”/z>Zðþ }X4ƒFi†ïŽiÊ”)FªŸ{$Œu@%:\4ªqnÐL‚=~èÛFÉþ…»Œ?ņbî?é+¯ý(ñØGxŽ€d-äî÷õ]Ãì³7ÿ7ÑÑÞaçKyBÍâå K1Qa)BZ P®摚q/3ú‹r%€rƒ€·X[)v˜|CriL·öÔûޖ߃ÔÃäȆ¬ã &´{ÀhôIÙÇÝ>Å`ò½¹¸2TÜ`+ü%ì£äËß"û•ðß#þæÜŠ"`óà‰]×:/ýÖ¼÷Å›ÓK¾þ#Þ÷ð7 Š'þ›sÍ`~Ø0OÀšw%¶²÷è!óÆÀˆÑV¢± †´ÆÔœlŠÞ×Véc_tVÅÇaé³$PuЀåXï;Ÿ744˜s ìçw>~‰Çø]OˆGK€[Ê‹€½í”øíedoøwˆÿ°V½à¿ŸSâË9þ.ÿæï}‚¨{“§%²æ_9C<%ŒÄA`â-¤æ\6Žq €ÀˆD[‰Æ­e(¸4f†ödsô±¶ÌѤú ¨q˜zd3ÔÀ%v555ÆêèfÇ>…²ë Ç…Ä0‹w!>Qû¬÷ J®ûÙ»ÿµ’•oyŽöPòÙ¯½ñ3R±¸·&Ì&5»ÿ#€Ž€5ërJlü)Q¯Ù±Êƒ@ H¢­¤Y]´–]1Ôã®ÈdÇt»Kcºç…ØÏUаôж»Eö>UWWË f‘-©|ÑÀ ÿ°æZÓVËa÷Xpkqòå»(ñ»«!þÇÂ-L×òDöÞ<µ86ÿ¯=M‰ƒA@ñäœ ÿªˆp+€@NZ[i­•ó"oOº4f¶þt{kD SSìúØÊ)§4ñ:ÆzØG¶:}@(É>•PŒþp£Ä¾)ªÖ輕¦Š]^ùö¼F‰g>K´ÿåò*7J[RªeQÛ‰%M‰”–€š|:Qã=D6–6a¤åL@´ÑZ¦‚hLÑš>øà¶Á­AÝ&ÉùP¨À°õÈ× Þ9^³fÍ$^¦Ñãþ—’}î` .¨MË}΂@ø„ŒCD‰€MÉWî¦Äƒ×BüG©Z •ÅZð åŒlAÆBÀšwõX.ǵ #°Y[ÙÜæ?ÝÛz¤ë=ø\4¦hMNÚÑéXrÒDzš6€@– aÆsæÌ1Ú—Ú–‡K¦jÿžÏèAý»(ùØûÈ^7Oòw4‚D‘ü$ ÚŽ!jYég–È @`œTûiDMsÆy7nÈI a‘-­CZkjO6Eï‹U²š6€€Õ€5t'noo7ê ^Ÿ2µ`hꆀ€ªh €0¡”ì¿á±þWñXÿçJ™,Ò*[ЬùוméQp#z„±Ú`s È$ë}fi­™¡?ÓÈ´6 2Á ÛÂ2€¶@ƒÖçiâĉFJÖ§d@Eí˜.ÇÅ& ý­ÿG²_ý Š!`† Ó45i9·&.Ö‡ˆAÂ@`ÒÉ©^˜û% µÃ@€5–:ºßèÛ•KkêOF—­Iå8ð/aP¬¬~<5ôŒ¸®®n¢¾ÀH<ÐC*ŠBÈ4«*×Yœ þÝÜåÿ½,þÌ–þï~Øè–µ½V×e]~ÂJÀšû—a5vƒ@à8‹µ–ÉÖšú“íÑÇnÓä\ Cùj¸N\__oÎ`÷ñ;?zä«)œÏOÀܼ•ùmÂ'c#°ïžè—÷Ûãípc3 WG‚À„ÙD­ÇG¢((”Õþf¢º)åVl”¼! ½¬Ek‰æ2\Z3Cƒ2§¨lÃÔd-°ómÇ[‹"QÌÍGw¦î¶y| Bù¨i#Õ0¨–WŸtfóçÇ39@tä Qïf²nâýîòáQ†%µ7ÿ„’þÇT½G½üŠ|ãõ¼5’Š7Uò ¼O1îÅ¢øÙ¯¨Ë$àj™QÇG»ù·{?QÿÞ8Æäˆ™¼rYsÐúŸ N@hX]óoÄ—Cc/ ÀÐK4W|†3]Z3Ÿ•ó¡aqäª+€ª««õPGvpe³)Î:•èþŠ'\Fòø£Ö¤¦¾•TÛID5“GN…×€Onÿ Ù[KtpãÈ×ãŠÐH®ÿ2Ù¯ü€íØw¾f";¶:‰f“ª›Jª†[°j§òƱ*áOÆ@/Oè³ìž×É>ÄβžM¼¿™èOò#N´rµ¤:N/w (?„š€šv.Ñ wãoZ¨kÆ‚€£±‰æ² 9\ZsPæ`#ŸþŰ„os9”þ”ž777[.¯Lés)Å=|ZÿGÂôÿ³w&ðu\Õý?3O»,Ë–÷}‰í8‹ãì d_ $¡ÐÒ–²ü ÿ–öÏò§eß )´„–å--…¦@ JB[ eÉFö8‰cÇñ’x‘÷MÞeË’ÞÜÿ9ÏïÊWã'éIzoî½3¿ûùŒî̼™{ÎýÞ‘ô~gîâïç,üg\I…ñ|c ¯cæQ¸àD²íy‚¢—¾Cjß Ã+W»E@õPôÌ'Ií|Ô-¿Fâ ¿ÅÚósK(Ï͵,â7û ­L!`Ž9Ùâ¾ÝNêàó¤ö¯.ltp#X¹GA†RxÚë¹¶§ÉTR@ l `î-¤Öýk *ƒ*€€m¬µ šËŽ¢5Esîß¿¿Ÿeoô±ÇF`Õ§€ùMHƒ.ä×\sM[m­ôGµ“TÏ. òØ¡_e«cçRîœòl¾çŒÞФK)äMíüE+¿r¢toçèËE ÉànìÑÓä Ž§Küq7ý`â9L¾„{³\ÈãSùM¿‹‰{²M»é„w¼Â힢½OÚ½ŒèÀz>¹èye|ʱh˜qkeÊB) V „sßHù—ïá?YÝVý€qðžk-¥‡][¨ŒhMÑœ?þñeì·©Eµ7¦VÕçœÌ} @ »̳Î:k|¿Iôìåq®I…½jæÝJá™ïã§®¶¢¦‚©×S®íBŠžû$ J$OßMù'þœèp»'ÝlœBÁôË)œÂÃVÆŸÏϳ‡ÁJñ¹í| y#î¤@=II0`çü=ÅíM T‡!˜q5Ï©À=$@ü'PׯÁÌËHm{Èÿº  `“€h­ž=6= ќŀéGI}j^àÚ¾€8T}Ü—Ï;·Í&Ø kå/¨)~!e“oâ¶ÃÂ%ï¢`Ϋgºn…•Ç;o¨ž ”\9ÇvRþñwó8u™ïÃÔ4E?[™~c:×—¡ Ón,lu‘ÚÅ€m¿:Ñ; ·ÇƒÜÅpοŸ‚xE œså·<ä•Ïpœ#ÀZK4—ÍöEÍÙ§A™‘Þ׸ô±M7µ/æ>´óT' ·óx »=º÷R x†l$ÿ „…KÿŒ‚Y¯«~]dætÿŒä8Îvÿÿ—Wv¹>N¹Z ¦\Dáœß"â¡&™I2ÆvOÌÉñÄ‚jûÏ)Úô&Àóø˜Ú¸‹C+ÏË€ mñÿûiDÞ‘ž:¡& 0ÑZªÛn€¢æì§C rÞ‹äz R¸}ûmmmãlÒzöóÛ»ÕÚ„æ¨í`ñ[“ÿŽÖnňøì½DÇöÅ>pè°y2…soåçö6^ÇêŸBûP¸Û|0û ”ã¼À€ç€Ào80àÏ‚á\nG$ÔæÜDjÕ¿¤®^¨$F€µVÐsÀjCsöéP®¿¹¯qÈ9g{¸Ðã¹@•TÈÇŒc·@žÇqçÑàD“øû3˜zÏØÿ¿ý­<¯,×ÅÿøÓøyý} ¦ò›oéM‚ÔŸÀ¸³)<÷l¢³q à‡¼dã½¼—ãsnÔÔóÐ nO$ÔgÝJùÕßáF˜4*u‹ %C@´VÞîäÙ†æÔ_¼tž ƒ Yñ% pÍMªßœ×e´ûÚK& Rjc…@m3‹ž” „@aÌÿŸ9ùæ?˜ÌKö-z;OŠÇ³ø# M€—5 þÑio!µéŠ6ü»³Ã9d¢0â! H )$PÇs³L¹ÔŽ'SX9T   ¸·uþX†6ÓœZ‹šUŸ¸>ñ%GÕtSSSkü‚Dy*ÊcÆæD™WØXxú[¸ûô„ —Šâ¼$н»ýó„GíŽ3;…݄Ŕ[ÌBvÂŧ|„e¹æ¿…ró~Ôæ{)Z÷]ð(ãÆä. g¼:9c° 8`æ«Hœ: ¦†@žåŸ²;¤¯¨9ûéPùúÐoÝŒ¤˜À…·«ºº:{%ËOi·Ä%$ï4ò=óª8ã¿w@2ìpo'/õ÷>^Á¡Ùþ[gSîÒ¿¦Ü+¿ ñ_‰G“—õ”>r×ÜMÁéoæåöê+Qêè˨çc“^1úrP€€³‚)WբǨ³ Ç'ÀzKɰz{Ë®5§8!âO’úXŸ+|èêš VÃ-œãÆ«/J<— ©.q³0X9Á¼Ûø×·¶r¢$? ¨Šžú ;³Ç×),G™»ò.¢ÉWøÉÔe¯k)<ý”»îàåyùO›)˜yÿŠÿ›³élƒTœ@XÇó¶ WŹ¢À `ÍÕk¯÷ž¡9åvüŸvüØÙv±û§|,¨†­óB Fc”_b¥®Œø!Ä€•¢™|9ü¥?œuKòvaÑ9ÑsŸ&µw¥}¿ø™ æÞÌÂô‡pwu °ÂHU¥~"/ýù Ê]þDãæWÕÔ`…‡Ó9 zÁôëR_GTªF@4WÞ‰€TQëQësU«~¥ öu].ÉÚ€ ÷÷D‘8г+=áÇÆŸNT?i€q:+¢µÿDjëCö«Û2‹rç~„hüRû¾d̓qgRîŠo“Úø=ŠÖÜÅoœh¨‘²NÖˆ£¾ IÁÄËO è9šÉú£Ò 0*¬¹‚Þƒ¤ìÞÓšSkÐQUÇÖÍ¢\}I´ä}Ûœ9s¸@]‹µJä9‡ø·Æ”†ƒ ç²Üî;µíg¤Ö~Ïn5B—¾ø(w5OLño¯-¸ ~a¢ÀkïâÙºÏOÌ`Ê%‰Ù‚!Ërü÷~ †Xn˜÷•€h®üAkÞ‹æíÉôiÑâ¾ø¤µªì;\ï ájˆ&ØÂþ¹çžÛ’Ëåì Âx]é^žŒ1ÝF^åÁøÅ^ù g+LàÀ*Š–-þ·Ì¤ÜŸæ~Lx+ܺ#/®a…—|•Tû(záü7¾{äe•qg8õÊ2®Â% i!L»ŠÔ–ÓRÔ’# šËâ¢9E{¶··Ër§èÒ"­_-~¹¼I|é AJmúísÆÞÛvFuï¡s þ”9üi0æ4‡½ƒkU%Ð}€òË>Quq7`ämó¼›(wõ·!þ„d÷ƒ`ÎïQî*^}aÜÜê9"3‚O¸¬zå£dç²âGÎõwpÎaƒC PÐ\ªÇîJMEí©Å?]ÊM¤Ï;ÝZ¾4D µöÌ™3›õ‡6ò°‡'¢Èû†Ñ)Gmò`H$Àoü£eçåþöØ©¼ÌðñížÃ>ðúôHà aîÊoQ°àõüo]ÿ ªœ¿Á$jÀ]‚‘@2D †¿ºŽ_”¡ £ª P!¬¹Â{C¤†öìÓ£|ºò_*„¬T1.+×@šçƒ &Œ)U±¤Î) (Ó¥¤,ÃNEÔ4U¤âhí×HíyÞŽÓü69wå7y)¨kíØ‡ÕáàeBóþœƒ6ŸâÉ»*û7#˜zéðýÁ Þ&_ä}PHœk.UX‚=qË}‹ÚÓæ~ßu¼3Ðyó+û.L ЄØwÜÔÔdµåpÀŒ&Rìƒ@F ìy’Ôº»­T>˜uÏ4ÿÏDͳ¬Ø‡ÑѦ^ÏÁž`ÌôÑdÜLBÀÀ]È p2¯€ 0<…e\¥§„w†öìÓ£ÅËâÇ%îvã”Ê5.ü5¹Âù––»€ÞN Ð-âcÞ‹ex|l¶û,ãþŸý íx™$wÏz;…çÿºü'ɽ¶ÆHŽ;yïsG_zó"žp @ ƒZÏàßÿq¬8ª £ ½®E{YL†öT£ZtqHÓ>â•Øx0fÌËŽB9;ÇcŽO!p|ï)§p"½¢ç¸ wÛI2ñ"%áEŸà1äoOÒ*lU“@m ¯ðwÌ}õ¨¬“*D•¸@À&ü °I¶½$±Œì¾¼+jÏ>-Êõ¾7H} h¸Ø •©K/3T/_é]»—Y»ô_¦Ž¬O%QÃÕþ#R;ŸI–FÝXʽâ L»1Y»°V}Ò«cé'(<óGl+˜xÁˆïÅ þ&,õ¿¨$I@zäóIZ<Å–¡=½€®4XÉã[¡Ajke %›)gÓ8l’€Úÿâ(KÀí^8º×sÿ§d]mhã®âÿHÔÆ³¼#¥–@°ðž÷güjøÿN1þ?µ*eÚÎ+ë:\ p’@@ ãÈñKˆv=›‘Ê¢š P vu—¡=ûôh±V¦V­DE«V†/€ær9»yí>‡U{8²Rp´þ'”;í­üæ®6+UÎL=£_ ê>’L}yÌ¿¼ù‡øO†·£V‚©×ñp ð°5ðDEÁø³­ÜH’@8q)åñ=2Iä°å;Ë¿0ChÏ5«KØ}`òÒ‘+ŽÂÔ›$¾_è¸U¬$c¤6þ°’%¢,ì~„Ô¶ß$ã ¯å\óß85{°â4`Úõʼnør°q,z8݈p’"Њ``R¨a'%,(jO Ûi=ªsoû8l†ö{œâNøF Zs¿)îðÍmø;~óš_ùw}ZÙóµM”»Œ{`¿Êrõ¼´`öoQxÖC‹Æòü9ô8ò¼‰á>T†@ OØ<©2e¡È‚ë Õݺö¬@=]Ä£)fk÷}ÆÝ0ê*ÀaäED#¿w:D »“¢gÿÒ!‡àÊh¨ ÿJtxëhŠ(ïÞ G¹‹xâ·Ö3Ê»WeŠ@°à)˜ÿšSê´Î;åN€d—@Ð2'»•GÍA`¸z^7Ü¢Fr½¡=ûôh±œ’Zu$6ª}Ë]w¦œëwÌQ»€AÆxê ÷ƒ€Ú¹ŒÔKßôÃYx90î­ùîÀŸWð“ðÜwM¾¢‚%¢¨´—|”‚iö«VÐ2¿ß1@2N`,þ&dü @õ‡CÀò€Ú³Ÿ6åªÄ‡S»D®õ! 4H÷Á1¢0}çÝA€DqWÛX´ê;¤6ß[m3(¿Š¢µß ê9ZE 'оž‚9o¬ºðœ@PxÁ_µÌ8YN²À€c€€@¹Tw¹WV庴§Ö¨:¯ŠíJêK ^_+›*…‰_[ÝcLX]¾‰—γw?÷%žðîÄ-Ã`ÝÆm÷Ó 4D“–PxæŸq>"ã›»äsDµ…AËi@ }‚ÖÓûö± 0Èî²EíiN8„Ãî}ìS@GTt^ –×n‹ÐÀ½Çz”©ˆ¢ç¿BÑŠ;†\Ë{”–p{… D/þQÔ[áRcÅÉrñ]~³‹es…瘨†ç­mš^öm¸@ ÆÌãÿ)¹ TU °¼ ` í©¿ê¼•¬n5Õ-~Ä¥— °D#ŒØ(n“€ÚðŸ”ïxrç~hüRó#ì»Hàðˤ¶>T]Ïxù¶ÜÅŸ%ªk«®”žJÁ´xy@»o.R •ß ˆøoš@Ô¹Û÷šÀH€@Ù2±*¾ S{гÎýã÷©€4¢nqÉ ûÜvƒ í’Þtp#åzEË>γʿœÞz¦ fÑ™À±ºcÃ3ÿÁ <+6«Ìx•Mó°  à*ÆÉ®z¿@À)Ao•{zQ[C{öéQ¾¥ K‡¸Õ™íŠç `0¡¥ ¿ˆ !çæÛŠß,?Hyy»<ñ gÝHÁäˉ§úV‘ôúÛÙNjÛcխߤs(Xð¶êÚ@é  ™$4O#µ÷…LÖ•á°»  mí9–‚š&"î"Ž”‹ësex¯=} ”Œ°DQä}#dñwu' Ô6R¸àmNº§@@RN טò ¢z P5u(däE ¢=KjÕ‘[ªÞ¾jw1ˆÀ„Õ{ˆP2¤…@xÚëˆjÑ3-í‰z€€€W,¯lí+8 ö ¦=Ó¬ö<ŽYöM½–‚šÕ)ÙÚúdíÁ€@uÔ5S°à­Õ)¥‚€€ÀPjš‡ºŸƒØ'PJ{–Ò¨ö=ÀƒšÎûr:à‰J5BrþK ƒ’ã K P%áü[ðö¿JlQ,€€@™ð²LP¸,³{ÿž”¢öôJðDZø ë€QüµŽ?X8¯äj)˜ÿ&¯\†³  )#À«Ðà­RÊÚÕ©<þÎf3¹¡=GGÀå!CEV Ÿs#ôŽÁ(ïÎyC%Üþf_CT?ÁÿŠ   ÞB»ÂÆ[pp<[,ÿžÚ³,­êbã¸(‹—Ñe]_ñ‹,?„¯ Ìxæÿ7g®Ö¨0€€€øGÀnÏkëÚ³ ær`¨Ö•Ïe€ž p@ Y%0ùl¢–Y­=ê     P&¢ö”·ÿåhÕ2KMö2—e‘°PèPV;á"p•@8÷6W]ƒ_    ÛÚ˶ö4PŒx×û@EÝ#®}%nÌÕU¢” `ƒ@Ý ¦Ý`Ã2l‚€€€ —€eíe]{—W‰ë} Ä»Zù|Þn Ä$€%ž+œ/³¯'²<›¬ à$€€@Õ ¨ÞãU· à=\ƒÕ*µg|À¸FµêãPÆ} Õz&D€¡2|®çÜêªkð @@ k,wjÍnÔ×SÝ—¯ChÏ5«K´} ³R@í÷ÀÛC—žgøåh™NÔº¸üëq%€€T“@ï±j–޲A j›¬Öc€âS)­jÕ׌û(YŽÂt•ü ©“èiØŠg\YÑòP€€ŒŠ@ÞîWÚQùŽ›A )–_¾Zמàìk@GX‚Þ^Ë¦ÂÆ 4ŠHš@0ãUI›„=˜z ÌŸ€€&Öë=+yQ{ê9´&µâËHÚD1R¯û¸†Õp©ª©§ 2Â.€€ûZ¦¡û¿û­A@ ST÷"|§ÌT›£²Ã' rv_¾ÚÖžÃ'vê¾öš".…± »3QžÚ¤8 0`Ú%C]‚ÏA@@ Y=@œ€åØ íéåÛëcvÐÝÝ}tð§¤ÊŸæd" Ó¥*ÛCñ £&L¹lÔe ¨(îÃ\¾SV”) K»“µ§ п¬:÷†µÏ= ¹ìN™ŠÞ<ìp dØÎ$ôÀÓ  àã@”@ÎîÖµç pÊûз@<ÂôôôØ z”W8@`âYDX½Ã†€  }º÷ñøLÐÇ; 0Ë“µ§žP{רú¼“¹ë€`öïêê²:@Yî†âäS§@ÀaáÄ¥{×@@2IàØîLV•ájÇ ÷–Š^Óž}š4fd ó±Ëìº0©ÄAÊqpäÈ‘Nó¢Ä÷k›7 ƒ #'L:oä7ãN¨ulWJE‘ >‘eíUÔžær\«êóÎå>¦ ÔܧÇÛ Ô´8רp@`¹Ñxô€Nƒ€Ø"pt»-˰ ~°¬½JhOS›Æu«“l}\À=zÔj ¨EÀl샀ÓZçaü¿Ó ç@ÀÅßÙŽíàm©NÎî %]²yVvÕ}¨“¬Ñ.‹´÷ðêÃ*6V»–—øŠÌ/RÇß x êÇQP×JÔ8‰¨i:Í3ˆšgÕŽµTI˜uš†8Ýcr¾ˆhÜ™NÆ9eì¸xÊXQ]Ë/_ íiþ™×uDUJú&W±¬ÈÊÖ­[­öPˆä'ýÌÂŒ˜@кpÄ÷âFO ^Oj÷ã¤:^ µo ÑËc­¥'ÁÞIɦ‘æøë÷P '.!špΉ¥JëÆéO‘g€€:¼%µDA`ôlk¯ajϾ?ó£¯yåJp5Pª† Îåš ½½ÝuèÊWª±p\$´ò›6$tèánû;$µëIR{žãîü¼¼šë)ßK´ï%Šx#ú1oü¤m>…S/¡`êåÁy“@]íUÔžæd­Munzëä¾O .@^¾|ùá|>ßËåxàÄcþj›x|à©Ýÿlx› /Ïc€Nƒ€ßŽwÚöKж=D´g%wçÏû]ùŠÓ±ž"ÞhÕ¿5Œ¥`ú+(œu=ѤW àyëžâ~÷|< N€@ u¬¹B{sØ‹æíÉžñ¬Ò-êè7iúÐpuÞWŽÂôtwwnllœÐw2éχ@ÒÔa†G ™'âªáH é uŸýí?%ÚÉcúãó¥£–'jÑuˆÔ†ÿ¦ç01S@ ®£hÃHm~0›Á÷ã xùg”çÆó¼s_CÁœ[±º€Ç϶:°Ž½7¿Þz\¸U$ šËrÍ)ÚÓü…5÷Žø±œs*¹x&Àø¾>8sˆ{Ø+Kþ 8M hBÀé‚s 0^¦Omç.þ/ý»ø¯ìÊl}¶#Eûÿžhå7)˜{=… ßÌÁÎyÙb‚ÚªC<Ô @`h–5—hNvR’ÊÕª'®vè§Ë€r0 øB œ‹«vM-¯ó‹ à4 išÓþÁ9Tw}¿‡¢u,ümÏÞ_Â=gNõç^?¥üúŸM»r‹ÞÂs\äŒ{pdpêÀ†Á/À§ 'XÖ\F@¿ˆö²e| èH‹Îº¤;†µ¤Æ÷…‚¬9à ƒhž1øçø@ÀQ©õ?8zô¨ÕÕb­Þ²Ÿ8\–Í` =Ì‚@ùTžÔƧhÕ·‰ºäu÷677Ï×%ž7N*º“¸e÷ìòñ$s{Ýó  L ê¥hù×(èXAáEÉËò$ªH' v=ÎA±Þá—ÛØFá¼›Oܧøþ<¯¦‘ç¼û ©ã‡xRGÞxŸºxSæJeÃ7…;@À)M¢µì%Ñšl]^žký©1µ©>'ù@çÍk¬ì»(DƒÔàuÚî &•ŒV”ªÎ€€@š ¨ö{)zæKD¼ì’ŸÔ–ßPþÐÛ(w9·có,?+á°×jçc#ð. ðâS0åò~÷–z[Fª‡ƒo[IñFG¶ZOÑ DÛ1gU?z8ð…€j°»êZQkš­C¡Ö¨^àô%lB–ýàÈ‘#v_14Ú}(½xÚà$Ø"ÐÃK-!$B@­ø"EkîNÄŒT™ÀÁÍ”ÿõ;(÷ÊÏM8¯ÊƲU¼ÚÅ3…‹n=EüXDPK4f¼Ñ”Wõ-†Û¹…TÇrR{ž#µw8@ 0Dg@–øÀ –µVQkJ¼-®Cõ±äzß fxáz Ò„j~vvÚíc¨§€§A¬PæŸëÞÀH'~ã=õ Rí¦³~Y­w%Ï?ô^ð f½&«*[ïƒ<öÿÈ®á•Ù:›‚s>0¼{ºš{t²Í¾åÄ2|`×oHíxŒ/ I]ºçAÀÛZ«¨5ã=4󋦩QõçNå®LX¬†jæáÞ½{­®+4N3}Å>€€Kz»\ò¾€@ºp€Míx¢µß%ÚÃo‘ÒG€‡rD†Âc,zkúê—pÔöû‡g1¬¥Ü%·óèãºáÝWîÕu­Üyma+ܲïyR›N¡cv;Ø–[\—~¢µ´´QÛ¢Ö”2¹†©Cµ[:·áÞ°lú(U1 ?صk—Õ€jš^Ê?œp@$«‘@*N€ÅôÔ‡ù­ÿC/ºF€Ûš' {Sp&/éˆ4bѶ‡‡uoxþ{‰Æ9¬{FuqÛR xËû^©à9Š6þ„Ô–‰zŽªXÜ £!`[kµ¦´þMu¬ÞëK@GT4p <Ù^~ùe«€Â,¹µÍüDZÓjƒÂ8€@ 2€ äï6€@¥DO} â¿R0=)'zá. »QpîG=ñØ17í&Ú·¡l§‚9WS0ÿe__ñ yî‡Pæ8—WØü_m¸—ý__q3(% ËòŠ$E­©â®Ö£:×ç­Š Ê8_’À5“†-yðÈ#ìÎçóV§VLÿ° à þ3ÑÝáŒ7pÒ@@-»Åÿ0»2§¡â¨Eëî#õÜg@bÔæÿä»â_i(hìL /øÔ&|º¦‘¿C¹ëÿr×}hÆ%ì‚ê ·BfÍÙÖX¢1EkzùÖ›Ù&eþb›·ØÙ÷!`ÂÔ°õ9ÓÃ?|¸§§g˜3ªTz&Šâ@ r Ë·V®8”Y& â?Úð³,#È|Ý£—þ‹ÔŠ/džÃpD[Ê šÕ6Rî²;¬¿õ,Y¿ òÊ_¥ÜMß§`Þ«8+yN‚@Å4M¬XQ#)H4¦hMã^­AãÚT.ÑŸ—»µëË€85¶Þ»ººv744X[¬V5M¦Àù&£Ä1dƒ€êÚCAëâlTµ*PË>MÑúŸWÑŠö…@´ú ù-ppÎû}qÙ®ŸGÚyLýËCûÀÃÕ‹?IÔºpèkm^Ñ2W‡àž g¼ƒ¢UÿÄ=‚`éƒ/Â6›$­¶UÃ$«UÉÄWÐÔªo#1îC©—¬s}Nçr>|Øj@5ψû‰cWµúçÁ ðFLâÄèRcô<¿ýÝ‚!!C5t´é†º„hÖå¼ÊŸ}‹W´.¢Ü•_§ð ºÐ‚—b.6‘¯>ÙÖXEiL-êV×®kFVô¾ÎÃZý†4ÍÔ~"pŒ€:¼Å1àøCâߟ¶²â©,ùä_íyÊŠy/Œîy’h¨÷TRîâÏzQÁœ ¦_Ãóððsþ(çëhãÁjˆÏ’&`[c5f< uªÖ¢&ý™yΙ}Ÿ~+M´™‡Û·oßi“¬j–éL7mzÛ &ud«yˆ}2 œÿx»[&®ì^–ï¡ü#¡Ü ß"3'»¨y´ñ'üÉ ßùyð¤”àÙé –‚3þ„r3o¤üÓ·spèEÏ*w]"pBcÙó¨¨1eÙ‹ˆ7ùE67íØ ¿àú7r×{% XÓÇñ<ܸq£ÕÕµÕÑ~"p‰Àá.y_@À ÿ^4“;Nvá OØ{ÔŸ\ð¤ç0©Í¿Ø“ú±ÜužÅ} W“â‰s×~›ÂóÞýêf€O@` uͬ¯XcYLEYª€Ö£Ú»ø±>ïTîCÀV ª><þøã;yƼyCÒû²€€ƒŽuð—Òc:—@ÀMÿn¶‹ó^ÜLù'?æ¼›I:¨6ý˜(¼´É\=¿ùç1ó<‘^šS°è-'z‡´¦»žinC[uSMSl™.Øm)“¤€Ö¦O¥Î™Ÿ;·ïS@àê¤A›9Ýwß}¼Nãv}‘•|Ìt+fa@  G6–q.€øÇ30*[#µúë£*"M7G/ßWº:a-…—óÜ .,ýyÚÎò²†¹þ•ÂE·¥­f¨O5 Œ±;¡¤hKјÅ*šÚSïëÚ˱ɧ€Õ ÍÜ<Ÿëìì´ÚÏWÁD€^<ùp2“TÇŠLÖ•á€ø-\;håwxÜ÷²>ÎÌyµëQ¢CÛN˜š›@IDAT­oRxÙ_P0õÊS?Kó™Ï pÞǹîŸä!õi®)êV!jŒÌ±f/µeŽ=ÐúSœÑûfnÏÉaZö% pK%ºì‡]]]v{4Ï.å'θ@`ÿj¼€ à,µüo(Z ÿœm ŸSyÊ?ñ)¢îƒ>y]q_£uß/Qf@áE¢€'ÈËj fßB¹ë¿ÉCìvïÎ*Ÿê&Y·çqQ[ŠfŽëÎRNÉ5Î'_2½Ôqnÿþýv-sœot8Y%u¬ÍjÕQo’€zþ ­ýÑ×á(›ÀÑ=<ü§Ê¾v>ƒ‡ãó€ïM<#ƒ•G•Ë% Zæ–{iU®+jK³@) ªÏUŇJêS ^w-I—<ìèè°PÍsÅ'$ ðäTu»è|« âÍÝV}€ñ”ù6f3°¤Öð0ˆÂ×TݶEñ¿àô ä<»{îÚ&šuX€@I¶µUQ[Æ{ˆ¯Z‹–ôÛå“5.;WôMàʬ‹:™‚?¾lÞ¼¹Ä@+}k¹,SQÏ[W¶»¼%@&@`øT/ÑþU<áÒyÿw€@J Äÿjˆÿ”6¯ÕŠ–ÿå¦^EÔ8É qâxE›~}R"ȘÿK>BÁÜ×%bÞ+#A-å^ñERËï h ¯˜€š@k*ËKµ¥¹@\ʱ™âÇægNìûÒÀ-à4Xó¼ì‡¼LƒÝ€8ׂ‰¥‘@ÀEjד.ºŸ@À ˆ+سgôøÊ/ûËLÕ[­ù/ý×s¢Îÿeµ}pîG(\ú޲®ÅEÙ à‚¦*jËxS‹Jc˜šÔùÆñ%`‚4›°#¾(øîw¿»'k°Pcçšþb@À!ÑΧò®€€=ÿöØgÒò¶'ImþlT½ûE/ëš«ã¥þ>Kxó_^Óg¼“Âóþ¤ßßònÅU)$`[S‰¦mÉh¥€hMS{ššÔ+ú¾LÐñ(www×òr [­¶BË<«æa@`2`ï±A.ÀG ~ÿéock=÷5þûÛé¢kõI­½‹ëÙÅ]—›(wõ—(˜q}EËO{aÁéoç‰ÿoÚ«‰ú•CÀ²¦M)Ú’]-©;‹ç¥&Z£Ê¾óÉ·€Õ `îës™Éqcm‘m%Õ2ß–iØŠwÉT{ã³2u>ô€øOO[zW“cûI½ÀA€4§žCüöŸÇ±7ŒãÉíþ‘hÒÅi®mÕêðD‰P5¼Þl[S5¥¬0ØÛ¯Ä¿4¾“ê‡4Wkñ¯óÜÁƒ­¨uû¬ÝÓî#p†ÀŽG‰¦^éŒ;p’"pBüÿ0)s°§ˆÖÝK¹Óx ¼–§|–†êÅoðd‡)wÕW‰š¦§¡JÖêPÐ}„¢Õ?°æ [&ÐršUŠšRZgê\üŠ‹½ø±Uß3î[ }°C´û‰Üèø-Ç÷Rî•_!ªeá‚T1ÁEŸâ^{X¾·b@=)HµÌ²îiQSŠ^6µ¦©A­û8| h4t9Öû’ë† ï½÷Þvž°aŸ¾ÁFn{ÖJu†Mð‰€Úò ŸÜ…¯ 0bjÅ—¹ -ºý n¬ ürî"Ÿ¶4îLž+\& Gª( †+_$j]ÑbQ˜Ûlk)Ñ’¢)™’î µ¦ÖŸÐÜ×Ç’;| ÄR€õ¹~ù²e˺;¶Ù*ù–¹VÍÃ8€Àà¢- ~>P/~¢ÿ-5ARG`ßK¤¶"›ºv­V…¸WEîÊ/óÊ cªeåºFÀ²–-)š’±ôÓ™±cMM_£Î} ˜ 5äx®#3¹Ã‡y–ŤÆÚ´ÂbÕaü p˜—u=°Ú_á%Œ€@Aü¯¸swâH†@´ò›É‚•thžMá¥ÁuñU¾¤£’ª…m-UÔ’z@­1ãÚS޽K>þið¶>Ö¹4PnÿþýV$ÝÀÝÀt#! ¨õ¼T¤Ä 5U:¸‰Ô¶_§±f¨S•Ó¯¡ð¬?¨Ré(Ö)-eÏ£¢–”@)ñ¯ÓúS{‘û´  È:™Àõ¾Îs[¶li_²d‰¾6ù¼v,Ï;‰¨swò¶a@ ,Qû¯)wî‡8dX[Öõ¸| PÿÏãÍ¿muŠ2~¼e*ÑX~Ó9f˜IÔ<‚ú6ž {½Ž€H ¨ÖyÖk%Z’ÞòyÞ䦩5ã:”?ö'ù0éÆáKÃÈÞsÏ=íï~÷»÷444ðkx;I_HÁö.sc'¬‚@UDëï£Ua‹B“%ñŸ,ïYËÕM>›Âi¯ `ÆUDc推˜!oÊ÷ÚõÑÖ(Úñ$÷Ø7ä-6/ȯù.å°ÙþÙnšJáE¤è‘Oùç;<’€¿hÈkªyAWW×Ñ’l£ž7­/㺳š.TµlŸûÆR¼N9^¾|yÏÑ£G7Y Œ[\t€€³ö¬":¼‘»ÝÚ6;ËŽ9Oâßá& ù«¯aξž‚™7ò[úæê9»ïyR/ý€¢Í,þ{»ªg§Ò%o{úÄ…¦é•.奘@0ëf çŸ?n³elOba³î° >ˆ^úO¢žNŸ\†¯&ñïPãO»…ÿ·(wÅW‰ÆŸY]Çd‰¿Ç>@ÑýÜUþà–êÚ²Pz´é§¬ÂdäÎÿ0Ï棬IýÊÖAµ.¬lÃ,M´£hH¾MÐz3®5¥dýÙ0­Ø½Üçß.Iƒ—\Gi$¾ýíoïâI6ÊE¶’í‡ØV½a¼ òÜ.S–PxæïSxÙ§øO}aÁ,/\‡“Ù% Ö}—¢çïÌ.Wj>v&wõÿå®þGþgWÝ+µí×”ÿéoó„gUÝ–5Ûy2ÀžCÖÌðÇX4† ^ëqàº&`ûå©hGÑìL>ojKSsŠ»rìeòm@²n9§÷Í\¬–'qXßÒÒbm:þ /&ìƒ A@¾´Ïx%Ñ´K)e§$€žPë¾GÑ3ü¦É\=…KßAÁ¢·ò׆2AÞsKÑÚ·Wç¤,G½¤ÚJÁ^ß †I 8ç=D›îç Ò‘aÞ‰Ë]" Úɦ²íÈË&_õ¥q$ˆ!ã4d ¯lõ¼5Û}ûöý{ssó>g'í|ˆr¿ù˜Û° Y PÃoçæß@Áâ·ñ—ôyY¨1ê˜ÿv:\ÀW.¼¿mÈ׌„R¦Åÿ ÆáÜ+(xå—3©#uQþ'L z<×$yî‘Gy)ŸÏ÷š7&½¯Ú0 iæ°—2c§Sx¿•»âï°”_ÊšÕ9I OüŸ<…½¤´L¦Ü ÿBÔº0)‹}vÔ _#Úötß1vøÛöÎeÀ£",úƒQÝ›“%`{@ÑŠ¢¹Ö: õd\gêãdUКÏo&Ý:×~õ«_ÝÆ“:¬3/N|⹉›„AH\ …KÞL¹›DÁÔËSQ%TJ€ø/E%¡sãfQîÆ»ˆš¦%dÐ0³çiŠV|×8Ý=/ðû·øW=°a`Þ¤Ó‡q.µJ`‚]­$ZQ4#3}¬u¤Ö•:7yûÊ÷Iuc˜¹4˜>ÖW{øðáµcÇŽµ¶¶„jYÄãZxÞH™P @ ,²üÖeŸá¹X1„¦,^¸È[êåïS$Ýþ ÿ¾¼­†ŸŽI¹ë¿ÉkMHÞÿÞc”œWP2™4R?=<éöÁ5ü÷ß~·à~~áÀ+á‚Û(Úóy¯|Τ³µ¤ZX­ºhEv –7­M=©÷Íܪ¿£1îs]oÝr¬÷͆“ýšmÛ¶I—{) y ”A  ð¬ß£Ü«¿ñ_-\â7µñ^Šžú2WBþ…!%J e å®ãõÂmˆ®¨ZùÿˆïL´Ê>S+}r¾:H ˜Í˲¸Dr›@a®4ÖJ6SQ+ÊËqÑŽòÙÔ“ú´Öš6]µm»¤Go ó¼n´B`-§‘›«Ìj¢Ý¥-*S ”U&ÐØÊcý¿È³û€—€ò½“R•Y¡xï ÄÿãŸã¯ò¯ )Qõc)wí?Øéö/=øE«ïK´ÊÞÛ÷¢w.ÃaÇÔ4R8ó2Çœ‚;qjÒ9ñS‰µ¢hijK½/¾é}ɽK¾Lмn³Áô~îî»ï^ÓÕյǼ1é}5ñü¤MÂøE`â"ÊÝôë¥_~Ã[‚øâ¯!þGÀnÔ·ÔÔSîš/ð„¢sF]ÔH È?ûEn{týŒ_Ôawú¦Á|Ãg˜}ƒGÎfÓU5ñb«(Z‘0'm©µ¤Ö™â§ì{|èÐbæºÁ$§_üâ]űö¬£[9Z‚ '.¸‘—ßú–ö‹ƒÁq* Äÿc,þ#ýo,•Õt´R<Äè²M°”ßý$ÑvÌr?är°}ÈKp E ˜v5Qݘ¡.Ãç¶äêøïñÙ¶¬ìŠF­XtÂÔ¦¶Ôûr™×ÿ¼}èÐ ¢si8s_ŽköíÛgw@®Ô¸yâ3€@þ2~ÞSpÉ_q—Èú°`'µúÄ¿ßß¼mŸð¬ß¡Â¸`‹5È¿À“" M ÷8ÑÑíC_‡+@`0üò-œyé`Wà3‹÷þ´ýý¯¨Íîÿ¦ŽÔûfn‘ØèM§e€­Ù z_GoäXök7mÚ´æôÓí.¢&GÁ^tiý£‹RA ä%þ^ñ1 æÞšŠê  0>ñå͆BUϧCÁÒV§ìrKÝÏËÛm_^îÕ™¿NÚHAÓôÌs€Q˜ÆË¯ÿÕ( ÁíÕ  X*]4"×MÞBé—ȦŽÔÚRçÕÀh™>÷Ð ¹$óXöuÃé<÷裮Íçó½…«-ýP“/°dfAÀ15u^õ×ñïX»Àª€ø¯Úò nàIÿ.ÿ~Ó”w}•®Rk¾W¥’SZìÁ )­ª•$`úÖ÷“¬¯O¶lÏ‘&ÚP4"33Çÿký×—‚Ö<çê>_}ôU"ÖZüë\7`øùÏ~KggçjóÆÄ÷'p ”ç 2L@ÄÿÕKÁŒk3 Uψ˭͢?¼ìã¼ÜßD»Žô¦¨ýa»>øfýÈfß<†¿.¨k%šh·°‹X¬ûTÃ/Ý'œkÕ Ñ†¢Ù ÑÅZ7J®µ¤)øeßû$õ=™ a6”Ùpº1k8 ]<ì%^ŽDµfÏ>,ƒ€mZüO}¥mO`!ñŸæA„ oâ€ãuƒ^“ćªý¿ˆz»“0•G­.à”ލ …Ó.Ǩñ¬‰xŽ4›©¨ u÷­KiJí¦©=õ9¯ò4¸4D©M7¢Îk·nÝj·€8:Én¤K€!€Üû%¼â3¼ÌÄ¿þ0š8ˆÿÄ‘Ÿj°yçY÷¯½Úük½‡¼LÑѽe^‰Ë@`“‚P⫉¼BšåTÔ†ñ€hÇRÚÒ{ñ/¸Óº˜d6šÿ’×<ûì³öS.‘@ sÂK>àÄ[¸ÌG…­€ø·‚ý£áEà©ZN9Ÿø éþ¿sEâf½7صßû* n&òÒŸ–çqƒ„;^¨ÉYw¦¨ Íâ:ÒÔ˜Öý­„¾â bká/çô~îK_úÒjëñR%ฌ änÐH %áÒ·QpÚïd©Ê¨k† ¨­¿ è±ÏqhZþ!Ù"κ”‚™7Ø2ßÏ®Úý‘¯#HÃ"plß°.ÇÅ 0 š&¢ñsü$L@´ÐD»½2DŠ6äšçxÓzÑÔŽ¦¶@ñc9ç]ò=`7Dïë†Ô¹Ú¶m[Ýþýû_4oL|Ÿ×#U“ÎLÜ, ‚€-áœË)Xò[æa%Pÿ’¿&@ì% >nŒ— .p¤ë¿ø¶ë™¸‡8.‡@oÏ›p¬œ+q  I œˆïßCBJè‚‚ÊÕ'd­´Ñ„¢ ùSÑŽZ/ê\ëI3/]gg¥»C’Ù0z_Oöu#Jžç­vûöí«fΜyï[KÒå%Øñœ5û0 ‰7—‚ËøM(d€@Ÿø¬®8›ÒCW1\ü:¢1s†¾0¡+¢=ϳ%ùZ‚4l=G¸çdã°oà p q ù~Oábá„r`NÑ„\uÿ/ÑÔŒZCJßø”ß)M=tK˜d6¤Þ¯yæ™g¤±í¦)—Úµë ÚÊ]õ|qK‚5lX'ño½ N:P×DÁÙÿçä±í=Åß-;^¶í…¿ö{;ýõž;E ¥i)—Yw¥¨ ããÿµf45¥u_+é@šf#Å÷uCJ^óå/ùEóaõ?±wQøJ¶%Êç„—|˜¨ežs~Á!¨4‚øˆ»ýãÍ¥Ñލ¼pñïÕѽU¹©s+žÑ€E`4ôp¯I`Üb> Ì3Ø·A ¡• ZȆí¢MÑ‚¢ ù0ˆëHóآǕ3†€n¡"û’ô9-üåXïGíííµ¼æã …+-þPS–Z´Ó P]áÜ«(˜{ku tp€@ŸøWèöï@sÕ·PpæÿvÂí„:´Iï" ¨{$wá8•€¬ÂKƒ"Ù% ¦Ø_]´ hB&ѧyßÔŒZO ,Ù—dž;qÆÃŸñHKŠ7Œ4¦œ3Uï×nÙ²eÕŒ3x€ ½¤¦\LÁ¦‡ì9Ë P-Íã)¸ø/ªU:Êgô‰¼ùw¦MÂ…x”Ù¾]J‡ÛO~}tÉ/øY$Ð<™èÈÞ,ÖÜ™:‹²D ²ñ€ÖŠZCš‚_kMÛ®Ú~z˜t#Åsݘ:¯]¶l™=®Àz¤fëa?5‹ÞÏÝo1Ä%5 ŠŠ”$ñ_‹Ý“¼ÊNpú[íúPÊú±=¥Îâ\™ToW™Wâ2š@8fúÐáŠêRS^Y½òË,¹¨Kâ:R—Y²û—¥= ¿Îõ 5Ÿýìg_8tè¬ûh/5N";Óž}X*g\HÁ¬›ªP2ŠwœÿŸÀ¸nwš¤àI8÷¢Æ‰ŽyÅîôuÏ'< xIG$¨æi+ €€hŸÆ)#¸±r·ˆ-È%êñÿZ#jÍ(¹þ:¯œ–KJKÀl½oæfc˜×}lâm…eþM½Ð¶ °•# ën_üñÊ•‡’@ÀA'Å¿ü;Ar‰@°èw]rç¤/XÇþ$‹‘ìɸm$¨f»â³RÕðµœhêÖ] (Zÿ¦†Ôûâ³¹/ÇÞ¦´â  HrÁ‰ê6nÜhÀô+â¾ã¼%.¾×Ýží­ÿp†" ¶ü‚¢‡äÍ?ÄÿP¬ÿ|ü\¢‰ö'–*Yï<º°—äRîIÊ%…ëÊ!Ðà`/¡rüNÉ5jú•ÖkRÔ€uìH)ñ¯µ£Ö“Öý­´i è†Ò¹n@Éã[í<°¢·×òÀ²IñXiÇ&+ªôS†ò²A ¾™‚%ïÎF]QËLPÛ èaˆW?\ðZW]ãù~Òöu+AÔ<^˜xÒ6$¨ sUåð‹Í#ÚÇbí'](5þßÔŽZOêܢו5ÖÿHº¡$ }ÞqÇ[iº±t®ÒlX½_÷£ýèù›o¾yg]]ÝTk-Ê륫‰‹(سښ 0 #& 3ÿ/~óˆoÇ à*“âÿ¸«.¯"`æµn³3“ýKÍwÇdY·-NÖ¬¥Ÿ@m3׿I7´š°ˆ_½Ú¡»»{§h?®»h`éÖ§5¡ÎåÁ}­#uΧғÒÔ Þ*ºÁtCê†5óàž{îéÜ®(ˆÿ_óR"þ‘ü!0–ç©Ÿà‡¿äG*Ÿ@]#3ñ½¨|`¸²l½G˾V†€ G´žh>®Q¼ë¿Ö…’›Ú±2•w°”´ÌÆ3÷uÇ»}Èr€Ö4‘»16`)5OàR)Í“ˆÚ––úç@À+}â?ñïUñ³¡GKÄ3®b‡1ùX¹ÏX8‹‡—…uå^Žë@ |Qoù×âÊÑm#Çr*j=ù£¢õ ä¦&45£¹oÙóÊ›Oc@L’™ë†–sz_G$¯ûÞ÷¾·¼««k›Üh-…¼>æ žQ < àÅÄ[p„‹v œÿà¯ÿv[b„ÖÛŽðF ·ÕµR8ù, †ý4œþû~:¯Ý'ÐsÄ}SäaA۰Ʊ™Dã‰Öc$`j@­ MhjHq[Ë~*’ÝÖ¨>Bi0sÓÏé¾ûî;¶oß>ë½¢Y×UŸ ,€@%Ìxe%JA `Àžg)ºÿÃüU@–Fò’À¸Óýr{þ~ùkÉÛ`â~cx®%ë0›zÇ÷¥¾Š.UÐm#O´^‘K\êcS3¦Nô›ÏD–Ò¸Ò˜º‘%× Ù¯ooo· )—rlª™ÝA— <ûÿe.;ß@`p,þó¿~ù×ß¿ŸºI çQF̹•¨¦ÑM˜yœñ&‡¼+i# ºö§­JîÖG4hË©¨ñZþÏÔˆfÀ²×Õ3ŸÖ€n¦–yÎæî‘N!N=‡‚Ù7Ÿr'@ ¢:·W´86î$šÆr*j»v£”öMhêC9N}ÊB@7¤äzÓ -¹< z«[¶l™ý@®žÔô Rÿð¡‚¿Øcçáz& hñ1ÿ©iþ ®ÅÛºç¿_rcIÀ~ È<‚‹?Öï@ *Žì¨J±(´?5ýBî¥%Ãîí¦¢¶höÑ‚ZššÑ®ÓU¶žæ€nLA¨÷%7Å¿ÞסÚ|ä#Ïx¸ð ø:îÖê/4Œ[! Å¿ùwáw>T¶jýPíX /ýPe™øøŒ±P¯¸C"¬ü‘Ì ÑÃí¼üëqüÞUùo…šÅKE;Ðý¿¨éd‚h<½iý7…Ôÿbd! +I7²nôòÚ;î¸cÙ¡C‡VŸ¸ÍÞÏhÎMöŒÃ2 @ hhàœ‡˜âß!·à ˜‚Ù7Qxšý·d¦O‰îójáåŸ j=-Q³0–]j¿õ¯÷™€ÍyµõzŠ–MÇŽèîÿi?9¯u¢ø­µ£ì§2¥= P7ª™ë‡@Gƒt®^xá…Zž1Ò~/€É¯$jD÷ÀTþæy\© ›/®Cüg£s<Ãt Rpé_R0nV j2ü*„KßʳþãeÇðÉáŽØ¿nÄ·âÆ2 ˆv c9‰–MÇnˆþÓ:OçZšÚPï‹ç²ŸÚ”ö@¼átÃêF7sý@H^¿jÕ*û€0GѬ+ãuÀ1Ø%àñÌÛvÁÁz"ö½pb©?éö”r)ù~&]à¯þ"óhNy{õ¯^¸ð&÷ÿ¾þ'qÕ&Ðñbµ-d¾ü‚va c;µÜ@ÝÿM ¨õ¡m—³Ÿ¥€n\3×/¢_öu^÷õ¯}YggçK‰µÄ†Ô¬‡;œ¶E@ÖuE p×Îü/ßEñïbëTÞ§|WåË´UbëB ¯æqða-µι‚‚Ë>“¨M!íYU&à‚v 'ZŽ«*Ëÿ™Ok=9gjB½_e:nŸ…@¼AåX 3ׄäôÀ¨Ý»w?m½™&žG4fŠu7àôp ªÛç v@@ñÿ‹?!ê:¤Ï ¯S/§ðªÛy2¼t5 ç_MÁU_Ƥ^=)qöàzü¨vSŽáU¢D»XN¢áDËÝ05ž©ýô¾¾N.ëFË5©Žùtÿ—éÏL7¨Î¥Ñe_7¾<æVÏãFžê_„£hεv Ã*€ø@â߇Vª¼=G*_¦åƒÙ7óŒøŸJmO€pÑk(¸ü ÿ–Ÿ³¬šW{ŸÍjÕ«·+š¥¨áâÝÿu ÀÔ€Zê<1V6 e) œuãêÜÿ²ß/ðµ¯}íi†М×Ú|F`@Ü%ñïnÛT۳㇫mÁJùÁ¼[)¼æsN,¡U1Ü«!¼ðÝÜíÿ³ÿƒŠ‚†M`ûãþ7 “ÀÜ× ó†Ê_.ÚM4—h­§õŸÖƒ:¯¼3Ž–˜•€Ù°z_rý˜¹¨â0ë½Të¢ñó}„àVæt£‹uæÚÜÕ ‹øÿtûwµyªî×ñýU7aË@0ózÊÝü ¢¦6[.TÎnÃX ¯ûg½£re¢$h;zŒ[ù·°VQcY³XNÜýÿ©b÷ÑzZ×™ZOP¼ÖÇ–kP}óY h’ºa%—Æ×¹ìëDçr®aÅŠöçgçÝÈ?‘@ÀyùAË´ø?Ž€”å–°f^O߀~0ÛΡܭwS8ui¿Ó>ˆï¹[DÁŒ«|r¾¦‘¯C]ÓX3gêäŠV)j·3¾35 © aYmG²žfCË`n¢lô±ì×q’'¹+ÉZÞ·šÔœ[¸Û\6f¶ Ƈ&püÀÐ×à ¨&‚ø'Ä5);_¶êÜí¼£v°~7~‹Â þ”çå¬=Iµ¼´á¥^ð'yâ4ÜL3µõÁ4WÏ~ÝX£´ŠeOD³‰vc7döÿ¸®ÓOç¦&´ìy²æ³†–d6¸ìëAryXôF=ôP¸cÇy즆 ¤¦o×X& Ž¥·Û-Ø}â?ã¿=hw\<Ê‹ò=îøS5O Îþc~“þ}î °¤jV*Up8÷JÊýÖ}œþ.2¨T±(FE@µ?0ªûqóà …µŠí$šM´[Ñ­ç$7µ^\Êår.3IÊB…uÃÆ]?æCbî7,_¾Ü~€[(šÉ³ð º^G….t®7QzýƒøOoÛŽ¨füïüèÖÝéåM­§ñõ»x‚À;(;ݹ*Hp"÷šoñ_!¼õw®y²íБͤömÈ6ƒ*×ÞRÔlÒýßÔræ¾Ö}q=(„´V¬2-ûÅg¹O¹4²<úÐ„äæƒRÿ¹Ï}î©n¸aekk«ÝÐûÌky>K^>çƼÚÿÕɰGy@ïQ¢š¦ C@Õ' Åÿ1¼ùOœ½ÃÕ—(h™ç°‡•w-˜}#³_EjãOH­ø ›Í•7Rn‰a@áÌ‹(8çˆ&]Xî]¸% 6ýüÄ7þD­fÈXc ‘hËéàÁƒ+E³±y;ΛÖs¦Æ3u_f¼i²Ô@×]7¼Î͇".þåÁQ¼–dýöí¬Ô’+ëkj˜È3JàІŒVÕ¶Bâß v/Œî·>E%L<,`Þë(¼í'Þôwο’ƒ²É½Ó ÆL pé›(÷îêÝ?Aü[z `¶<jÃÿ”w!®hÎu<ÚÇþ%¢ÕD³q%Dãiñ¯ó¸ÞÓ:Pç#ª»¯7%÷ß BÒÈ2 M7¶Îã…~XtÞðÌ3Ïg5…ÿóf öâKÕFȸñpÉ)¸ð£§€êW‹ÿèçï Õ‰‰'«ÎÚSÁØi¾ágžz_E·¿¿àž3jï ¢Î;Ö‘:²³¼!„¹ šÚ(hE4þ4îL{S.Ƹþ*6Š®õħ)Zý“êÈxÉjâ"Šnü®u OLŸ>ý=ìÈdÞŽ[ïËvœ7™5Voò’WÌ@ŸNÊZÝ¢º¡u®ë7ÿfÞ¸eË–Ç]¨·pàKº.ÈA yk’· ‹Ù"ñŸ­öamÕ¡üµ®ƒçÇ™0ÂRz[Àï6¸—–î©Õ÷¶GVMèÚÓ'î$•—ïÈÅÄ×2ƒw#w®kÕg‘ƒ€ß¢nŠ6ýÚï:8î½ZàÆå¢Ñ•¼¸5µ›Þ×úNçZÿéÜqÊ•w/«sIÝè:×…ÎõC£ó^VâñÞÞ^ëýPÕ웹¿‚tP@;¢BùÕA*€ø¯Ôô©v-Koå*]³wvlæ&OÁÔWžÜ¦pçÆÖ…ÿ•æò¬PxÈì±#V}HµqÖ"Mb¹’¢ÍD£±"Ž´nÓ¹Öu:׺Oçâ}æ¾Ðf1 m&ity(ôƒ`>0z_òÚ}èCíûöí{̼ÙÊ~m ©¹W[1 £ P ÐÍoŽö® ¨<ˆÿÊ3M{‰;eÒg$èO@­ú·þ'pTQ-šÄvm&ýáܦv}§µÎӚ϶ÛVíg9 ëÈÎõcæMk×®µàGF-|£ÕÆA@íx@ ² þ+Ë3#¥©íd¤©QM(›€Úù(/‘)š©Z\Ñ"EmÖÄõ45›Þ׺NçZ÷é¼Zxœ.7«itIºñu®ýÐÄó†ïÿû;vló‰ÛíýTãÏ"™x ¬Øþ„5Ó0œBÿ)lÔdª¤öo%êÜ–Œ1XðƒÀŠñÃOO½ "ZÄvM&ÚŒý(Õý_ë8­ï´ÞÓ¹¸/û™KY ÄZ_?f®œ^þ\¶àÎ;ïìܹs§#½n‹×Ç hç <—ê¡ÄìÁPŠ @ü§¸q“©šÚòëd Á €€ûö­ hÛ³îû鱇jáëœð^4™h3vFæ:ÕzMë7SÓéýL þxce= #@ñ\yxt®$ÉW¬XáF`ϼY×oSƒ@2¢ˆ×œþE2¶`%½ þÓÛ¶ ÖLmúU‚Ö` @Àeê¹pÙ=ÿ}«o&5ç5NÔ£¨ÉJÍþ¯5œäq§¨ƒ '²Æ—¤Éå!17SøëýúÏ|æ38pÀ~h1×@Ñü¤H `‡À†ÿ±cVÓAâ?íè@-Ô.î‘tl¯žÀ«äíÿæ'­ºvãÑ<Ö¬Al'Ñb¢ÉØzÞ´N3sSÓÅâ¾Ö‚²Ÿ©”å€ÙÐà ¨•+W6ñz“Nô …¿[¬‡Yì÷ë€GµxDÛ9vl·ù»„}(€ˆÿŸ½ƒTç>¾¿£`0Êg@z$múòž=\ ZÑS_àºòï î„!Ô§=ì>F¢ÅD“5…¿ì%þí:oÙ:'þJH3˜-ôC˜ôq#¯7ù(¯;i}qQ5v>©©Kú{oÖû`SÍg Ÿ'õÒ=–ÿŒÁ¼wx¶>ñ_ÍçegêïŸZ‡€w à0T€Úú+RÛWdêï^?õ’Àÿ<Ñ¢=l'Ñ`¢ÅØRÝÿµ^ÓzÎ$#®Ëq¦SÖú0 ÝED?4’ëIO.Qûþ÷¿ãž={qá鉼Þ7àCF ¨uÿÅ5׿J…€j—O s;E?×oþË¿ W‚ÀPTÇ&¢=Ï u>H#Å/$žþi¬™SurEsˆ-ÆpjyÓúLë5SÃÉT­í´Þ¦™þâšõ€<:é‡B?(¦ð—J.ý`IÞ´nݺßè›­æ³_EÔÜfÕÏ.uhOøßÙ€š—O  þßNêÐÎòïÁ• 0 jí†q5.H µú[TX4-r±¢5Ds8ŠLºÿ›Ú,®Õt ÀÔxxoßN´ŽéD?0: só!küú׿þÈáÇ×ZoÆ †¢…XÐz;dص⮠×U/‹ÄY˜pÑèDîçyIöŒ®Ü  à£ü"âÙ;ýòÙCo£·òb{5Ö=í%Œ)Õý_k6Éõ¦õø®5Ÿìg6!pòAЇ<,²¯ÉM᯻™ÐüãhûöíNôP‹~Ÿ¨¦.³2*n—€Ú½šÔ®§ì:ëî€øw·mÒæYo©¿“¶Z¡> ƒPO|†T÷±A®ÀG£&PSKjáG]L% í%¬X–Öe¦V35œÖtZçÉm²Ÿé„@ÿæ×‡~Xô$U< çšüñGòùüñþÅX8ªGjþu Ã$œ  žý P€À© þOe‚3U% ÖÞGÔs´ª6P8€€ÔæŸS´É…¹Ü R/Ôœ«ˆ&V§ða”*šK´ßïþoj5­ß$7µÝ0,¥ûRN¶¯< :éÆ|€ÌÈ’Þ¯{ç;ß¹¦££Ã^§¿™ýtƒ@¢ÔŽU¤¶=”¨MsœÄ¿ã ”N÷T×R«¾‘ÎÊ¡V ' ï õÈ'±W5jñT­ìá,šK´ß#Ýžµ3sS»éºÚ„©õô¹Læœhvý@H®73 ,=¹„ÙݤiõêÕnZ’š¾4“2*íµìËü$¿.H™'Pÿˆ ÿ2ÿ Ø ^¸›¨ûã°  õè'HuLÄV–¨Ég’–ŠšK¿ý7õ˜Öhò%ÔÔpZ×™ZωºØt€S雊EÒ”è¼ñÎ;ï|¸³³sÝ©E%&Zü¦äÂ" È2\jÍ÷À#ëDüÿLÄÿ®¬“@ý-PÝGI=ÿ÷–¬Ã,€@µ ¨u?à®ÿWÛ ÊgÑnh ÑZ¢¹Ø¥áNþ§Å?Ú³H€“‚)üõ¾}ý:¤£NÁøÃüÖ­[Ýèû<ýJ¢±3NÖ { 0õ,w½=¾/a«0ç -þCü;Ó&uD½øc¢Cí­=ª )&° ©'¾”â :Tµ–©D3®wÂ!ÑZ¢¹Øï¬u˜©ÍâºMë93w¢.¶@ t ˜Š~˜ôóAÓçš|ðÁ‡{{{;K—äÙ¢ÅoHÒ l@?êx'©Çoïw!ñŸ‘†ö£š*ßKêiŒö£µà%”I€'øŒî?©Þî2oÀe£!-þm¢Ð¾\%Z‹ë¢»ÿk ¦_Ìêc­ÛL-7©¼×~‹º‡UIúÁÑ’äúáÒ¹Ž>Õ½÷½ï}yÏž=NôPó9P×\¨~€€ ц‡Hmú™ Ó°i‹Ä¿-ò°;¨ýqR›1Èø@À'ê‘:¸Í'—ýõ•µ„:íwœð_4–h-vF&ÿÓúKë1›šMë8ñ_k;ÙGbô ô¢ydß| t qj^¹r¥ªi¤èô[ú× G 0õØç‰ŽíMØ*ÌY!À31GÿýǤÐíß ~œ€zœÿõü"|  à<õüW)Ú(/‘’ -b-ÁšÂ…TÔXòvS‹}ɵ‹ë4­Ý´ž“*È>R‘@$N! ãJd“¤÷%—`‰¹ ;Ùäœä [¶lyñ¶Ûn» ¡¡aÛMãQ¸în òù~•0+„ýþ •åA½]Dû_ `Áëìþ.Àzu ˆøÿÙÿâ¶Þ‚¿5LGÜc@‹™¸OâHßžÿû6§¯n¨Qª¨µ?%µå—©ª*™!°ç9Rš¿ië¯ç™©¹µŠªÓ^ů6'X³om%‹ÏÉ u˜~û¯%×¢_ë7)Pˆ%b@øP?(fïZb>lfÄ©éG?úу]]]ÛO-6ù3ê,^†Ë‰;’¯9,ºD@=s'©m¹ä|©ˆÿJPDI`á ~ó KJŠ7ì€@¥\OÑ/ÞÃï{WªD”3ÑꬷqU2‹¦mÅÖôä¦îÒz,®ÓL 'ŽêcÙGb þÈcnº€Îõƒ'¹<5wÜqGÇŽ;ä}ëI5Ï"5ç ë~ÀŒP©>JÄÿÄ‘RBâ?% ™±j;HуÆÿÕå_6€€ódrYž_†º0‡G’m%ÚA4„ I4•h+ö¥†·ÞúËuÑf¦fƒèg %J“‰?@rlF—äA“MG¡Ì²ùÿ³w&pVgÚ¯{{ß醺š}‘}SQPP n$:‰ÆÉÄÏh?³|3:ÉÌ$1»Î81‰Mb4£&bD#ÆQÙÄAŒìȾ/ Ê* ö½ç{߆G‹ãí ºï­sïS¿_õ{öóÖÿœs»ž·êÔY¸páìH$¢ï£$•OªšAµƒ Iµ”j*ñE?EÝkk3[³¹Pg}` áK£7’&µzƒÁ⦃µ{ètþŠ+f‹u"EyÇ t"±ªß7Þ«ÿ,ýgœè “XA;»VÈf\g ÅЮýý `žŒ°{ÑgÖp @‚ h·ÿç¿Âÿ5 º .i†Z*_Pøuô¬­Ñlí– ŠîŸ–€ú¯‘}é´f;ʤӸñÔÚ‘©ÜŸýìgs䳋eyâS‡³M´´wâý $ ¼­ïHàf‚t7PüéjÑצ¨=&¯%Éx76eknC$7ˆø¿NÆ Ú³ñ>uZA4ƒ I5”j)ñ¥¹ƒÿA³i1 .i @IDATåtšÉ"À€£IÜLvâßþ˜öæÍ›—µ~ýúY 3®«¢ý¿×óñd$ÐoËÛ 4È¥uÿ.] úÒ’jH¯–o#-ŽL$@ &°ç=}æ+”Û•`GR÷ô.iÕPª¥äj¨ö‚¾ò7¸ê<gm­–º±‰%g aPöÍdOãf³{è͉SmÞÔ©Sg9rd}çˆÓÚÎãWÒ%N'ãiH qˆÎ¼^>íÃÑ}§• -êÞÃü*»b&?OvJàFù< (mž‚bð¶¾j¢/H0Ž£ýÇä…uA´‚ Iµ“j(ñƒÿù5–-üU‹ÙÍžv¡8NúÀ@Ó/‹ÞPz“Ù7 ZÍö švï½÷Þ¼y³ÞÀ¤°‰ ºÁ?è XdDîè "0Yù¶ 82yLZGõÚp&G.Ýh5û¶òw¨ÕàòÀ$Ð0oéï7ó_¤1€7Lªu××nÈBÕNª¡¤Äi’mm½¥Z ÌÖeªÕ˜š@À+ÝG¼ n(µší› 7£Þ ÈäÍš5kö±cÇ>H°ÿÇOßy‚ñŠ:9á OìY'Ýþ¾ḋ+?YĉPñ?CzgPü'øBðôq# ÷zôÙkø:@Ü€óD)O zÌxsÿŸñÞþÔ¬µZÍ”(^Q…1uú“ΫšIµ“,ÔÖ[üÛË/þ¡ÏôX:ÍÔ$«q#ÙV§@Ö¾A3¿ýíooÚ¹s竟&[„Mtàuñ8ÏAÍ#p¨Z*ß×oóKÍÛ[·<ˆÿê5-l‘\& ïGŸûоV¹ì%}#àÁ75ðï­}%øeI‚DþcÂnHBÕLªk¦dÕV¶®‚ÖR ¦šÌÖh2ûɼN3Å àÆÕŽá˜ƒ‹pƒÁê‡7¤Þ¤:›Umþ‚ fE$Ét“×å2ãJ¤‰\#ðqñ^¾Ýx‹î’Ÿn'×µ¾?ÿ­Ï˜gp›À¡=Œü?ÆÛ>ßm?é ”€·áY}êjcö®h ’ËmÕª \Hª•T3‰/øôô´•ZͶƒ.ƒu¡(Îû ïV05@èÄf¶ÕiÍHñge«9gúôéko¼ñÆÊ‚‚‚ž2ŸØw³rLxÓ¼ÄúÁ³“@}v.5ÞŽù&Ôi”1ú?€©u È7Ñ7¿lÌ Æ{í?aËëâæÑÝ'ùؘuÒ)'×„Ú vß_zHA þz¯ÿ»ù §ºŽÉѳ¾eLÉ.¸bvíÚõòùçŸÿ˜8S,Y~ˆÍ1+ë<²Þ@v0Àÿ:ÍÔôFÖsõg à&ƒE 7"nJµ˜.x÷Ýw_)++›øÙÃÅI]/€%šÐþ­ñ?9ÏHM!°s™‰N¿Ò„ν݄º_Þ”=¸Í©8´ÙDçü›1›‰HÀ"­5Þüÿ2f÷RýS ñkoT& S!àm›g¼y?’16öœÊîܧ•è¸`®´þkU+‰)¬šÊÖQÐSÐZª½ Ã`eSS °@SIoéÇÖhù‡õ·þë¼²…Íyë­·_}õÕýóòòºà ³Ú ;OzÌM˜ <1 4J V¿¤'Øþ•&T~¶1é9î šNÀ[õ'ã½ò¯Âw{Ówâ–$jö®5Þ–WL¨l„üß,IµÒ³¼$pzŽî3Þ[?4Þ‚ßJ[îG§w,îÝâ\jý¯®®~í‹_übÕþýûÛKAÑúoÛúZÿí`@‹3JÖª@ej0!!Ú¤72¢RvÔê“èÕ¦M›Ú­ZµJ#[N$¯ë%Æ+îê„/t‚"à­›c¢OÈØïk¯0¦Ó&°ï}èìiÝüo©9íÃñ$ôö¬7Ñ¿É3³êÏI_TZŠ€þÏŽ>q©<7/J[­]…n©3ð8§CÀkÓÙ©ÖÕHª•¤L1uԉ庺+–ðçÖÄ›‚=šêÄfÚâ¯É¶:m÷Ðy»õ½²·lÙ²ìÒK/’]®Il /»PzÌJ¬<; 4…€öØôš Ì5OÞÉ•wÕr4@ÌÔ,úþ廤¦tg–ÑΙH€šA *õÎÍoo÷ê8\Ƨ.jÆÎÜ”RˆÀî…&:ë»Æ¬xJ:qM¡‚«¨‘³o“7í{9áô¾}ûÞùÖ·¾UµqãÆ6â6žê»ÿvë¿ÎÒ¨*Óv @f9ê¿BhNb€æÐúôC„Éî  7£q£Âz³gÏÎ^³fÍËÍ;e+nÝe‚ñÚ¹ñð·b)yèd"°s¹Œ|mÝ·ƒÍáÉT²Ö+‹|QÁ[ù°‰>>Éx˞عþ$1‘ œ­‹MôÉ/ȳt¿Ôô_> @ý2ì«7Éçýn0f×JBq˜€×®§1¢\IªT#‰?ª« ›`mm¥Óþ–[“¹R$çý`€æ_"má·{è°L-zÄìPSS³ò‚ .&½:莉MÒ ¯Ô„×ÏL¬<; 4‹€üÖ°^DíãÆÔl7¡¶}ùµ€˜üdtÿuOÉ{þß1f­ÄÙ“’@³ ho€­ooà Æ•›Pa·f‚;@ÒPá¿à§2ÂÿÆ|¸)iŠ•Ì‰œó}cùÝ’wþ—þä'?©Zºt)ÿ‹Õú¯½4 `Л̗ªÕʦ‚•©ù”›f[ì§Ë|†d*Xs–dféÈe¶= ^:tèPéåF ¿ôUÞµÜ gè 4—@Z¦ õ½Ô„}ݘ¼òæî|ÛË'̼uOïïʧýØK"ù.0KäPç3Mh¸|J«Ý ×\£?$Ðz>\i¼÷þ ÿoæ°7LëQnñ#G;ô7щ·øqOõ€2òÿÿŒ9ò9Ù¿PrdœÈ¶ú‰@ c0 p𛨠¹ÄŽo€ÎaX¼ûo t:+33sÍyçw¦Xì"áÉ+¬0áµÏ'Ü:@§D@»áVKEdù_dDû&”_&€Ž§t¨@ïtd¯0xÀxs¾/-þ39z(ÐÅ¡ó$¶Ë@gò¾óÞ÷LH×å%¹tt´¹¤gÙæ™2ˆìÆ{»ª®7Þ§oÇ6÷XÜ>"çÝ!u¤ŠDœú3ç<|øðê_ýêWS.\¨¥Úº¡±¯-ÿþÖ[øæ˜\Ð4*V™šOÜl±¯=Ð @{hô@ôØ·hÑ¢+xKóOÝ:{„gÝdÂ[¶ÎÁyTˆ7y¿-Ô÷ó&Ôc²ôËÑ^eÉ›¼íóYýWéŽüš¼§ÿ'™H€J b° ¼Þ„:]P7xrh1‡¶É—xž0Þi,â ²-†5ÞŠva¢þ>Þ§­÷|ÒíÿÞ#F<)èàhõG×ÖÍv @{øƒÚ €©Ø °|›ªø·˜W‹VÛ*kÍu½Š‹‹×I——³322ŠeYâSqO~ÿo⟡Ä_ zpÚ>úàøˆÝ˦³o…\%­ýÿ[× c–M“÷.7È£«ÿ™H€N@ÒÚÒ5úiiÓÚ/ct—@dnÂÝ¢$Ð,ÇöË=üŒñÞú…ä_³ã]iŸ=ܬCpc‡„Â&:öNy)Ù‰ÎÇæÈ‘#ëï»ï¾ª×_]Kµc·þÛ=üƒê¶¶X±§î¶+°n{é¦w`Á^ @[ÿ‘Ñ@ç÷½óÎ;_0`ÀM®/üúí&¼îUWÜ¡$в²òM¨óÙÆTŽ9Þ2¨ÏxÉÿ·Ý‹Œ·éUé~)-þnnY6< @ë§™PÅ0cz\lB]&I0 ¯õÎÅ#“Àé¯ëÔuñß8˘íKDfi¯l¦d í1ÎDGIÀ‘´lÙ²ß >\Fsþ¤õ=Ô"#(ë5XGJ 7T¬2½áÐiÍ•BÖ_M͈\ÙV—üío{©GŸËÉÉé*ó OÞ[¤±|g݈~-è@+wâ½µ¯JËœˆhí о¯ •0¦ìlù®÷YÒ7Gcv¥ýk·ýu©„Éhã;þ.ÿ:ä]!h2ùj€·E^±“ì¥I¼l€!GK@rœ|E [“à I Å ýÀx»ÈW-Þ4Þ¶E2ŽÎÖ?˜x^8Ãhß•$­ÿU‰?ùßÖH˜†Ž‚®R ½…¢è<Ó)€€=…]¹‹?íÖ¯Ó±zØcäÈ6ÚúûáâÅ‹¯îß¿ÿ7d™)´è—&mù_ð…N@ÜH iÛÍ„Úõ‘‘¼û˧HLºWœZêäÿ×þÆû@^Uø@ºöW/“A W‹àç ~q»þ< $Š@^[ @ö7¦Ã0*bLI_Mˆ¯ $êr$õyu X¹_ÿϘê¥ò¿FìþI]dî8Hÿ+7â{ÎàX¾|ù}Æ {LÒ× µµïýÃê{ÿšñ*€@ƒ«,:éUgj"öh"¨z6Ó›P…¿mqcj¤ 7«ZD´l[ðì³Ï¾Ô½{÷‹¥@Ù&áÉt³¼óõ’ ±µ1áׂÄ‘€~×»ZZÜ%óüñÿ(údçÊ»rúï‚r5·Ãñ¯ ÈBYE2ħŒY“)ÿ»Ò%¦W_—^y‡ÒÔ寫Ù'ÿâvsXòG’l5ÞmbwÉ/…þc"H9‡E”­›gŒd­<˜üðÊoL©èïNA'còÅæ´“ß±ò›“&‚tmG@’=ßé%•ßÙÖ¹Mp•¶å ÔŠ~:&ÿ_Žî3žÞbtå72pŸ9´Ûx‡äÌ>ymŒõº–g€#zòú£Öí]IÒú¿Iµø£­ÿ¶&´­Ðú¯?u?‘1¬,bj.­â20Ô^ÈXÑœ!¹±±´À5Ò @>bîF ­zؤ-øÎÐ      fˆœùMãõ»±ÙûµÖÒúÿiýÿ‹­ÿvÖ¬­"šñî¿ P« ãsüÛ,*X™Nn@D§Ôâ&µ£Xˆlù­ö˜¡ïÜž-··×çZãU´Üy$     ¸ðòÛ¯Ï?Åí|HµŽjÙ®¾ÖÕH¶v‚ž²5–žÚK§™N§­]pƒâ†UkßÈÿvD+ý‡?üá‡ëׯ×ÂJ7‘áî âzA$@$@$@$@Á v“¼2”匳ªuTóˆCÚK:–&²5“­¥ ¯œ)KÐa å® nNXܸ¸™q£û­®/üë_ÿ:ãðáÃëZÎÓýç?ÿù‰Œ½ˆƒ¸`½ß•‰x‹¸p-è 4N d"#þŸlæN^5ŽjqÊný‡èWkk%è'[S¡Ø¶æÂ2ÚfpçÎh¦ãŽnnߨ¸yaíÛ¾á1]8uêÔ<¸Ú•²ym™h÷ \q‡~ 4@ Ú}Œ1¥ÃØ"¾«TۨƑ³jë?tmmÝkk«ø:žÄgc å.®‘²oV½qcãf×yLc<€´_ýêW5ëÖ­{¡å\:ý#E†}Çx½?tú%âH€H€H€H€H ùhݦ­ÿî$Õ6ªqÄ£4ɪ }tÚÖDÐKªl-%³uÉÖZXF{ 8hìbß°ˆ^ÁâÆ†ø÷ÛÂ{ï½÷…ýû÷¿×È9â¶:”[f¢¿·óñD$@$@$@$@$@Í' uv/¯¼ù;¶ÒªiTÛÈáëkýG@5ô¬­©ZÉÃÔ<,-{ÝíÈ”}ÓêÜøG$,üç?ÿÙ¬ZµÊ©^^ÿoÈIiË’âÑH€H€H€H€H€Z„€ÖÕ½þ_o‘cµÔATÓ¨¶‘¤šSÅ>4¿:I5“­¡d¶.Ù ËhO‘§®‘ÝìQ,XÜàþówß}÷‹{÷î}»‘sÄouz¶‰œùíøg"    h2ººzzN“·oí U˨¦‘óH†Îñ[è"è$X[Kµ¶«)w|Zþ’Û*ûæÕZorµþ›_ç =ýôÓ9®õ0].6Ѳ!â& €+êêèRWw)©–QM#>…$ÛZǯƒldk'ÇÖVXF{8 xìjßÀˆfáG´«¾‡¡à¶Ûn{¡ººzn#çˆëjïìï/¤_ï`"    H4­›kÝ¥¤FµŒø«õžÐCh …^²5”KÅJ_t4F¦Ö! Ñ.Íš0í·€Ñk ËÕb>}ûöícÇŽÝ×£G‹B’d]âSv‰ôSØk»W$Þz@$@$@$@$@)N ÚÿJãu¿Ü ž¤ùóçWI÷ÿCâT†äc’ZVº mµƒv‹¿=-›1µöh ŠõÃŽ`!ª‹¨ºÁà!P«¹àòË/sÇŽÏ×øø¯ñÿ³ñr‹ãbž‘H€H€H€H€HàZ'׺¹KIµ‹jñI[ÿ¡kü½ž¡ƒ ‹`míäR±’ÊZïrÚ+ûfÖ7=Ä}¶è7Þx¡¶¶V#hn¤Œq‹¾Ð     HQÑ7K»êl7’jÕ.âM‘äúô –C©6²µ ck),£m ´ÄFaßЈnÁê‡@-z`YÞµ×^»|Ë–-Ï5rޏ®ÖnFÑýâzNžŒH€H€H€H€Hà8h‡3¤ëÿd§p¨fQí"NåI†ž‰¥qTAÁښɩr%›3 ´îµ#WöM­7:¢^°xHüA€¢3f<[SS³­u]mÎÑÃÆ)ƒ„9„Ds¨q[    8mR÷F~_㎔S­¢šEœò·þÛÚºV5‘­‘€ÆÖPXFÛBܹkZ¨@Žƾ±岃ÿ°öƒ’õío{ǺuëÜêPÜÏDú}ÁQÜt‹H€H€H€H€’“€ÖÁ=©‹»”T«¨fŸ²$ÇÒ4Xf‹è"[+¹T¬¤ô…€Ö¿¬v˾¹qÃã!ÀC«AЦNúìœ~ßr«ñòK[Ÿ Ï@$@$@$@$@$PW÷Ö:¸KI5Šjñ ­ÿ¶Ž¶Q Ýdk#ÉÖNXFÛ‚hA˜ʾÁqӫŃ VŒXLº|JãØªU«œê`ÒsMdäm›«I€H€H€H€H€Z‚@]Ý[êà.%Õ(ªUħtɶà·u­yl-dk$—Š•´¾ð%îø]ÚœJ³&Ûb¹Z ÈØY¯æsvîÜùθqãzçååUÊr7Ra7cö­0¡}›Ýð‡^ @ˆvm¼A2ò¿C©ººzþm·ÝVµvíÚ¶â–Š| h>jM×€ø—Më[ÿA¢­ŠK¦øÀM«@}Q3óâ‹/¾ûî»Ïz’âçrãgŠœõ}ãeä4¾!·     h6­kkÛ¥¤šDµ‰j”~Õ×›Y—û{@ÁºT´¤ö…€ø]^[´ãFG÷û@@#eþéÂË.»ìmÛ¶=?·?S(·ƒ‰ÿzãr      fк¶Ö¹]JªIT›ˆO€ø÷ë·µôôŠdk%,£m ´ÔF‰›Ý¶xðpØŽÐåųgÏ~F>µQÝÈyâºÚë}­ñÚõŽë9y2    HvZÇÖº¶KIµˆjñ©X2´‹Z»»¿ÎCß@ïØÓ²S¼0/ÒÇÏ£79nx< x8ìÓxÔæÜpà 6mÚäT/#ß#ŽúOÝ€ÃJàÓ’ Àiºu][êÚ.%Õ"ªIÄ'}ØÖ*Ð/¶…ÎîB‘l„e´­D€€VÛÈaqÓÃâaÀ澇©Í£>úŒsŸ”ï‘FüC#Eçj     ¦ˆ ¸ÊxRÇv)©Q-">µ‘ Ý¢6–v¾Þþu©h)á ñ¿Ìz³#é´> °:‡Ä~˜üTú/ùËš•+W>¹bõ»¤^›N®¸C?H€H€H€H€H ´Ní ù–s¾«Q-"Žégÿb‰~èè[üCû \¶6Â2ÚV$€Ïѵâ)xèÀ]­f Äh¿}ˆ4gHÎ<‘³ÅfIÖî5:œ>zôèÍÓ¦Mûy»ví.”åî¤êwMúó7JhƒÏ³;…ž †@8dj/ùƒ1¥ÃœryÏž=³¾ô¥/}þüù•☠}  ‘iýüŸÎãs€ °@(ÀÊfLñ Àñ üÙsàF·­NëH™>(:‡Æ]óäÁk'ùéÚÚÚò;©t¨‰öÿ¼;þÐ    ºº´câ_5‡jÕ ‚Rµ‹ê¿FÑyÕ0Ð2:]Ÿè‡’M˜âE-Ññ:Ïs2ô°{ '@SzhÏ€«V­º±[·nמ|èÏÕÖ˜´§¯2¡ý;ìOO$@$@$@$@Á!à•™È•~ÁÚñ×´aÆ©}ûö½_<ê(-ýMiýG§ øOÐ¥e€·N«7?²>ÈxPAóGØ4º¦ËŠŸ|òÉ¿>|ø}™v'ÉVdô¹Á¯è ¸K@ÔY]Ú1ñ¯ZC5‡€ÃgÿT‹ØYu‰f[Ã@×Pø W’[ß“p…J|ý@/=+zd`¬j4ë¼Z½nX–5kÖ¬ý“'O>VVV6J–»“ò;É@»L¨z•;>Ñ    p”@ôŒÉÆë{­sÞ-[¶ì_þò—µRŸ'Y…?Þñמ:íØ4vÊfu‰­ÿ ‘Ë@ ûN ѯ‹!ø±Ìž‡àesÖ¯_¿pâĉ=òòòºúŽŸÐY¯ã™&´þ9:æÖ0 …““ €€WPj¢ã~#Í|ú&°;©ººzÎ-·Ü2eãÆ¥â• {ˆÛ"€žjÑ .«ŠI¦Ä°<xX9³$<\j±ÜÌž=»äõ×_Jç8”ØâøÎžžk"£þC"¦á[ÏY    Hy!©3ÿ§¼÷Ÿë Õª1Tkœp ú#–&ÑuÐ/Ð3Ð7(—­}°Œ6Žˆ#ìFN…‡ "òöö´nt^­f½Ž:Ÿ5o޼Ó&M:Ô¹sç12ïN §¯´¿ ¯yVBöï€;.Ò    ˆ+pš‰Løµ´¯WÄõ´M9ÙâÅ‹ï»þúë7ʶú^úà˜‡E @ƒ±zÈb&°€ Wá¸PŶÅã5µqÃC†hl›¯~õ«ÓwìØñÂñÃ:ô·Ý úO9DWH€H€H€H€H qêêÆRGv-©–PM!~µ‘ í ¢ó¶F±µ‹­i´x˜×i¦` ðcœ†ZdûAÂñ¯uydÓ¦M•¯¾úêôššš1ΑÐEÞÀ›¥'@ï„úÀ““ @¢ hXëÆ®%Õª%TSˆo*ðÒÐ'¶fޱµkÅLYpóÒÛNëeG×ð ÙâÓº.÷k_ûÚ¦uëÖýÕ¹âI7§è˜Ÿ/=Ë9×è ă€Ö…£çÿ\^æuïlÕª%„ƒvýoLüÛE5‹_ÇÄ'ÏÑ îÝqÍp>‰7ÅûþZDÖd/ÓÀÎÛV§íœ³oß¾E£Gî™——§Ñ;wRV±ŒVeÂ[ÞrÇ'zB$@$@$@$@q"y«ñ:ÓÙš~šêêêù?øÁª–/_ÞVöRA¯ïøû³Ýð¨ÓØY\—Ð ó´ &À@‚/@=§‡è×Õ¶ð×yùš°ƒz=1Ÿ!nhÔ¨Q»ºwï>*»ÕäÞn°1Õ‹LhÿŽºÂð ¤hçáÆ;û?œ+jmmíÁ¹sçN‘À!qNµøS‹Áÿ þañŠ€-þÑ À¹2Ò¡OÅ$Y¸EÀŽ”é´>PȈ°áaÓ‡ÏÿJºê\yå•ï­_¿^?ßá\Šž÷Sãå9ç"    Ö àå­»˜T3¨vß $Cc@èÛzC§mM‚ Šgk,£M0´&'Ø ž¾ˆžÙBˆ}<œ°Xßö¡‡ú«¼°¸žs$nqN9ÿ‡Çû2$Î ž™H€H€H€H€ZŸ€ôßœ÷ÆHص¤ZA5ƒø¥]ÿ¡# +l‹uj¡Kl­‚i׊HNà+nß þWÔ[,Ã+~«A;g¾ùæ›G/¸à‚ºté2F^p+èSØUâ‹{Mh÷ - $%h¿+Œ×ÿzçʉDjßxãª[n¹E¿ –#Y¿ÿ½¼ ëÐ^±‚²˜ŸýS.&·Ä ‹„ë“FÐMÃC¦V>¼  ÓvtΞnsÉ%—¼¹yóf÷¾ NG‡ÿ«|°§L1‘ @òðJ*Mô¬s²`ªT+ˆsm$Ûž¶E¿NÛš:å³5 –Ñ:B€G.D#nà¡‚ÕïÝàa´P{ëÛþUÒ–5r®ø¯NË0ѱ¿4^fvüÏÍ3’ @+ð22Mô‚»ŒIskLn-²jÕ2ÙX×ÕÐÐ!ªI O`e“Ëø €ËWçSß´›?ºþc)–ÙV::¯Öκ,kÖ¬Y'Nœ¸O^¸@æÝJúiÀü6&¼qž[~Ñ    8 Ñs¿ëä'ÿ´Ho¿ývÕu×]·I&ó$ÇêöowýGÀ  ‡Ó¤&‡ ¨Hd DÕ`Ñí ZDåìxPÕ–Œ?~®tóyÂÅ"{=®4ÑÞã]t>‘ @³ D{Œ5^Ÿ/7{¿xì š@µœ«D²­l-}akèèØx¸Ísœ&N`œvׇJ.X<| ‰ÿÜîÉ'Ÿ|\ºû89ê^täWTv¼´üK$@$@$@$@%àv4ÑQ?vÒ{Õª Ĺv’UäÛšÁ?m ? G`µœ:Íä8¾àøò¹’yÍšbY¬×ÀŽN«µ³.Ëzå•W~îsŸÛWYY9VæÝJi™Æk?Є×>/?!úûÂD$@$@$@$@# c\E&þÖ˜‚J'_´hQÕW¾ò•âºþ«è÷¿`ðP>Špܪ8d DÙððÁ¢[NS"x%_|ñ›6mÒ¨Ÿ{©Ý 9ûŸÝó‹‘ @ÔÕe¥NëbR  Z@|Ó®ÿMÑÐаÐ%.“>ÕC€€zÀ8º‘5ÛâăëuDóÅ«=vìX¿Ç{lÚþýû—ºXVšh÷1.ºFŸH€H€H€H€H ^Ñîç­Ëº˜´î¯@µ€øg‹ÿÏè…ëmÝak-&æušÉq|Àñ Ã=týÇ*̫Ŵv0iµvΚ={öá‹.ºhoçÎÇ„%ီX¯ÓhÚø’ =èŠKôƒH€H€H€H€ê%à•›è„ßË'ÿ2ëÝ&Q+"’dÔÿ{¯¿þúmâƒvýÕíß @€ €Tì#Ë$SÐ8'ú‚0þ"†VH<œú°"£Õ?–-ž0aÂÒ è/ (Gã§ÌÈ7ÑqÿeLº{? ;Ï-H€H€H€H€RŠ€ÔY#HÝUê°.&­ókÝ_|“ïo7iÐ?ÕÐ~ñok‹KŸê!Àõ€ Àb´ðÛ®bY,k·þë4¶ÉÉÍÍýû!Czçää”Ûsb:§ÔxyÅ&¼é5'Ü¡$@$@$@$@$‹@dÔmÆtkU—}ðÁ‹¦L™RõÆo‰3*ÞÑÒË¢áÐ@åAó´ À@.R=.ª€·“=q ÁotÎgÊÁ±Ñ£GïìÖ­Û9ò&@–}P'¦ÛÊ+J5ÛL¨ú}'Ü¡$@$@$@$@$`ˆž1ÉxCoµ93][[{pîܹSn½õÖ½âTŽäúºþCø«EobíᯂY&™‚HÀAô?Õ}Æõƒ˜‡ÀO0ÈÚ^³ ûlËê4æuÝÎ%K–|±OŸ>7Ê´{)rÔ¤=÷XëžoôˆH€H€H€H e x¥=MäÒGä½÷ÚÑô¢¬^½úþAƒé׿:J>z"׈EÖe:­=P«d´úÃÊ*¦ `€ ]­Ø¾ªøG @·À4–â€Î#P`/Ë;xðà‚sÏ=·k^^^W=S),ñŒÎ£Lhí³&T«¿KL$@$@$@$@$X^v‰^ò€4µékõî¥êêê¹wÜqG•4ô•ŠwÚšï·þÖ¼û¯B=P@Š e €Íç2¿oq½€X dÈCxøðáºwï>4==½ÐÀ„Ïg¯]O^7S:ñw'á׃ @*hE.’AÿÚp’BMMͶ—_~¹êG?ú‘¶âkàúºþ#`wýWÑ«û¿“e¥SM' Â)Ø „ÕÚ,¢wúàÛ‘=ûAÇòük¯½vãÊ•+sIùy&rÖMκGÇH€H€H€H€Rƒ@䬛‘º©«IëôZ·ÿô³¨ï«¥T+@7@üÛÚÂÖ²)SP °@P¯ÜgýFW¬AÏÛ¢õÛÆz ÿ­·Þš{É%—t(,,싃9eÛ3æàZú`ƒSnÑ    Ô íu¡ñÎú7g »uëÖ§¿üå/OÙ½{w¥8©â¢ßoíÀ€PÁÏ®ÿÎ^áSwŒ€SgçÚžú¶_úº Ó¶µÇÀtšüP–——/ëß¿߬¬¬ö]™ö:1¡msLè£\q‰~ ¤ô/:¾JFÕÒ1·ÝKXúÈ#T=úè£úÉ?­ãCôc@ÌÃj@Å¿fýÈvYÌ” H†«øiì €óv@§ý½t>ë•W^94~üøÝ:u%Ÿtï×M\Šv-ãIü£µß/þ5@PŸø÷>sN.H.*è˜Rƒ"zxÈùƒEw ýqÐ dü ²¨ó:]pýõ×o—@ÀŸ¥G€.s3¥çšÚ‰¿7^a{7ý£W$@$@$@$@ 'à”Jñ>c¤îèjÒ:·Ö½µ.>Hö×Ïíz;êòþZ×G½º@‹ ­ ÓLIL€€$¾¸1Šæ°u^lñ¯? ðc¢¶tܸq¯­]»öO2íl åvhn•ñ²óõ‘Ž‘ $†€Ö£O1Zgt9i[ëÞâc©d»N®Óõ‰ÔíQß׺,M ‹™R_H…«|rí.ÿö{¹ÿ5{^ƒF˜×é¼]»vÍ5jTÇ‚‚„ÄÍ”ÝÖxû›ðÚ™ò“§¿L$@$@$@$@)O -ÓD>w1íÜÛZ¯ÑŽ;^üÞ÷¾7eåÊ•å2«‚_­ýî?–#@€hõG@áÈ"¦d'À@²_áØå³Å¾nyÛÚÓº-üuæÓå‡(«sçÎKûôéÓ+;;»£nìdÊïd¢mÊMxÃq¿wN^#:E$@$@$@ñ" ›Ú ï0¦Óñ:ã)gÿþýï=öØcU¿þõ¯sä’Ñâwým‹uhùW ñÑ«þ°R¬R(1BÛWT|]ŒiµÈXŽyµý~›3sæÌƒçœsΖÊÊÊaéééyº³“©¸·ñ²²LxË[NºG§H€H€H€H€âC rî­Æôþb|NvŠg©©©©ž;wnÕ×¾öµ]r}ï_[øUäÛ¢½°N×£åß~÷¢V6gJ ¤Ê•Ž]Nˆ{{­.Ó‹il ‹ æó§M›¶áŠ+®8XVVvnÝ\ýÓ~ˆñj÷™ð®¥®zH¿H€H€H€H€Z‘@tÐÕÆú[ñ -sè%K–ün„ ähxï_E>²À²ÆÄ?£ø‰³*â˜R›€ Ôií"„ABÔ¢ûþ˜ ãF-–©í0~üø‡Ö¬YóˆL;¼³o3Ñž:í##   hyZŒž}{˸…¨uj­[ËautB»Î]_]õv».ïçŸÂ¿…¯SÐÇA»b-ﯶàחкm`Ñúï·iüqûƒ¾1räȲ¼¼¼õ8ñËCÆ«¼À˜Ý MèàÎÄ»CH€H€H€H€Z@´bˆ‰Žûµ¼Øª¯Ò»›vïÞýòüã)‹-ê.^j ohñ·­t½?€wÿí €lÆ÷þBª&RõÊŸ\n{]ªÓþy{9Ö×g3¤«Rz—.]–öîÝ[t÷{*átãu›hBÛ_3¡Ã{µŒL$@$@$@$@IJÀ+ím¢Ÿ{À˜tKÏÝ$ƒþ-yüñÇ«îºë.RdI†ÀW‘o ô@ï  õßýèñ+«)þB*'RùêZv~X¬Á<¬.×i;û{躜3f^›%0DÌ×LýõºK`ó«&T³ßIé ÀéðŠ+MäÒ‡d }GÏÝtôèÑ]³gÏ®ºþúëuпBÉhù¯Oüc½_ü£õŸ]þÝ½Ü ñLÅ à‡ÑAXýá@Ñ?"Ž~‹dÉ•W^¹Rz<äIrqf‘©t¿ñ Ýý‚¡Óüè 8L@ëxZ×3Rçs9iYëÎZ‡?K$£^í¯oc^×û»ýk­ÿ)6bsIť鶸GäÐÀ‘Zý²­½®ÃèÑ£g®^½úA׆r;J—°ûŒ—«¿µL$@$@$@$@É@@ëvZÇÓºžëIëÌZw?ýƒþÙumÔ½Qç¶[þ!þQ‡G½^‹Žº¾ëè_+à+­ 8€‡ÕÝß.ºÿë2L×g5À”¿iÓ¦ÙòcÖ®°°°} 禳Ú¯â,Z?Ó„"úÛÊD$@$@$@$T^V‰Lú1Ž/ÂÖ­[Ÿùîw¿{ïÚµk;‹³*Ö!úµRªïþc^-Zÿ`Ë¿@aj˜ óIŵÀÚ °ÌüºÞž×iŒ  ÓòC–Û¶mÛÅgœqFenn®þ¨¹›rKW6Є%`"ú[ÊD$@$@$@$8éÙ"þcLéç]ß»wï›=ôДûï¿¿8›)YÅ=þ°X§ëPáo·þ³µ_€0Å&À@l.©¾T…»?ù—a^mc9{Μ9G‡ ²ºk×®gdff¶õÜ©ù¼ -ícÂë^–ø«þž2‘ †€|é©öâ»);×y—>¼æ¥—^º÷Ö[o="ÎêÀÙþ*ô5ÛÂËlñ¯Â_³Š~YÄ®ÿ éS |Ê‚S'€À?yéq±eö6±‚cB×å=õÔS»ÇŒ³­¬¬lhFFF.â¤-ìb¢%]Lxܼ@tŠH€H€H€bPñ?þgÆTŽ‹±Ò­EGŽÙûæ›oV]uÕUëÅ3 ú§"_>„?l}â_E?²e’â_!0Lí䥜#O0ð#‚¨¢þÀ ÒˆnGj­„µ¤t™æÒI“&ý}åÊ•”ANõ8n§®ÿâcâö…¢w$@$@$@$ ¤ÎV;þ'ÆHÎõ¤ua­kÝX|-•Œúr¬º4‚vÝõqŠ×/¶cþQÙ8vAvüÈàGâ?Zþ~‹õÏ9眙ï¿ÿþÿ:\ÖO]“ ‘±ÿ^÷åÓ…œ"   pŠ€ˆÿº:[×IN¹UŸ3ZÖ:±¬×Ï žì¯?cëÕjÝõpÔËQO—UL$Ð0¾Ð0®=¹Ë¿ÍÝÿau¦Õú³›t™ÚüåË—Ï;vl›¢¢¢~2ïvjÛÏxíLxÓ|ñS_™H€H€H€H€œ! âÌ¿¯÷UθÔ#›7o~ò›ßüæùRV¥l§•K|»»¿=õ±Ä¿@E¶!7¸.E 0¢¾™Å†°Çnö<¦m«Óv†øÇ²tùÁ+…Bo <¸,??¿ì¬Õ @^¡^wÖE:F$@$@$@©H rþ¿¯ÏÕ(ú®]»fÝsÏ=Süñâpºdˆ{´öÛÂËÐòïØÂ¢6<èdü 0æA=£Š÷Æ’½ Ä>–Ùó:µ`ÁÓ¥K—%½zõê–]ÖØÁ¾¾Ý@ãeç˜ð–·î     ¾ð£¾c¼~ÿûöí[üÄOTÝqÇÚ8–#ùtĬîÿÿ¸ë$‰å´³CÄ«ß~a²`ÿz{9¦sf̘qpèСk$ÐG>¨£ŸºÚaÀí+DïH€H€H€R„@øï] J+Ÿû[;sæÌª¯ýëŠÃ…’ýâ_[ûíÖ¬G뿾÷Ñowû—Åu‰â$h$À@ƒx¸ÒGÀõ¾Uu³X¯3ùö4–Ù6úôé;åó€[Ëˡ¤§§»ýy@-Ò£&¼íc"   ˆ3È™7oÐ×ã|ÖS;]MMÍýÜß•W^¹NŽÐV2Ä=ºøÃ"€õ¶ø·þS±Á{jÎq¯”#À@Ê]òÓ.°-òíƒÙË1m }{Ú?&@áÔ©S×ÈgPövìØñÌpX>àêzêx{¸~è @R¨kùˆø¯­­­y÷Ýw«Æ¿@.†=⿊{«?è;ÿxï?Vë?Ä?lR^oªe ¨c"æÀŒZ;ë"“ø±Â~Ì`cE7ËÎ?ÿüÙò=ÔšãL"·õ¤Ë™þb"   ˆ uûW"Z·Õ:®LêxW¨7Wü£û¿]÷ÖiM°Ççø—!Àâêz  •ß¿½Ó¶ÕéXYƒQ…ûÛßž¿üòËsKJJ†øìä¼¾ _Øü¦¸Çß_'¯"  >ýÔŸŽöÿøÚµkž0aB•¼ÿß[fµ± £æ±iþ±Zÿõ¬|*¦f` Y¸¸±„½.¶§ýóüXŽm±6M~ ÛoذáÕsÏ=·HR?ÝÁùÔnñ ÚÊ'ç‹«üvþzÑA   `Pñ?æûò©¿kã÷æÍ›ŸüÎw¾SõÞ{ïõ§µ¡ âb=b1õjÑí½k5 •Ld™d¥S!05ŸÍgÆ=>%` y,Å2ÌÃBäë|CÓ-Í?zôè|ù:@iAAAOÀiÛ¶?ƒN_ :G$@$@$Hÿ½ÿ!0îïØ±cÆwÞY5mÚ4íöŸ)YE=„¾ÚÆÄ?±„¿ìÎD§N€€SgÇ=¨Oðƒ½¾!áíÔf¾óÎ;iÅÅÅ ûôéS‘——W‰ƒ9m%m[iÂæJLV¯™H€H€H€H€N™€Œ ];þ§Æôœ|ʇˆ÷ŽÕÕÕó|ðÁ{ï¾ûî<9wŽdˆØÆÄ?ZýíîÿhùGWSØxçK $ÁEt ï~W°ë1¯¶¾éœ9sæëÞ½û’=ztÉÎÎÖªû©M/-éÌ €ûWŠ’ ¸L NüÿĘn“\öò$ßöíÛ·X>o]uÛm·i ~dˆ~ØXâ_{èz´úÛÂ?VŠÅtê8uvÜódòXêŸ×å¶à·ç±­mu:ï…^8 ¯¬ìÔ©SϬ¬¬RÝÉù¤A€gH`–|AÙH€H€H€H€šL #ËÔN¼Û˜Ê‹š¼K¢7¶¨Ç*,ÓyLDzº¬¾\øè£®“o©îèØ±ãà´´4TÅý”+o-tkB[$pô°ûþÒC   H¯¨ƒ‰^òGcŠ{'àì§vÊcÇŽ}¸hÑ¢ª‰'¾+Gè(¾¡ ¶øWÑïþü°§æ ÷"ô›”L$Ð’ðC¥Ùîʤ?púƒ‡?;"ª£øGÑõضü /\ ßS½¯¶¶60Mê^QWS{ùŸŒ'ƒ2‘ œL@ëHuu%©3%i]Të¤Z7ŸË%£¾j×mu:VýÛÆêúú³]§ ú à"ÐEû ?b ʉ@‚öeC?”ò*Àì¥K—ùr7@IDATþ.‰èg R(·£‰\1ÕxzÂ_:I$@$@$@ñ àµïYWGÒºRP’ÖAµ.ªuRñ¹B2}Sê³þ–­£žŒz³]— ú äBÐMû‡ ?føqSëÔ÷ÉR¬×ÍŠ‘#GÎX±bÅ}â’Yd"—JO€ŠÁr›Î’ @kÐ:Qä²?#u¤ %­ƒj]T|VñÆ,­«¢ÞêïÑŠz¬Z;`×Q_¶ëв9 ´,Z–'v2ûÌþQCÀÀfCV8õXcÆŒùýòåËÿpò)ŸKÏ5‘ÏÝo¢½.pÜQºG$@$@$@­G@ëBZ'2R7 RÒº§ÖAÅç ÉZ'ÕºiCuW¬Óílñ–»Ž¬Óš`Ïñ/ ´ Ø‚0y¨z `À¿X`ÿÃ6XŽyµØFmÚÇ\>cÆŒç.ºè¢¬víÚ µ7tz:œn¼nä_À>ÚµÜiWé ´4èà/™èy?1&œÑÒ‡nÕã­ZµêAí¿ªººz˜œHë£*êÀ+¬°±„¿TøCü£‚²Šâ_!0µZ-|2[ÐÛÓ'ou|Î^¯Óþ¬[é²ôýû÷·—O¯¼0nܸ쒒’õ­¯ÓyÆËÎ6á­:v  $9PÈDF}ËxÃn•‚ÚÕ=÷˽víÚ?]sÍ5UkÖ¬ Þª†‚ð‡Ðe PKüCø£ÅÖ} ô0°ì¥ œãø•W«?n˜÷Ä¿\çýY÷Á²ôÝ»w·•îX/5*»¸¸xÿ€NÏ·Z÷u€ðÆyBEƒÀL$@$@$@$„Ò2LdüOŒ×çK+Üúõë¹é¦›¦,\¸°8Ÿ.Â>–è·—Aø××õŸ•¿ÀÝ Áw˜€à_à •â¾c^­ùÄrl«Ë±NmƦM›ÚÈ€,/K W‚±a ¬|ï6Z6Ø„6Í6¡ZýŸÁD$@$@$@ÉCÀËΗ÷ýcLç W¨ 6üåæ›ož2gΜâ¼¾³ ¢Þùèò«ë €õwû×ú.ê¼~+«˜H õ0ÐzlyäØ Üc¯­©îçÏØZ—gnܸ±pË–-¯œuÖY¹mÚ´ÑîYÁIŒézþñ À±ÃÁñ›ž’ @¼üR½ìcJƒÕIS‹$ LÓn»í¶)2æT7™Í”ìÿv À?­Û6ÖíŸâ_ 1Å—ñåͳ' ‚½) ÛÁú÷ÑåvÎ\½zu¾f}öÙyEEEýý;8=ŸÝÖD{N4ám¯›Ð‘v•Α @c¼¶ÝMíåSPÙØ¦Î­ß¼yó*þŸ~úéÎâ\–d´æ#€X»å]þ h¹Ði&hu ´:bž õ‰zl^ßz~l§۪͔ZóvîÜùêˆ#ò%ÐÏÞÐõéPF¾ñz_ṅËLhßV×Ý¥$@$@$@$“@´ëHt¿ eÇ\ïòBÿýþ÷¿_5}úôNâ'Ä?Zø!øÕb™mý-ÿöˆÿ*ö‘Å¿R`Š+⊛'ó€p÷-Ž9‹mm«ÓÈØIç3e< ¼Ä €~Çëy‰tûŸ ÄU¥%   ºÏü½S>󧽿ƒ•Nˆÿ{Ÿxâ‰Xâßú:mÐCÀßúïÿÔD?l°ÑÛÀ` ð—0ð€ GA0‹åYlk‚÷:€Ä5¼Nç/¿Ð„·Ègù…€Æ®?ד $š@8ÝDÎÿWã ùgñU²D;Õôók·mù÷‰tù‡àÕÀ/þëkõ‡è‡mºsÜ’Zˆ-’‡9-þÿþùú®ÛÙÛb˲¤'@®Œ 𪠘¸µÔí™hÇþ28à\Šèÿ&   p€—%#ý_ü?Æt¿Ô=çšàü;Ñí?[v¨G«?„?æm‹mýïü«Ð×j!úae ÄŸ„RüÏÌ3’ÀÉp/Bće5²ªô›«ÈÚŸL?âïdé´ZdÌcµG¯¸âŠMwÞyçMݺu»Fæ—Bû×™ð‹ÿlBnœït˜H€H€H ¹ xÅå&zñ½ÆkÓ3ÕOýÝ~ûí¿“ÿºH´N©â-ÿèæ€=mêëöOñÈ;"¹f€ä¾¾A+‚§ã7Ž@‚Zý:@ÁòåË_:÷Üs³Š‹‹ƒ÷šìàRª^dBwŸîK$@$@$@-FÀ«h"—|¦,Õúd}âßîþÖ¿ø×‚*ô)þ“Û ®Üö’Þ¥*ÜŸjíì¨x×@Ä}cA ô‡zë[o½5qàÀ7¥§§çÈ|ðRä¨ Ïûž ¯z%x¾Óc   @ˆög¢c~)’YÛU‚—jkk,]ºôw#GŽ|I¼ï$Yë–*ìíZþýâÛÔžØÂßÿZ¯D–ÉOzè4 8CË‡è øàµ:ÝA èq¶ÌŸ?ìàÁƒ¿‘™™Yì;`fCKï7ioN‘8´þ/b"    –f"çÜl¼7¶ÀÁsˆcÇŽ}øÞ{ïÝ7zôè9âAgÉÚRÖ|´îSü ¦ä'q•ü%e ƒL÷iCAí€ìï «G¶Ñ €vÿÚ:kÖ¬³†þììì²ÀÂÚ6ߤ½r» }t0°E ã$@$@$@nðr Lä¢_Sq¾‚555;Þyçûdì§·ewmù×–[ü«ð÷·øc™Ýò¯­ÿšuÍD@‹?¬,bË¿B`r—€ &šâ«þÛÛÇšF0A§Ó%?üðj‰ ¯///‘ÑFW.VÓãb`¡ Ú8÷é0 €êÞ÷¿ìÆ´ä†C§àÅ‘#G6J/Ϫ‰'¾'»w–Œ.üöújíi `ŠÂ| ÿ¦R l!ßX¹›À1pÜ¢G}tãˆ#V—••uÉÊÊ*ŲY…Æëýy‰eï’@Àê@¹NgI€H€H€O Úïp¯1Ù%‰wæ=8pàÀÊÙ³gWÉhÿkäe’!þÑå–âÿs·`` ˜×-•½†Xo  4”ìcé´æÂÇ|û!C–JO€ŠÀ¾ ßäõ*/4^q¹ oyS:©éÿ<&   h€@z†‰Œý7ã ÿ¶Œ’¤oV3íÛ·oñË/¿\uõÕWo—tKüÛ-þ˜FP@[ÿudvûLÉA€€ä¸Ž©V [¸×Wv€ú¶‹u¬ÂéÓ§ïíÚµë;•••¥ò¹@éWÐTÒ×xÝ/0¡ío˜Ð‘-Ý&  hmÚh¹ô÷ÒQþÂÖ>U«¿ººz¾Ôãªn¸á­øhoNóÈø±Zý±â_-„¿Z¾ó/˜‚O€€à_ÃT-A,áîgÑPÿþ˜‡Íá…½Þ£G¢‚‚‚žþƒf^ºïy}å•€ÃLhï†À¸MGI€H€H€âC Úc´‰Nºß˜üNñ9a+eÇŽ3|ðÁ{o»í6­êû ¶ð×i´ôû­-þu;mù§øLÉG€€ä»¦©T"ˆõ–.3Ž›;gΜèG}4kÀ€¹ è×Ò'ŠÛñÂÆëv±ñòóå•€…2>­þOc"  Hii™&2úÛÆ;çßå›Hú¤à¦Í›7?yçwVÝ}÷Ý…R Í*âUÌCÜ«­Oøë:Ý–â_ 0%7’ûú¦Bé Ö›SÖúzÄ:VŽ|:&kíÚµ/Êà€i%%%Cšs"ç¶-l¢•#Mh«¼pôsîÑ!   øð ;J—ÿ*c¤ èIêiç;ß©š6mšvaÈ“ 1oêëöooË–ÿ ß ô¿Q±O£;qpŒîcµv˼¹u4› +k¨[s–Ïb¹ZlÿqûöíËk7žqÆ7¤§§g˺ঙðœï™ðÚ9Á-='  8%ÑžcMtìÏ¥–SpJû»²SmmmÍÊ•+˜4iÒý»wï&~i½ ‚Þnù¯¯õÛª¥øwåÂÒV%áÔª'áÁI p/ÛF@­õ„-ôu:V µÚs`ë¼yóÆ <øFùB@;™t ­zÔ¤½ö?ò/OƒâL$@$@$@IM =ËDFI—ÿ~ÿøbÖÔÔìyï½÷î?ÿüóçJa´å_ë}¶ G ±nÿ*ü‘u ?ø'˜’—_HÞk›Š%Óþæ¦ú^°ƒãêóR"ƒË,—6ë:tèÐ533S˜ nj7P¾0Ö„v¼-_ ØÜrÐs    xm»˜È%¿3¦Ë¸· ÂÊǯ}óÍ7«Æ¿HüÕ¯5i}âÂ6VÛBø«…ðçhÿƒ)y 0¼×6UK±ÞXù›"üõþãé|›©S§n4hвòòò2é PÖØÉœ^ŸÓV¾p¥üÛÜcB»Vÿê´ÃtŽH€H€H ÉB!x…‰N÷ýó:6y7W7Ü·oßâ™3gV]yå•ÄÇrÉ*Þ!èÕªð‡è÷Oë¼½­Š~ŠÀ”:HkJ%µE» }{ÞÏÁØÓþítÇQ[(ߘÝÓ©S§·+++‹óóó»ÅÚ!0ËÂ鯫¼ÀDÛ÷4¡mošÐÇú“‰H€H€H ȼÜB™ð ã ºQ^ŠÔ· ƒvíÚ5ë‰'ž¨úú׿~PJÒ^²-þUÜ#Ç 8 V÷ƒð÷·ükM¨Â_Ê¿$p üÒýz Øb]¸1_ï§°"oÆŒ5‘HdNß¾}³ý™@¾Mí}© }¸Â„öoÇRZ   €ˆV—Qþ0¡ÒAó<¶»ú™¿{î¹gÊwÜ¡ã6µ‘\ŸøÕêo·üSüÇFÌ¥)B€€¹Ð)ZLˆ~µM‰ÞbXŽ…e:¯9gÁ‚2ÍógŸ}¶×¶mÛ!!IØ(ˆ6”‘o¼Þ“—“kÂÛß5&ªÿ'™H€H€H€A #ÛDFËx£`Bå_y{ž}ÿý÷ÿøÍo~sÊã?ÞIåK†ø‡°÷·üÛ=Ðòá¯V[ýí–¼÷/‹?©3ƪêz&4@ •@“§óñ"€{ܶúE;kŸ8 †©Å¨ÿþ/Ø_ À:l«ûé?‘-2 ÍxùLà×rräÅú$H¡ýëLø•Ûel€ÕIPH€H€’›€×¡‰Ž¿ÓxE=’¢ GŽÙ+Ÿùûã9çœóЍ³d­¯AüCØûÅ?æau;tû×úšî¯‚ßÎû~+›1‘@r`€äºž,Mlÿþµø‘÷/Ç|cë±Z ÿñ\vâ ]ä Ád—Ô è¥3áK4 o—™Ó$@$@$@.HK3‘³þ‰^ðßÒ71øÕE*#ý¯Ñ‘þ/¼ðÂ…2[)Yësó~ñ¯bßnõ×y{[ýš5 -þ°vÇž–M™H ¹0\ד¥©Ÿ@¬ @¬eøÑ÷[=2–ùÏ‚ã¨-Ö/ 0àÝŽ;–æææj´:Ø)$%ÊÏ1Ñ.ç˜ÐNý\à`—‡Þ“ @ðJ*äó~2ÂÏÉ"‘µƒcðÓÞ½{ß|饗î½êª«6Ki*$£å>–ðoHü£·„?Åðo–à4 0pš¹{ @¨7æ´-ô1 kï‹ãù×=õÔSû _ëÚµkŽØ>öN–Oy}¯’øùÞ㟠lAè8 $ý¼ßLt¢ˆÿ‚NÉP º2lݺõ™‡zhÊ­·Þªâ½T²Š~y´ìûE?Zÿ Àöjýâßnõ·ëpö´ìÆDÉI€€ä¼®,Uà ÜcmÕœ{[{Z›7gγfÍšç‡ b’apÀ:Xø\`YڱЄŽ~‹!—‘ ´"¯°ÔD&Þe¼×%Åçý• öç­^½úÁï~÷»÷Þÿýú‰¿BÉòö°ü°³®×¬û!£Õ_…,ñï¯ÃÉfL$¼BÉ[j–Œ>ý, >ÈöÀ€Ó¬ïö7gp@ ¨V÷Ó>[æÏŸ?nРA×eeeuùäHµ™ð[¿0á¥Osl€ä¸¢, €ëäCCÑW˜èٷ˰Å:~r¤£GîZ²dÉC£G~UJÔY2êPôþþ–ÿ†Ä?Zþ!ü)þ“ãva)N“{œ&@îh±` E±…÷Ïc¹ZýVò¿ÿû¿ËGŒ±²C‡eÙÙÙÉg¯òB­$c,6¡šƒv¹9M$@$@$Ђ¼6e&rñ¯ÿW¥‰B?H”iÿþýKfÏž]uñÅÿ]JÔE²ÖÏì–ÿÆÄ?Ö£Å_-Ä¿Z¿ðG½ V6a"Ô!À@ê\k–46XAl‰ °X®Ö¿Ì?oo«= ŠåÛµÛ+**ÞêÒ¥Ka^^^{ƒ@OTûNŒ Њ@—”Γ @ü ÈÀ~Ñ!W™è„{)êÿó·âwïÞý²Ôª®¿þúä4å’U°Û­þ÷õµüÛÛ"ñ–­˜ØYf?SÓeL$H‰ËÌB6B ¡ €½+”­ßb,Ǽß̘1ãèž={fžqÆa`ƒÀÎëØÇÈ—Î’Þ‹ø¥€À^H:N$@$௤“‰LúµÚ¯IšwýÁWÆIzäÇ?þñ”»îº+O–•Hö·ú7Uüc?´ú³å°iIÀ"ÐTácíÂIHJx`µÕ^§ýãh—~d}Ï_ûàÁê4r–µÜ?.ÀQé°ð•W^¹®_¿~_•Wt„ÛäI‘^ø+~ošÄñõ0 @³¤¥™èà/šè™ß•îþÙÍÚÕõkjjªW¬Xñðøñã:|øð™â¯Ö™ âÑ¢¯-þ:k°?Ô¢Õ_­-ü!þÕjB# ìñ¥üK)Hb'‹Î"“Àgày°­Ð3ÈÀ@õ Àzt_=ǶéÓ§÷–oþ©¨¨h°Ì'WڳܤÍý¼ð~r•‹¥!  V$àµïe"clL»­x–ÄZÞ÷OFþÓ¾ð­THVAKük V†øÇ>þhý·…?ľßÊ¡™H u ð€Ô½ö,ylÿ±×~A޵ÿ`b­ó/ÓóO›6mGÇŽßèܹs^AAA/ÿFžÏmo¼¾W/7ׄw¼'qyýŸÍD$@$@$“@f®‰Œú¿&zþÏäcÂcnä…;vìxñ±Ç«úÚ×¾ö¡”£L²Švy­$@ÜÇþº Û¨ÕýcµükÌ®—ÙӲЉR—©{íYòú 4Àžøg«Ëíil×ÍŸ9sæÇ›7o~aàÀ‘âââáp8yžK¸È´j"}/3¡ƒMèÃÍ ±à:  HIÑç™ÚK/mâçIAí|˜<)‰“÷ýüÞ÷¾7å׿þu)Y±dˆw[Ô×'üëÿv«¿¶ü£õ_ëbv}Ìž–UL$Úš*tR›KŸªð|¨EÖÿÊ:­"]§µ;¿Nã•tóG·¼` €uº­î§Yÿn}õÕWÏ>|øWrrrºË|ò¥M/›´×~aBª“¯l, 4“€WXj"ç}O>~wQ3÷ ÆæGŽYÿÎ;ïüyܸqoŠÇ$£Î£õˆ·ßù×ùXâ=Tðë´ üXâŸÂ_À0‘€Ÿ@ò´4úKÆyh4v4ý'cÿ£‰5oÃÞV—ë?ÄvúÓŸÖôîÝ{qYYY‘ ØUW$UjÓÃxýä“ÑC26À )šCR•–…!  ØôÓ~Ce¿‰¿•ñïûÆÞ&àK«««ç>÷ÜsS®¼òÊõR”.'Šc·üCøÃÚâË$P«û¢Õ_­Š~¿ðGÅV6a"° 0`Óà4 Ä&ÐXÀÿOÆž·§ýG×uþõEO?ýôÁC‡ÍìÛ·oH^ HžO¢ôá ùdàù&Ú}Œ¼°B^ `o ¡% H~^Ç3äÓ~¿5^Ÿ«¤/¡vL¾´~ýúGî¼óΪüàÚÀ¡_;Š%üѱo[¿ðÇþ¶ð§øO¾[‡%ŠÆ„M\à)H ð¬Ø¯¨Õ`²þ³ÓŒ×Ô¢Û?^ °­½ö=š™™¹@>øƒ úGy% ³# SÔ„ÞŸnÂoþÆ„é˜@L$@$@$œ¼übyËqá_÷aò•SºüoY²dÉ#ò‰¿GŽ;v¶”ŸøSo‹z[ìc{;[ø£õÂVA¢AV—1‘ Ä À1 p ÔCÀÿ±6Á?Ƭ_lo/ÏAsº=øàƒ« ð÷öíÛË+•öÉ1-HÛö“פē×ö¬’Î|±p$GiY   $žf¢ƒÿáxwÿêÉÅBºü¿.W]vÙe«¤3PJ§ $ðõû Yl‹}mᯢ¿M.°, ´0Z(—ôú¯mÿòOë<–)$ÌÇZˆz®¢éÓ§X[[ûj¯^½ô•ý‡š|)-«îµ¯ç8Úÿ¾äÉWF–ˆH€H åx•CMôsÒÝ¿÷¤Ÿ 6†'gÚ°aã÷ÜsÏ”Ûo¿]Åy{É*ÚÑêïûú®?²],ñ¯ÇÔãiÉÿþ:”¬f"hŒ@Cb¦±}¹žR™žµvÖhwS_ °_°_À+x@uúrÛk¯½v¾|.ðËòJ@7™OÞ´á“6ÿ¿ùµ€ä½Â, $5¯°‰Žúãu¿$©Ë)]þ7,]ºôÑóÎ;ož´B²F9T¬«G@§UèÃÖ'ú±î‡Vµ*úýÂâV6a"h öh %nC± {í§-þøç«ÛcZ-2ŽãŸ×åh'¯¬–ž‹ÊËËósss“7PÜËxý¿d¼´c&¼{¥üÛ×ÿÿL$@$@$à8ŒLñ&zÑoê^qsÜÛÓroÏž=³ž}öÙ)“'O^'ê"]þUÈÇûhõW‹ ¶%þ!ü)þ ´ZŠ$“ªì € w$ÿ4æë³ºŸ®ÃzÇo‹žyæ™C»wï~±OŸ>‘6mÚœ‡µ§@ò%-VŹÒmòRcŽl3¡6&_Y"  ä µhï±ÒÝ¿ÊxÝ.)œœÿšõbÉk‰5ï¿ÿþŸî¸ãŽªŸþô§Ù²ÈåßnõG¢߶è~hùWÁ–­! “ŸÔ“«/é¶L$@1Øâ%Æj."hû9Òid¼ÐØ+v÷ÿXÓx%@­Ö(4p§ÿ0·½ôÒKC‡ vMaaarŽ …ü$ízG^ ø… í\ýÉ"N @¢ xû˜ÈèÛépf¢]iõó8p`éâÅ‹ÿ2qâÄwåd’µn¢bÝ/ü!þUìÇšÖešmá¯ÇðGë?GlÁoOË.L$@Í!ÀÍ¡ÅmI ~vÀÞ ÿ¤`u¦m«ÓÈØë1¯Ë4Ðî‘GÙܶmÛ×:wîœ)A€¾ö†I7_^÷µ¯¸Ì„ªW˜ÐÑÃIWDˆH€H 8¼ÂRs»‰ŽþOcò;ÇñSôtëÖ­OK½£êºë®Û+‡è|â0õ »›¿¿@SÄ?êD°ðõ ÌÓ’ 4“@}¢¥™‡áæ$@'à™B/ØX½TÄ#£•ßßÀžÇ6è €Þ‡åS+xà«Ï8㌫³³³+’þjDŽšÐ²MÚ¢‡Œ©a é¯7 H$@.ÈÎ3‘a_5Þ ë“zd ¯©©Ù¶råÊÇn¸á†Ç–-[ÖO–çIÖ–z´ÞCЫõ·øÛóØû©ÕãhF‹?ºûCøCðÃʦL$@§CbåtŽÁ}I€N&€çʶÐy´÷fÔÚßþö´½ èɳ}êÔ©ecÆŒ¹¦´´tŒ/ùSÍ>~ç×&¼ìi©†h½‚‰H€H€Z‰@zº‰˜l¢Ã¿eLv›V:‰[‡­®®ž+é/×^{íñ¬ü„wÿô°¶Ø·§±^mCâ_E>z*ˆ~X]ÆD$pš Nó0ÜHÀGÀÿ¾UŸÌê?4ûŸæauC{Ú?oï«…6Ó§Oß/¾Ð·oßc2@`o 0y?:¬4Ò³W9V üœ|(q T&L$@$@-K@þ£GûŒ3Ñ‹c¼^WÔýïiÙ¸w4èïàš5kêúûÑ~¤ $«8W¯BÞø:lw÷·_ˆ%þíVÔmüVNÁD$Ð RZâX< ÀÉìçK§íl÷Ðitç÷÷кv{½°zè?ÙíO=õT¿‘#G~©¤¤d„̧Fڻ„ßúoÞ¸05ÊËR’ ´*h—&zο&ý'ýlˆ|ðÁ¢·ÞzkÚç?ÿù²¼\²Ö7Ð]B^­f À^†mÔbµ*öínÿh쀕Õu AÌÓ’ ´öhˆ< 4BÀø7õÿsÃ??¿Õý° Ó¶Õi$ ”L›6m‡ôx¥k×®Q °¿Lk !¹Sn©ô¸ÂD; 5¡ýëLèPur——¥# h^Y?¹ègÆ~‹1ò¿%RDÒÆ2eJÕ­·Þú‘”¹B²ÖaT´k† ·[ûuº¾V þñ¾¿Z­ÓØ­þ±ê8²  @KhH˜´ô¹x<HexÖl«Óè  VrÈ*â‘ÑÒo·þÛÓX¯ûÀ‘eÛgΜ9bÈ!_***JþÏJ?I›^1ioßkB»×}²ˆ$@$@$P¯}9KD—ñõm’”Ë÷ïß¿ôïÿû´ &,’–KΑ á‹€Zˆ{µö4¶Á>~ñowû%úu @+`€V„ËC“€Ä¿oqݬýOP`ÞþGh/³§ííëfýÑ @»?ÿùÏ æÈçC26@k}rO¶én¼þ_4^».&´w• ÕLîò²t$@$@§DÀ+®0Ñ ¾/ŸôûQ§Ç)#¨;mÚ´éñ‡z¨êúë¯×ÏûUJÖF [ÀCðCì××âñKükýÅßò/‹ê’]çÁ2Z &Ð iáSñp$@BÀ~ætÚÎõ°[úuÚß óؽÔj°ï£ÌÌÌ·g̘ñü¢¼ ŸòI˜ÐÚ§LxÑ&ôá¶Ô)7KJ$@$P/:á?âãõü¼ÈÞÔj;pàÀŠ¥K—>~ñÅ?qìØ±³R®dížïÿôþ–~Ìc½Zìkw÷Õê† Ù¥.Qüƒ- ´2Ôú¥ke˜<< 4ƒ€°ÿéaV‰iµþì_yÿ>ºT§?E@D@º¼ ¦þü[íÿÛŠòŽ¿Ýå?€gýí@?ÿò—¿ŒOäœ`™wý)ø½Øç~ÄèÓ"ƶÿ´þ\öÏëZÛ´!¡¬$"Ð í0,íRŠŽÿ/z‹(Ã2cÒ?Ø´¼»Ï•°±U¾Û°ôƒOýlúýï?cæÌ™WÛK§[¹S}’[ýlR²ø¾$Wùa¿YD@ºüГ’úé7&ùñ—ÚÁá§´øÒÎ;/Z´èñÏ~ö³oÚѰÌgý!Ö)Üý}úù´ŒÃr;öþ¼óo͸A²’ˆ@;Ð €v¯ÝŠ@„ÅXågÉ9ƒžóõôÑ}nG‹:L ~øá‡×çóùçíKûlUÀ‰¶«Š(þþ“üÔk“ú‘§Ù´Èæ$W½ÙŽß£*":Tè´rI~Ìôäàœï'ùO~»áÜ~h>½ÓP‹~àÀš•+Wþêg–nºé&|g¬e\ûS´SÐCàûÌ;ý´¾Î‹? À;þýøñd6·!é•$dE  ¤ Žv’v-EMÀÿŸ„fܾÀ7-|ÞÑ­H[À¶Üý ×YÞôë_ÿzò¬Y³¾0xðàÙV.Þ´u‰­¸7)YùŠ]ÆàzIID@D ÃÈ—ÔO˜mwüÿÏ¡eþv m?°ªªª .üõ¾ð…å¶·–{XÆÅ?Ä;żŸ€ÁϘ·ü°ì ‚~Lø{Áï}k®$"Ð^pÁ¯$"Ðñø‰€´MÆa[šqäì>& =ú裕7n|zâĉ»íÝcºuëÖ•E—z Iò'^–ä']f—6»“Üö5fq£$" "Ðat+Mê§~6©¿än[Åu-pÒa†v¬RWWW±bÅŠû¿ÿýïÿÌ2~ßG[ÆMüxQôSäû;ûðcwüÙ†¡øÝù·®¯-ü5âJ" íLÀ‹ŒvŠv/"ðÿ?c+ðƒîWð.>D<ïìóÙ¾À¯`]ÚjüÈoºï¾û†~êSŸºjøðᦂ‹;å÷nMŽ{çIÉ’ßÚZ |HAID@D Ýô(KêOþ|rð´¯$¹žƒÚmeÇ›7o~æOúÓon¼ñÆJÓËø}‡ð§øç-E=D~ÌG;¶e?´1á±ï¿÷­JID #ð£#ŒGcø[üÊI´€ðG™“~"€âŸ–BŸÖO0FËm0™vÇØ±c—þ÷ÿ÷U'Ÿ|òUåååÓ,VÜi¿­Xö«¤äÝGìëÅÍBG/" ǘ@¾ß°¤þÔk“ü”/Ùºµâ\ æ‘×ÔÔ,]²dÉoþþïÿþ7ö¦üF÷·LÑOK!O¡ï­Ÿ`œâŸ6Møc"É‹ ÿCLô§tHz CþµhP"ð78 VøYúü.Ä¢¿°÷ÁþzVWW¾ÿþûWvïÞý[ °ÿðK1‘Pœé8;ô¡3’üÉ×'ùÁã’\­½0°_URh+ùÓ’úsÿ¯åÛ“dØL›¢.ÞŸ!0¶—üí^µjÕ#¶Rïžø‡Øb¿ÕS,Œgý)öi)ða™ YîÉô‘&þyý`MïüóÚ1%H MTtÀ¡jH"PôüÿWøaæj> @Ë»ú¸ËŸwûaÓVpZö…On~ä‘G&žsÎ9Ÿ·—^`e%¨z7)yçþ¤äÃùv©„k&%£&pÜñIýIç'õ§ýoû^}¡E©€½äïÅW_}õ·×^{ín9öi?Þ½ç]}o9)À' ¸ E?-—üSô{Ë¿‰’LÀ ŠNODàHþÿ.|ŸÃ‰/Ü)è!üáÇ&¸*À×s;ô?üá»Ùg†æŽ=z®}- ÌbJ ?äV=“”,µ÷lx×ʼN(\.É:5©ŸfÏ÷ÛX’~n”@À–û×®_¿þ ûLïßýîw!Ö‡Yæo1Ê^üSìs ¼ÛÖSüSøÓRðÓ⇌Ù܆¤7’NBÀ‹ˆN2d SDÀàÿaoᇓ\ @ñNA›à'Жí¸ûÁÅÇnËx,`ÒìÙ³¯4hÐ…VVrr;W&¹÷LJVa<šä*ðØ¦’ˆ€/ü°‰¶Ìÿ‹I~Â\ûE»ë”<]»v½¿lÙ²'±Üß&ÆYž…ðŸÂÝ zŠþ,KáËþ(úaC᯻þEIº /ºÊ1é8D X ðÿ³·ð!üÓ&ü$~Ö$€ŸðÛrw *n½õÖƒ×]wÝöùÀ+zô衇7cÿ"ñÒÀ¥%%¼`ïdÆË˜•D@D ”v·—ú}Ê„ÿ &gO-‚nþ!ÖÕÕUÙçüžzøá‡ŸºãŽ;ðûŠåþø§X÷ž~–àgÛÒ²?Þõ§ð×]ÿæÿµi è4(:Í€5PLþÿ4|ŸÓ&x'ß úB&üdûàD¾Pñ‹_üb˜½,ðŠ‘#G^‘³”9òb­ÜW“ä>´UË~«UÅúo@Ç-E@ ?ô¤¤~êUIþ$»Û_Z^GÜüCÌ[Ú¸qãSör¿§¾ò•¯TXþáÛý!Ú)à!ìáSà§Y¶§¥ð‡ Å?ïöÓZ“†„²’ˆ@   ò.ð—¨C€€ÿM™“°ë´^Às%mÚdëýÄ|N ï–7?ýôÓ3Î8ãŒËí³³­¬”F`Û²¤äýÿg«ž·¯ Ô¤µR\D@:žåIýÄO›ðÿ_I2Ÿ¨WJ#`Ÿõ[ðÖ[o=}ùå—¿imðœ?Ëç^ôSÄ"þÑ–íØÅ?ûæÝ~Z }Zë¢ñ¹øJ" œÅA'? _D BÀÿÿæmÚDûìHk7Ô2Źí^ÌSÔÃÆ²o ß÷þ)øiyÇ_Â߀)‰@W&àBW>N›+ÿœ~lÀ¯à|NÐÆ&PÇ8}¶÷è ßúÖ·ö_ýõ—Ÿx≟³÷àbG)ƒ@~ïV[ðë¤dùï“\Õꌖªö#<>©ŸüY»ãÿ…$ן¦WÊ"`Ïùo\µjÕïzè¡§ï¾ûnüŽb¹?~7)нp÷‚ž‚Ÿ1–i÷¿½>£Š~ZŠ~Zk¢»þ€ $]‘AW<6“ˆÀÿðÿ×9à-:3'¼€÷â>ü,Ãúv~"À÷¹×ÚUüä'?éû™Ï|æòÑ£G®[·nø¤‘Rr;–'¹OÚ;žOrÕ•M´Vµˆ€´-|ß¡öLÿÅI~ÒÜ$ßrÛô~àÀÝëׯÿÝsÏ=÷ô׿þõj;,ÿž–½H‡ïE<Ä}Lðû}Xnïû¤ð÷¢_wý –’/ ŠíØu¼"PŒøÞ[øÿ´iô^ä{ñOß×ûmü$ü]–7ÛÝÏ>ûìˆþY½(Јš*ßHJ0°r~’ÛƒkH%h{ù^}í³}s’úIWÚbõ3Û~‡]dxÁßæÍ›ÿÚk¯=c«àVÙaá9ÿ>–½H§p‡ˆgNÿ>ζ´¾ÏPøû ÛMã~÷q%.J€" ‹žKD BÀÿ¿‡fNÐR¸CÌç¨÷wüCñïËlOËþ`±m–+žzê©é–>g/ <ßÊJ…Àû6¾d“O'%«Ø'±ÀBID@Z‘@iϤ~ülû|ßç’dôvæÆé[©Pö‚¿—/^ü»+®¸b±mƒ;þ-Cˆ{¡Nñî-—õ{±ÏÚ1Ÿ“ìÓ /úu×ß`)‰@1ðB ˜9èØE  ðÿ¿·œ  ø÷–⟖‚Ö ~ú°¬ómá³Xì¶ræÌ™«ïºë®ËìE— 8ðSjƒuInµ½<ÐrÉÚ74Ðvj+"p$ˆþ±g&ùñ—4ää¸GÖ«Ô$mÛ¶ýÕ^ð÷ÌÍ7ßüÌ¢E‹ÆÛxÁ:Å¿î¡ð§À¿ýÜÆ‹ÿPø‡âãæÝ~ZÄ”D@Š„/ü‹äpu˜"  øGˆr–9 àźñ÷^ð§ùlK‹>}Æ…Jå•W^¹Å^x)&úöí{šÅ”šKÀ&’uNJVý1)YóZ’|\ÛÜÔ^D Øt/KêÇÔŸxq’Œ¹ÐÎÎý-ù'P]]ý„¿½ÜïÙ'Ÿ|rˆõáßRÞ§¥€§¥¸Oý¬gûPø£Ì ÞéG‰åC¥ÿ™`YVD Hø‹ÿ"9d¦ˆ@„€?Pø{ËIج‰/ü!òQö1úœ€E´ì7•óæÍ«¹é¦›.³/\V^^>ÉbJ-!`ŸL6¼l ÏIø±‰ŠwZ/òéÃzmY†ÏmýjìkŸåÊo|ãøtà¥ãÇ¿´¬¬ìD‹)µ”Þ°ù/IÉÊg’ÜG¯&¹š­-íIÛ‰€tRùòAIþ„s’ú —Ù«è>igvœz•ZJ ¶¶vÕêÕ«Ÿ}衇žýñŒß6ÿRË^øC¤#‡¢ŸâŸ–BŸ–qnK˾)úa!îi)ôi­ªqé?|%"%À‹ü"=|¶ˆ@„€?/pÀ[?À;ö°ñôÞfMø‰ßï{¯õ_ùï|§äꫯþŒM|¦gÏž'DÆ®Ps l[fö˜ÀG¯$¹Šåvy诛ۙڋ€tH¹\’:É–÷ŸgÂÿb{Ý”9ÌÎ6¨½{÷~dÂÿ¹Çü¹ýèGÞþü¤Ê^ôS¸SЧY/üц™ÛòoŠ}ZœÀ}¶bCÒ‰$dE@îè ƒˆ€Äp"ÀÛp"€+¼X§ˆ÷ô³&؆ýøŒ}í±\yûí·ùå—c"à›¼b- P·=É­}!É­™Ÿ”¬ÓÞÜJ" ’@÷^IýèI~Üœ$?ö¢$é1 SFG´ ÿµ&üÿðôÓO?wÛm·A°Cø÷²LaNáOÑNOK‘ï-}¶ñ–ý±Xf/ø)ôCkÍ•D@Dà^Ø‹‡ˆ€Äøs}Nø•œ€õ¢b>´¼ë›ðm}_ô±¼Ñ¥6pÉቀ,¦ÔZòví¹ñ5{àü$·þ/InûúÖêYýˆ€´ü€QI~ô'íNÿ…I2òl{p §S¥Ö"pøŽ?„ÿLøã5ÿ2Ëæê´^Äçȇõ~ØŽeöKÁO ‘Ÿæ±ÄŸ“ˆ+‰€ˆ@#^Ð7䈀ˆ@„€?Wp ´i“î¸ ¥¥øGŒ~hý$€ß}p’[¾÷½ï7wîÜKìeX0ÞÚ(µ2|íf[ðR’[gï X¿8Éí­nå=¨;æÈ÷ìk‚z’u–}²oN’+ÞÜ.Ô¾&üWÛËýþðÄOüá?øÄ8Þìï…?' ÜQOïm(øYFúÜÖgŠ~/ø)üim“†$áO²" Qþ¢>Ú@ApxÎðÖOøI uˆvf/曚à¤'8À¾Ø?lã·ÜrKîšk®ù´­¸Ø^¨¯¸¿¸Vw·.±É€—’’ “ÜÆ÷ìR7ÔD@Ú”Àq¥I~ä)Iý¨YI~ÌùI2hªí§@¥¶ `/÷[aKýÿøØc=çwBX‡Ký)ü½p‰~/ò)öiQç·Oþ1ñæà§ELID@R ð">µ*D@D àÏôÃI”qUêE:…{8 @OÁZÖÓ†(s_˜ØòOÿôOûÿîïþîbLôíÛ÷‹)µ%uIR±ÐVØê€Mo%¹Êír×¶J" GEÀ>É—zR’q†=ÏN’ ›eë©zU—Ú¸iÕÕÕïAøÿò—¿üãÏþsü&áŽ?Ÿñ÷¢ß w/üéS䇖õ1ñÏþa)úi!ò)ôi-Ôƒ¯$" ™xñžÙH•" "!àÏœ@3ŠZŠsNp"€BžÂÞÛ´IÄýv¾/øÜ—)ÒdËu×]·Ë&>}ÒI']ܯ_¿S:&þšä6ÿ5)Ùø¦YûºÀ­8èµNN ›Ýá>9©n/ïù ü–%øÙ_êÎ;ßüðÃ!úŸøá‡ûØŽ!ü1ãB1îïÎSüSÄSäSܳL˸·aÜ-D>Å¿¹ B_Â$”D@ZLÀ_À·¸m("PÔüy~,S˜s€–bž–“œ@9ÍG·ƒefß°P[æÌ™SùÝï~÷¢É“'_4xðàs-¦t, `5À{oÀÆ¿$%›lB â}ûÂÀÞc9íK:&î=“ü°©IýþOšÜœng2œò”Ž%ªªªW–/_þÂøÃæÏŸeþþ¥–!¾!Òi)Ø)ú½˜÷B?Í÷Û±/ö Ë ‘ËnH~€1Y(ˆ€¿p/h5<Ÿxë' ÈÃLÑNË €ÐfM2€‹®ª±cÇ®üÉO~rÑgœqÑ!C.:ÎRʱ(Ü–êíºwÇ [ðF’Ûò®Ù¥InÇF»Üŵ¯’tQ¹’$ߤÝ៖䇜jöÌ$éo¯*)Ñi¨=þÆZÚ²eË o½õÖ _ÿú×_X»víÇ`ËøMñ¢œBÖ øBÄ¿oÃm}üÞ†ÂßvÛ¸Ä_Â4”D@ŽŠ/Ôªm," ‡ øs ýpe?€«_”ý$üp声.’-È>øà¤Y³f]8lذO•––êÙ Óži_½GÀVTÚJŠw“’-Ø«õ¥öü+Ѿ’@¯¾Iý‰v‡ßÄþP»³?ÌžB*-?ÊNµùÑØ·oßöŠŠŠ?-\¸ðÏ7Üpà ëwû‘‘ÚBøû‰ø~þöð½ø·b£ð}”•D@D ExÞ¢µ‘ˆ€¤ðçú°ÌüðÉNÐBô‡“~ œðí¹,'üþ¶Y¼ÊV ºð çŒ3æB}BЈt ”«þèУUï'¹*[1°u•&:Ð߆â˜ØÏ:1ÉždÙÞÌoKùó}Op ä¶7|Êoݺu¶4ßîøoµñànÿ@Ëá^˜{ÑÎ;÷þn¾_âxXöÛÃ÷ÙïOÂßà(‰€[¼0?¶{ÕÞD@Š…€?ÇPüãØ)þCëÅ:|f{fÄÂI€p"m|{öCë'vYÛª›nº©þú믿оp¡½0Ðn×)uD¹ÚMI lµÇ¶,3»2ÉÕØµ|^+c;âßWWS¾Ï`ûlÿ³Ó’–ó—芇Ú%ŽÉ^ì·ØÞèÿç‡zèÏ÷ÜsÎýþxÁŸâ^ Ó§àG™~(ô)þ}ÄØ­Ÿ\ð¢qž¼`é›{„²’ˆ€´ qÞ*ªˆðçø±ìE9} v zZŠûB-·óýa(s_x+]Õyç‡^0uêÔ9¼À^€É¥ŽL`Ÿ=*°å$·ÝV l· mkìë’d¯=V $-%гܞÙ“äŽKb:òÙ&øIDATòLð°çõ‡œfËøû¶´GmwŒØãýû·mÛöâûï¿?ß^ì÷âË/¿ŒûAø÷´LáqNaN¡NñNÁß‹>¸=ûã¾¼¥Ð­mÞü$c²" "ÐjüEy«uªŽD@D …Ï9Þ†“ä´éïýð ÿlÇmØ·Ü,.ܰد·ðqá‡Çª~úÓŸŽ¸à‚ Î5jÔùeee-¦T 0A`“Én[5P³É&6'IÍæ$W[e±­InïÎ$©Ó$A«þSèaâ¾g?÷ƒìe{¦ïʇ›Ø·\nOåôÕ ô“ã{·ê.ÕYÇ%P[[ûÁ† ^zñÅ_þÚ×¾fËvD¸ÌçjŠsZ ~ x–cb?ŒanGŸýJøwÜ.™ˆ@„/¶#U ‰€ˆÀ1%àÏGôý$|ˆpZø^ SÄs ´û1¶õ}ù}pŸ°¦ô’­×^{mí7ÞxÞ”)Sε—žk/ ìnq¥b&p .Éí©Lòµ6!`óE{,Ûc¹=öOÆÊ¹:{ia½ ðãš$÷±M(Û„}wìÈ=ú$ùöR½ž&î{™ÈÇrü^æ[9W6Ìböî¶n=Šù_“ŽÝØKý>¶—ú½²lÙ²Wî»ï¾—y䬾‚è·4Ñ»ýçë^ìSȇ"ß—ÙÆ[öž%ü ¾’ˆ@ç#À‹ìÎ7rXD «ðç%ú°>C€£ì9D;Ê^¼‡Â>¼óN„í}_ìÛï>ž7Ýf¹ê¿þë¿ÆžuÖY³GŒqnyy¹½2\I P0ɼ3)ùxG’ßg–& öí²¯‹ÛÁþ:{RÙ&öÙ“(õöÏm¿Y+'÷ŽÙcÊûì#?¶zhûÏrúÄÒA³hŸ–Jì¿Áñ¥GÖZ,¼›Ë*±ÿ ˜Û*µ—¨—ŸäKm•5>q~¼ù%¥‡b eÄLÜ—÷¥åIÎr}÷þI®»é5ô¥$¨©©Y±iÓ¦W^ýõÿøÿ¸Ö6Áÿ–ñÖ pøøÇOK±^¨ðG{NÐg´ìÛïWKý œ’ˆ@ç"€ h%èˆüù‰>¬Ïà(‡¢Ü wï§M MÖd€ïûB9Ü'Êv‹7ÙzÕUWÕ|õ«_=qâÄsí]³í]¦†”D@D@š"`Ïöï¶gû|ðÁ¯Ü{ï½ ~ó›ß”Û6iwû½(§P§õâŸâ¾©· ­ýð%ü›ú‹T½ˆ@‡%À‹ê;@ LD è øó}XŸ!¾QE9…ºð~q/üÓÊŒû~°/”½å8ðæh¬ Øz÷Ýw9ÿüóϱ/œm_˜n1%€€½É±½Éÿµ—^zéÕo}ë[[¬¢wûñE îPð³LÁî>bYŸõÞ²ö ë3Çë³õV@Pèøx1ÝñGªŠ€;¾¢ë38l˜½x÷¾ŸàdêéûzÆýöØÊÞÂǸ`mw²Í¾°ñ{ßûÞÙ§žzêÙÆ ;»gÏžc,®$" EK`ïÞ½ë***^{÷Ýw_ûÁ~ðš½Ñß>ßÐ úû˜…ð¦à†qZ ö– nï-öfŽÃ‹~øH´¡ßP©?D@D £àEtG—Æ#" iüy‹>l˜!¾½EºñùˆQø{Ÿõ¡õ}Ðç~QöûÇ¥}€>Ùvã7ÖéK_:kÒ¤Ig0àl{DK\•D@D Ë°%þ5Û·omÅŠ¯ýêW¿zÝ^ê‡ó$îôÛ Ι8WRpSô#æEº÷ ÿ܆íYfßÞrÿ Ê>[Q”D@:^'²&ü6l¾9 @ËýÑbŒöÚ÷C“v'ì¤3f|Ò¾"pVß¾}O±¸’ˆ€tZÕÕÕïÙ[ü_óÍ7ÿb+Ÿ>´¡èǪ' m/¾½ ÷BÝ‹w/æ³Ä?Ú¥åpŸ,S臈1yŸ1Yèx±Ü)«AŠ€ˆ@>£K¢›eúâ°é^Ì{ŸÂ¾Pë· û÷û…qÁbUÀö“O>¹â_þå_>qúé§Ï>|ø¬²²2}RÐÀ(‰€t|µµµ+6oÞ¼ðí·ß^øïÿþï]²dÉ05îô#ChCÃÅêËÛíñ€ÿüÏÿ<Ë^xæ!C>a“'Y\ID@: ýnÙ²å¯ö2¿7~ö³Ÿ-´eþýmpü°8÷QpǬç1á~4¢Ÿ}ÇöKÁËlî>ÊH~àPDŠ€ˆ@'%^(wÒÃаE@D JÀŸãèÆÂ1 pZ\¸ÂÅ;'g9Ͳ]hÙ7÷ç-ǃ‹ß†É€9sæì²É€3m…À'l2àLM%v!pXô¿awøÿj¢ÿùóçãÍýý8BtSd‡œÂ<&økJø‡í°Æè‡ûåx(ø½µÍú¨S.G˜J" "ÐÕ øs}ØX¦G](Ð!àóbžÂ±˜ïc~;úì“û-ÇrÄdÀW¿úÕ™Ó¦M›9tèЙ}úô™bûV6#°k×®e•••‹–.]ºèÞ{ï]ÔLÑïE9…z̆Âm }nïûö>?b^ì{¼¼Ø÷>ê”D@D KÀE¥’ˆ€ ΣK›eØPˆ³ áŸ>f½è§Okïûdßܬ|Nì°U·ÞzëL{L`æ°aÃfØ O·z%8jö"¿·+**Þ´åý‹î¸ãŽEvǰuŠ¥ýÈ8§A0C`SdÓ‡…@-E{h)òiQïý°=ʾo¿_ú^è#†Äý†àá8}Yè²p©$" ÅFÀŸûè{ ™Â›¾äðc¢=÷^ô§ùá6±¾ý¾ýxàã ìèß¿ÿZ»HŸ1sæÌé¶2`º•§wëÖ­—Õ)‰€ˆ@“8°gÇŽ‹íNÿâE‹-¶ÉÅ7­<Ö6¤èǹ(Kôã|Šó˜xGÌ ü4ßoë1Ÿ)ð£‹Zkh ?D@D «À…£’ˆ€3¤˸ðEÜ‹qú~2 ô½ð§Ø÷1ï³ý†>÷å-ÇCk›%;ç·ÝvÛ{wÀô±cÇž1`À€3zôè1 ”D@D€êêê6nß¾ý­µk×¾eËúß~ûíø" ¿ÃM)¨½õ¾þ¡O!ß”Ð÷õìÓ÷îe{Z/úé[u£ø}”•D@D hà‚QID@Dà°'ža½áÍ}/ÆáSüÓ÷">&ôQŸç¶ì3´á¾16ļÝmeLì˜;wîn¸áô)S¦œ1xðà3ìQS-®$"P„liÿ»UUUo-[¶ì­|ðí'žxç!ŠþÞæ{QMqß¡8§ÐO³^àû6ˆ£ãþ£OëÇç}kÚ0vÄhC¿¡Rˆ€ˆ@±à…m±·ŽWD@Ò„çE”£OŠíP£ìE;=ã(§‰ÿ0î·¡ï-|fŒ~h?¶Xµå¥¥¥Ýu×]§Ïš5ë´Q£FÖ¯_¿Ó,†ïu+‰€tAûöí«Ø¹sç;6lxgáÂ…ïÜ|óÍo[ì;TÜåïk¹»eˆk/¦}™Â–‚ÜÛÐG9Kì£>¶ïßï~llˆ1›{„2ê•D@D@Œ.•D@D@âü9’>lZö¢›bÜÛp2uœm8Ös[oý¾¼ñ¢ì-ü†É³;¯¹æšú«¯¾ú4[pÊ AƒNÅê{w@«Sè„ìYþ:Üåߺuë»v—ÿ½ÇüÇ{ ç.ë‡è§pމëP|³ìE;bò1›6àûð>÷ZŒ1Ž7f­ú¡6J" " \*‰€ˆ€dðçJúÞÂ÷Ù‹m/ÄCŸ¢qú͵~[ö>è{‹1¢³\€Ij{ñÞpê¸qãN¶ žªÏ %èàð™>{aß»kÖ¬YbÏò¿k/ųüú̸ËïÅ4Eµ·¡ø¦@Gœ"ßûŒjý¶á¾Â²k(úm8‚ß‹}ˆ€ˆ€#€‹@% øó&}ØÐ§ÐFœ"ÜûŒQ¬Çls&ÐÛÓç>Ò,Çã-|äZË “6°ñ_ÿõ_O¶/ œE~Ìb{g9ì—e?úÞÂGFª±Œ ]öEªo|ãSg̘1mĈÓl‚`ªMœ„FJ" mGÀÿ‡&ðßß´iÓÒ7ß|séüã÷íÍýƒm},Cô—Þ;4Euh)¬½§ØGŒ¾ùŒûXÌ÷íèÃfe?>?vú8,øH´¡ßP©?D@D@² ðÂ.»•jE@D@²øs)}oá3C|{ŸeŠro½øGÜ—½Ð/$î·}îã }Ž•u°¸Ç„À.ËÕ#Gެúæ7¿9eúôéSì…‚Sl…Àd›˜rÜqÇá=J" - pðàÁ&ø—Ùþåöâ¾e‹/^öŸÿùŸË6nÜÁ±ÑÁÿ³ÅøIÁìËÞŒ± K¡ï}Æš÷¾>m{¿/ú~/êèÓZ¨Qì#Æä}ÆdE@D@ $€ 9%Ö!žSY†eÆžàã¢1ú¡øf™eúÞ†>ÊÌÜÆ·a,Ö?bŸ÷ ÇŒ2.È9!€I]·ÜrËàsÎ9gÒ 'œ0yÀ€“ÊËË'õèÑÂEID B ®®®ª¦¦fÅöíÛW|ôÑGË_}õÕwÞyg•5…Ðg†àçÿ9ü¿ó™¾·¡2¾÷£¨gË´>NßÛÐG™ãô>bŒÃ"1æË‡jýɸÉh&üˆ(‰€ˆ€´>~¥ï-üXö¢›íèSȇå,ÁŸU‡~Â>Ùwh9oy hKv·eL 4äOúÓ¾øÅ/NždÉV œ„ [%0Q«ŒRÑ8|wÿ~»£ÿá K>úèò矫f ò™{›ï…1E4c,{ ?+{±v1qïÛ¤ù~lƒÆæëXæ˜cÖ6iØÎÛÐGYID@Dà( à"MID@D m øs-}oᇙ‚ÚÛÐGÙ‹÷Ðg¶ý…}2F‹q†>cá1øò~ÛîˆI¯}íkfÏž}Òøñã'ا'Ø—&èå‚FI©ËÀËúì ý+í“|+W¯^½rÁ‚þô§?ÝnJ¡ ±¼å˜@fÌ lÄ(´½Ï­çôa›ã£/¶}”ýþé{ ?Ì’è%8–pq¦$" "pl„ç\–½…fnļ }ŠrXŠ}ï3æmšÏ¾XÏrš ÇÆñ£=ý˜Å—0)И¿ýío™5kÖ‰öèÀ‰o+NìÕ«×8[)€Ï—)‰@‡&`wö?Þ³gÏ»³¿jÛ¶m«m)ÿª… ®úÿø-6p|ŸÃ7ô‡™ÂÚ iÆ`›Ê1Áž%üÑ·¡õ±pâô½…f EE¿ÃWh#¸ S8öÂó/ËÊ}o)ªc6M #îÅ<ýæZß?·ÅØ|œå˜õÇ‘æsR€v÷—¿üå>_|ñ8ûúÀø!C†Œ³Iq6)p‚Þ)€"JíEÏì›ØÿÈÄþš-[¶¬±·ñ¯þãÿ¸æþûïÇ{0(ô!òá7%ö½PNÔ^€Sh{¡ÎzÆšk±=·a_1Ë}Ǭ?øHŒÑoþƒm|L¾ˆ€ˆ@À˜’ˆ€ˆ@ûÏÅ,S$ctô½…ðf™>Å8âôCKñÎ8ËMY´gn›e9†˜å¸}|$_¯eL0ï>ýôÓ÷]sÍ5c§NzÂèÑ£ÇÚ§ÇØÄÀ˜ž={Ž)--`m•D UìÛ·oûÞ½{×™Ð_gŸà[·~ýúµï¿ÿþG=öØÚ·ß~»ÔvB‘ÜÓ2E/­…cÕŒÓ2³1Ƽp§ß”elDz·ËôÃ1³Lë•>,Ú)‰€ˆ€´^lµÓîµ[€@x^f6ô£…÷>Ë^¤£Þ—c‚ÞÇèÓbÛ4ß÷ë}¿Oú~œôi±-}s}Æ`XÞs8cb ÁŸ9sæþÏþóc'Ož<ÚV ŒîÛ·ïh{¯ò([10ÒÚ)‰@”€ÝÑßhÏêo°¼¾ººz½ÝÑ_¿|ùòõ¿ýío×.Z´Ïæ÷:œ!òéã¥}¾ÞZ¸1íëàûýPh³³^´ÇüXÌ÷ãëç˜ØÆ—9v¶cÙ[ë¢ñéÃ2¡­’ˆ€ˆ@ €‹(%ŽI &˜ëœ¿wîܹ½mr`ظqã†1b˜­j µG †Ú$Á› jóXî­ÔA ˜¾ßg¿ÒÄý[²_iKö+íN~å¦M›*Ö¬YSa"¿â‰'žÀ '!ê™{81$ ^ïS̲.ÍRD³žå˜EÌÇYö¶)AÖûmc>ÆÅ8ýp¬,§Yrñ>¶QèÀxÔ‡¨¡‰€ˆ€Âs7ËÞ†>ÊÌߡϘ·éhK?ˆ“l›G}Ø7Ë1‹˜³œem“ÆcE;$¶§û±eL Àb’€eÄêÎ;ï¼Rûdá & :tè`ûlá`[90¨wïÞƒluÁ@›$h°6QÐ×Ú+µ2öÕvw~›‰û­°»wïÞjwòí«z[«*++«V®\YeŸÖÛòòË/ï³]CÔ3ãëö°ˆñkª¹VÕ(üÃ:¶I³Ô¾Žå˜ Å7ËÞ¦‰ú´¸ß>Æâc,ǬÁ÷ÙŠeúÞÂGÂ6J" " „/†:Ép5L€@xg9fËÊ^£]¬LQÏz–[Û²ÿ,ëëà’Ï·c™uô½ÝoL Ä2DçÇöHÁÞ9sæ ˜6mZûŒá+÷0`@?›$èoýìË}m²¹²m¿¼ØVàN½¥;~ˆú]‡sµ½Q¿ÚþN÷;¶oß¾Ó–èï°Ïèm_ºtéŽùóço·"…Î2­Uq|,Ã"¡“÷“è„øcÚ ‡®!‹€ˆ€4A <dz³ˆ’½¨¦³>?Vn*žVqúþbe,lëc¡”Y1_O?ËÆê| >„^\è3–z³ Ÿ1´g™¾‡ð!Öhé[¨QìÁqÏ‹>¬Ï|¬£qrÁêñ¢<–aQfŒ>-úòÉ Lú´hG?ËúºÐG9-Æ:ZÏ.Œ±.fóq–C‹>ÃXl;ߎ~ÌúüB²5;‚‡/ÃGB?J" " ]Œ~ð•D@D@º>ð|ïËôaCŸ±4Kˆú˜Ï¬÷Ù>Œ§•ý¶i>ûŒYƹ=Ë¡µ¦mYçcMù¬‡EBH´…ú ÛeÅXGë÷ÇXsl!0Ö¦©˜¯ùY1Ô±¾)?VϘ·ß±ëbÖÇBåX û`¯÷qúÞfù¨ËÊVÝXO Ûù–}|.@àh/º‚ˆ€%ðüïËðYö–ñ¦l(°Y¦Åöôa½Ï:+ÄmÇl–Ïú¦¬uÓÐÛùrÌg,Ëúº,uHØw,¥Åcmcûæ ¾´ö±¸5å³>ËúºÐ•k*S„£]Ìg Öûlïc…ø±í8F¿=clïËMù6ÔFa϶ˆ!¡ìSXöuòE@D@º ^tÁCÓ!‰€ˆ€4ƒ@ø{ÀrÌúüædŠyló£e;– ±MµaŸ~ÜÜÆÇ²| õõieÆi± ýТž±°mZ9¶ Û¶–‰Å0–Uf]h1>ĸ/‡õieÆÓ,E6ë}™~ÌÆbè#g,­>k߬+ÔÂm˜Ð¯’ˆ€ˆ@/0Š…]D@Dà0ØocYuÌèŠ~̦ noÊÕ3ZŒ!+æëcã-4æ;æ§Å÷6ËëPFÂ8Û"Å„có嘟cÜÛ,u-É1aŽ~§ÅXGkãcY>ê˜}Œy‹¿K_†Ô”=ÔêПlëcòE@D@Š”@[]()N¶ˆ€tI±ß ÆhqàðYŽùŒµÄR¼sÛ¬²¯ó>¶õå4?mŒb=´÷eú…Xß&ËG÷u¨ô·¦Õ7%cõ>Ö”Ïú,ëëàÇÊŒbcâÚÇÒ|ôVçãa»X¹qÆÚàoŽñÐgÙ[øLØNID@D@¢Ò.¢#ûíð1úÞfù¨ 3@û˜ë>îý´6±x,†¾ÒâÜOSõḹÇü0Ʋ·Y~X‡2öß’‘aÌ—c~cÙÛ,uÌ8ú1 ó°MZ},‹¡¿´¸ßWئ©qûú˜Ï,ö¦X,l£²ˆ€ˆ€4hé…ð‰€ˆ€ˆ€'þžø2ý,‹:_ŸVf¼5lSb¾¥û—ضaÜ—éb}›ÐG ûo—>ó˲¾~¬ÜTœõ-µ¡Xoi?±íÀÞÇÓʌǬÁGBŸJ" " "Ðb­uÐâhC.I öûâcô³¬¯ƒ+§ÅØžé·Ä²}¬Mó嘟cÜÛ,uH8Ö–¤˜Ðô±˜ŸcÜÛ,?¬C9-Æ:Z+ý–ØB¶µ c¾L?Ëú:øL8%h5-½0hµ¨#¢!ûÍñ1ú…Xß&ôcå´XsãøËÂ6>‡±¬2ëhýþ˲¾.ôcå´âi)&:Ø/Ç|Ʋl¬ÎÇàR޵I‹57F؆ٗc>cYÖ×ÁgâØX–V'À VïXŠ€ˆ€ˆ@b¿C>óóÖûØ-Ê>–å·E]l Y1ÖŬeù¨Câñ*Åÿd›BDg¬5å³>ËÆê|,Ëo‹:PC¿¾ï¬ë`‘¸]è7TõŒÉŠ€ˆ€ˆ@›à@›ïH; Ä~›ÂË´èš~–-´.ÖÎǼÏ}Çb…Ô¡ RÚö¾.ôceÄØß¡Róÿô"ÖoÆ}9æ3F‹¾èÇl,Æmbu>æýØ6±úX;Æb6-æãð™¸O–eE@D@D ÝíÅA» \;(*i¿W>Þ”«g¬9¶9mñ—¶ÅØÆ×eùaÊH¾ŸC‘Öù3&bØ/7峞£¤ßÛ’mü>½Ï¾|,ËG“ß–1Yè0ÚêB¡Ã "" "Ð¥ ¤ýŽ…q_nÊÕ3F ¨ôÓl¬yŸ}ø|$_+§Å÷)ìÇ×Á/D¼ÆÚ„±¬2ëhÃý2Nëë mV›XeùaÊL˲" " "Ð)4u1Ð)Bƒ´ß¸0žUöu-õÓ¶Ã ­ ÛòpýöŒ…¶6~›BÄm¬MË*RçÛ´–ãô}ÅÊd¶c\VD@D@:-æ^tÚÕÀE@D@DÀÈúý ëZ³Üܾ0äpFZœõÞÚ¶9¢7­m,ƲÊYu8¦£­÷\¾||èr ½ èr® Y¿iu±øÑÄ0¼ØövVÛ´¥ÍÏiu±øÑÄp|±íyÜYul#+" " EC ½/Š´TD@D Ë(ä7´©6YõYuf¡íü6Gã*ª³ÚeÕalMÕÚæhŽSÛŠ€ˆ€ˆ@—#p¬/º@ˆ€ˆ€H ¹¿¹Ím_à0š±ïB„vsúõm›ÛwsÛû}É(€/ hª&" " " íL £þnK¼·ó? í^D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D@D øÿÿÿÿÿÿÿÿÿÿÿ>?ÿÿÿÿÿÿÿÿÿÿ?@ÿÿÿÿÿÿÿÿÿÿ@AÿÿÿÿÿÿÿÿÿÿACÿÿÿÿÿÿÿÿÿÿCDÿÿÿÿÿÿÿÿÿÿDEÿÿÿÿÿÿÿÿÿÿEEÿÿÿÿÿÿÿÿÿÿE6OXdknnkdXO6il32ࢆìëéåÙÏbŽì…ÞÝÜÙͺä^ì†ÞÜÛÒ­Üè[Œí†àßÝÙ·Ãüâ\‹í†àßÞܳýùß\Šî‡áàÞήþû÷ÚZ‰ï‡ã âáÖ®ÿþúõÕWˆðˆä ãÞ¹acu–°Q‡ð‰åâÕ½­£“ˆ…“‡ñŠæãàÙÑÆ´¦¤‡ñŠçæãàÚÕÌÁ¼‡ó‹éçäáÛÖÏ·óŒêèåâÜØÙ‡ôëéæâÞã‡õíìêçåé‡öïíêî‡÷ðïíò‡÷ñðõ‡ø‘ó÷‡ù‘ôù‡ú‘öú‡ú‘÷ú‡û‘øû‡ü‘úü‡ý‘ûý‡ý‘üý‡ý‘üý‡“þ‡“þ¢†ìëéåÙÏbŽì…ÞÝÜÙͺä^ì†ÞÜÛÒ­Üè[Œí†àßÝÙ·Ãüâ\‹í†àßÞܳýùß\Šî‡áàÞήþû÷ÚZ‰ï‡ã âáÖ®ÿþúõÕWˆðˆä ãÞ¹acu–°Q‡ð‰åâÕ½­£“ˆ…“‡ñŠæãàÙÑÆ´¦¤‡ñŠçæãàÚÕÌÁ¼‡ó‹éçäáÛÖÏ·óŒêèåâÜØÙ‡ôëéæâÞã‡õíìêçåé‡öïíêî‡÷ðïíò‡÷ñðõ‡ø‘ó÷‡ù‘ôù‡ú‘öú‡ú‘÷ú‡û‘øû‡ü‘úü‡ý‘ûý‡ý‘üý‡ý‘üý‡“þ‡“þ¢†ìëéåÙÏbŽì…ÞÝÜÙͺä^ì†ÞÜÛÒ­Üè[Œí†àßÝÙ·Ãüâ\‹í†àßÞܳýùß\Šî‡áàÞήþû÷ÚZ‰ï‡ã âáÖ®ÿþúõÕWˆðˆä ãÞ¹acu–°Q‡ð‰åâÕ½­£“ˆ…“‡ñŠæãàÙÑÆ´¦¤‡ñŠçæãàÚÕÌÁ¼‡ó‹éçäáÛÖÏ·óŒêèåâÜØÙ‡ôëéæâÞã‡õíìêçåé‡öïíêî‡÷ðïíò‡÷ñðõ‡ø‘ó÷‡ù‘ôù‡ú‘öú‡ú‘÷ú‡û‘øû‡ü‘úü‡ý‘ûý‡ý‘üý‡ý‘üý‡“þ‡“þÂl8mk-MMMMMMMMMMMMM?Mÿÿÿÿÿÿÿÿÿÿÿÿÿêr Oÿÿÿÿÿÿÿÿÿÿÿÿÿÿùw Tÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûx Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûw Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüw Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüw Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüw Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôp Vÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê@VÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿUVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿV8dmmmmmmmmmmmmmmmmmmmmd8 !!!!!!!!!!!!!!!!!!!! ih32ì„ciX˜ÕæßÜÜÖÊ¥–ÑðŒéèåâÞÚÊ¥•ÎíŒæåãàÚÐÄŦ”ÎîŒçæäáÜÕÃÁÕ“ÎîçæäáÚ˸äÕ’ÎïŽèæäÞѺäîÓŸ‘ÑñéçâÖ½äúíÒ¡Ññé çãØ¿äÿøìÓŸÒñê éäÚÁèÿÿüñØ¥ŽÒòë éåÛÆÌÌÈËÐÛÕ¯Õóì ëçÞÌ®‡xvv}”¬œŒÕóì ëéàÓ¿§œ™•“Œ•|‹Õôí ìêåÛÏû¸¸·´¯­œ‹Öõî ííéäÝÖÒÐÐÑÐÌε‹×öïîíêèäã€áàßäÅ‹×ö’ï îííììëëêéðÑ‹Ùø’ñ„ðïîõÕ‹Ûù›ñùØ‹Ûù›òùÙ‹Ûú›óúÚ‹Ûü›ôüÚ‹Ýý›õýÚ‹Ýý›õýÛ‹ßÿ›÷ÿß‹ßÿ›øÿß‹ßÿ›øÿß‹ßÿ›ùÿß‹âÿ›ùÿß‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›üÿâ‹ãÿ›üÿã‹æÿ›ýÿ勿ÿ›ýÿå‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿç‹êÿé‹Òà›ßàÒÿ’„ciX˜ÕæßÜÜÖÊ¥–ÑðŒéèåâÞÚÊ¥•ÎíŒæåãàÚÐÄŦ”ÎîŒçæäáÜÕÃÁÕ“ÎîçæäáÚ˸äÕ’ÎïŽèæäÞѺäîÓŸ‘ÑñéçâÖ½äúíÒ¡Ññé çãØ¿äÿøìÓŸÒñê éäÚÁèÿÿüñØ¥ŽÒòë éåÛÆÌÌÈËÐÛÕ¯Õóì ëçÞÌ®‡xvv}”¬œŒÕóì ëéàÓ¿§œ™•“Œ•|‹Õôí ìêåÛÏû¸¸·´¯­œ‹Öõî ííéäÝÖÒÐÐÑÐÌε‹×öïîíêèäã€áàßäÅ‹×ö’ï îííììëëêéðÑ‹Ùø’ñ„ðïîõÕ‹Ûù›ñùØ‹Ûù›òùÙ‹Ûú›óúÚ‹Ûü›ôüÚ‹Ýý›õýÚ‹Ýý›õýÛ‹ßÿ›÷ÿß‹ßÿ›øÿß‹ßÿ›øÿß‹ßÿ›ùÿß‹âÿ›ùÿß‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›üÿâ‹ãÿ›üÿã‹æÿ›ýÿ勿ÿ›ýÿå‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿç‹êÿé‹Òà›ßàÒÿ’„ciX˜ÕæßÜÜÖÊ¥–ÑðŒéèåâÞÚÊ¥•ÎíŒæåãàÚÐÄŦ”ÎîŒçæäáÜÕÃÁÕ“ÎîçæäáÚ˸äÕ’ÎïŽèæäÞѺäîÓŸ‘ÑñéçâÖ½äúíÒ¡Ññé çãØ¿äÿøìÓŸÒñê éäÚÁèÿÿüñØ¥ŽÒòë éåÛÆÌÌÈËÐÛÕ¯Õóì ëçÞÌ®‡xvv}”¬œŒÕóì ëéàÓ¿§œ™•“Œ•|‹Õôí ìêåÛÏû¸¸·´¯­œ‹Öõî ííéäÝÖÒÐÐÑÐÌε‹×öïîíêèäã€áàßäÅ‹×ö’ï îííììëëêéðÑ‹Ùø’ñ„ðïîõÕ‹Ûù›ñùØ‹Ûù›òùÙ‹Ûú›óúÚ‹Ûü›ôüÚ‹Ýý›õýÚ‹Ýý›õýÛ‹ßÿ›÷ÿß‹ßÿ›øÿß‹ßÿ›øÿß‹ßÿ›ùÿß‹âÿ›ùÿß‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›ûÿâ‹ãÿ›üÿâ‹ãÿ›üÿã‹æÿ›ýÿ勿ÿ›ýÿå‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿ›þÿæ‹çÿç‹êÿé‹Òà›ßàÒÿ’h8mk ¤ëëëëëëëëëëëëëëëëëëëߪ< ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìM¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîK¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîL¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîL¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíK¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîJ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíK¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìJ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíJ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíF½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿã)½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹ ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ™×ÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙ×™ &@FEEEEEEEEEEEEEEEEEEEEEEEEEEEEF@' it32ÿÿŒ«æçååäàÝÖ±3ëæ åääããâáßÝÚØÚÌ3Á«æåä€ã áßÞÛÙ×ÓÓÝsÀ«æååããâàÞÜÚØÕÐÍÉÚ|¿ªæ€åããáàÞÛÚØÓÏËÆÁÚn¾ªæååäããáàÞÜÚ×ÒÎÉĽÄÚm½«æååããáàÞÜÙ×ÒÎÉĽ±ÕÕk¼«æååããâàßÜÚ×ÓÏÊĽ³¼ÜÒk»«æååäããáßÝÛØÕÐÌÆ½´«ÜØÑlº«ç€æääãáßÝÚØÔÏÉÁ·¬ÏÞ×Ïl¹¬çææåääâàÞÜÙÖÐËĺ¯½çÝÖÏl¸­çææääãâàÝÚØÓÎǼ²®éäÜÖÏl·­ç€æääâáßÜÙÔÏÉÀ´©èêäÛÕÏl¶®èççæååãáßÛØÒÌĸ©âñëäÛÕÎlµ¯èççååäâàÝÙÔÎź­×õñëãÛÕÎl´°èççååãáÞÚÕÏÆ»®ÒùöñêãÛÕÏl³°éèèçæåãàÜØÑɾ±ËüúöñêâÛÕÏl²±éèèçåäáÝØÒË¿³ÃýýúöñêâÛÕÏk±±éèèçåäâÝÙÔÌÀ³ÀýþýúöñêâÛÕÏl°²éèçæäâÞÙÔ̵¾ýÿþýúöñéãÛÕÐk¯²éèçæäãßÚÔͶ¾ýÿÿþýúöñêãÛÖÐk®²é èççäãßÚÕÎ÷¿ý€ÿ þýúöñêãÛÖÐr­²ê ééèåäàÛÖÏŹÂýÿ þýúõñêãÜÖÐr¬²ê ééèåäáÜÖÏÆ»Ãý‚ÿ þýùõñêäÜ×Ñp«²ê ééèæäáÜ×ÏǼƄÿ ýüùõñêäÜ×Òrª²ëêééçåâÝØÐÉ¿ÀãáÝÜÚÜßçððôöòìäÜ×Òr©²ëêééèåâÞÙÑÊÁ¶§–‡}wtrpnlv‹¥ÁÖâàÚÒs¨²ë êêéèåâÞÙÓ˸«‚}{{yxwtsqokrÆÚÕl§²ìëëêéæäàÚÕÍż±¢†€€~|zyywq€»Õ`¦²ìëëêéçåàÜ×ÏÈÀµ¨›Šˆ†„ƒƒ‚€|uÌ=¥²ìëëêéçæâÝØÒÌû±¦™—–•”’‹ˆ„€Ä¥³ì"ëêêçæãÞÙÕÎÇÁ¹²«§¥£¢ Ÿžœ››š˜•Ž‹´¤³ìëêêèæäàÛ×ÑÌÆÁ»¶³±¯­¬«€ª ©¨¨§¥¢Ÿœš–ªP£³íììëêèæäßÚÖÑÌÈÿ½ºº¸· ¶¶µµ³²°­ª§¥ ²£³í#ììëëéçåâÞÙÖÒÍËÇÅÃÂÁÀÀ¿ÀÁÀ¿¿¾½»¹·´²®¼£´îíììëéçåâßÛØÕÒÏÍÌËÊË ÊÉÈÆÄÂÀ½»Â£´îííììêèçåãßÜÚØÖÔÓÒÑ‚Ò ÓÓÒÑÐÏÍËÊÈÆÌ£µïîííìëéèçäâàÞÜÛÚ‰ÙØÖÔÓÓÑÒ£µïîîííìëéèèæåãááàà‚߃ÞÝÜÛÚÙÙÚ£¶ï îîííììêéèèçæåå„ä€ã€âááßÞÞ᣷ïîî€íìëêêééˆè ççææååäãã磸ï€îíìëë‚ê†éƒè飺ð€ïˆî‚íƒì€ëí£»ðƒïŠî…íñðƒï£Ïñ…ð£Óñð£×ò£×ò£×ò£×ò£×ó£×ó£×ó£×ô£×ô£×õ£×õ£×õ£×õ£×õ£×ö£×ö£×÷£×÷£×÷£×ø£×ø£×ø£×ø£×ø£×ù£×ù£×ù£×ú£×ú£×ú£×û£×û£×û£×û£×û£×û£×û£×ü£×ü£×ü£×ü£×ü£×ý£×ý£×ý£×ý£×ý£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿÿÿÿÿÿÿÿÿ€ÿÿŒ«æçååäàÝÖ±3ëæ åääããâáßÝÚØÚÌ3Á«æåä€ã áßÞÛÙ×ÓÓÝsÀ«æååããâàÞÜÚØÕÐÍÉÚ|¿ªæ€åããáàÞÛÚØÓÏËÆÁÚn¾ªæååäããáàÞÜÚ×ÒÎÉĽÄÚm½«æååããáàÞÜÙ×ÒÎÉĽ±ÕÕk¼«æååããâàßÜÚ×ÓÏÊĽ³¼ÜÒk»«æååäããáßÝÛØÕÐÌÆ½´«ÜØÑlº«ç€æääãáßÝÚØÔÏÉÁ·¬ÏÞ×Ïl¹¬çææåääâàÞÜÙÖÐËĺ¯½çÝÖÏl¸­çææääãâàÝÚØÓÎǼ²®éäÜÖÏl·­ç€æääâáßÜÙÔÏÉÀ´©èêäÛÕÏl¶®èççæååãáßÛØÒÌĸ©âñëäÛÕÎlµ¯èççååäâàÝÙÔÎź­×õñëãÛÕÎl´°èççååãáÞÚÕÏÆ»®ÒùöñêãÛÕÏl³°éèèçæåãàÜØÑɾ±ËüúöñêâÛÕÏl²±éèèçåäáÝØÒË¿³ÃýýúöñêâÛÕÏk±±éèèçåäâÝÙÔÌÀ³ÀýþýúöñêâÛÕÏl°²éèçæäâÞÙÔ̵¾ýÿþýúöñéãÛÕÐk¯²éèçæäãßÚÔͶ¾ýÿÿþýúöñêãÛÖÐk®²é èççäãßÚÕÎ÷¿ý€ÿ þýúöñêãÛÖÐr­²ê ééèåäàÛÖÏŹÂýÿ þýúõñêãÜÖÐr¬²ê ééèåäáÜÖÏÆ»Ãý‚ÿ þýùõñêäÜ×Ñp«²ê ééèæäáÜ×ÏǼƄÿ ýüùõñêäÜ×Òrª²ëêééçåâÝØÐÉ¿ÀãáÝÜÚÜßçððôöòìäÜ×Òr©²ëêééèåâÞÙÑÊÁ¶§–‡}wtrpnlv‹¥ÁÖâàÚÒs¨²ë êêéèåâÞÙÓ˸«‚}{{yxwtsqokrÆÚÕl§²ìëëêéæäàÚÕÍż±¢†€€~|zyywq€»Õ`¦²ìëëêéçåàÜ×ÏÈÀµ¨›Šˆ†„ƒƒ‚€|uÌ=¥²ìëëêéçæâÝØÒÌû±¦™—–•”’‹ˆ„€Ä¥³ì"ëêêçæãÞÙÕÎÇÁ¹²«§¥£¢ Ÿžœ››š˜•Ž‹´¤³ìëêêèæäàÛ×ÑÌÆÁ»¶³±¯­¬«€ª ©¨¨§¥¢Ÿœš–ªP£³íììëêèæäßÚÖÑÌÈÿ½ºº¸· ¶¶µµ³²°­ª§¥ ²£³í#ììëëéçåâÞÙÖÒÍËÇÅÃÂÁÀÀ¿ÀÁÀ¿¿¾½»¹·´²®¼£´îíììëéçåâßÛØÕÒÏÍÌËÊË ÊÉÈÆÄÂÀ½»Â£´îííììêèçåãßÜÚØÖÔÓÒÑ‚Ò ÓÓÒÑÐÏÍËÊÈÆÌ£µïîííìëéèçäâàÞÜÛÚ‰ÙØÖÔÓÓÑÒ£µïîîííìëéèèæåãááàà‚߃ÞÝÜÛÚÙÙÚ£¶ï îîííììêéèèçæåå„ä€ã€âááßÞÞ᣷ïîî€íìëêêééˆè ççææååäãã磸ï€îíìëë‚ê†éƒè飺ð€ïˆî‚íƒì€ëí£»ðƒïŠî…íñðƒï£Ïñ…ð£Óñð£×ò£×ò£×ò£×ò£×ó£×ó£×ó£×ô£×ô£×õ£×õ£×õ£×õ£×õ£×ö£×ö£×÷£×÷£×÷£×ø£×ø£×ø£×ø£×ø£×ù£×ù£×ù£×ú£×ú£×ú£×û£×û£×û£×û£×û£×û£×û£×ü£×ü£×ü£×ü£×ü£×ý£×ý£×ý£×ý£×ý£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿÿÿÿÿÿÿÿÿ€ÿÿŒ«æçååäàÝÖ±3ëæ åääããâáßÝÚØÚÌ3Á«æåä€ã áßÞÛÙ×ÓÓÝsÀ«æååããâàÞÜÚØÕÐÍÉÚ|¿ªæ€åããáàÞÛÚØÓÏËÆÁÚn¾ªæååäããáàÞÜÚ×ÒÎÉĽÄÚm½«æååããáàÞÜÙ×ÒÎÉĽ±ÕÕk¼«æååããâàßÜÚ×ÓÏÊĽ³¼ÜÒk»«æååäããáßÝÛØÕÐÌÆ½´«ÜØÑlº«ç€æääãáßÝÚØÔÏÉÁ·¬ÏÞ×Ïl¹¬çææåääâàÞÜÙÖÐËĺ¯½çÝÖÏl¸­çææääãâàÝÚØÓÎǼ²®éäÜÖÏl·­ç€æääâáßÜÙÔÏÉÀ´©èêäÛÕÏl¶®èççæååãáßÛØÒÌĸ©âñëäÛÕÎlµ¯èççååäâàÝÙÔÎź­×õñëãÛÕÎl´°èççååãáÞÚÕÏÆ»®ÒùöñêãÛÕÏl³°éèèçæåãàÜØÑɾ±ËüúöñêâÛÕÏl²±éèèçåäáÝØÒË¿³ÃýýúöñêâÛÕÏk±±éèèçåäâÝÙÔÌÀ³ÀýþýúöñêâÛÕÏl°²éèçæäâÞÙÔ̵¾ýÿþýúöñéãÛÕÐk¯²éèçæäãßÚÔͶ¾ýÿÿþýúöñêãÛÖÐk®²é èççäãßÚÕÎ÷¿ý€ÿ þýúöñêãÛÖÐr­²ê ééèåäàÛÖÏŹÂýÿ þýúõñêãÜÖÐr¬²ê ééèåäáÜÖÏÆ»Ãý‚ÿ þýùõñêäÜ×Ñp«²ê ééèæäáÜ×ÏǼƄÿ ýüùõñêäÜ×Òrª²ëêééçåâÝØÐÉ¿ÀãáÝÜÚÜßçððôöòìäÜ×Òr©²ëêééèåâÞÙÑÊÁ¶§–‡}wtrpnlv‹¥ÁÖâàÚÒs¨²ë êêéèåâÞÙÓ˸«‚}{{yxwtsqokrÆÚÕl§²ìëëêéæäàÚÕÍż±¢†€€~|zyywq€»Õ`¦²ìëëêéçåàÜ×ÏÈÀµ¨›Šˆ†„ƒƒ‚€|uÌ=¥²ìëëêéçæâÝØÒÌû±¦™—–•”’‹ˆ„€Ä¥³ì"ëêêçæãÞÙÕÎÇÁ¹²«§¥£¢ Ÿžœ››š˜•Ž‹´¤³ìëêêèæäàÛ×ÑÌÆÁ»¶³±¯­¬«€ª ©¨¨§¥¢Ÿœš–ªP£³íììëêèæäßÚÖÑÌÈÿ½ºº¸· ¶¶µµ³²°­ª§¥ ²£³í#ììëëéçåâÞÙÖÒÍËÇÅÃÂÁÀÀ¿ÀÁÀ¿¿¾½»¹·´²®¼£´îíììëéçåâßÛØÕÒÏÍÌËÊË ÊÉÈÆÄÂÀ½»Â£´îííììêèçåãßÜÚØÖÔÓÒÑ‚Ò ÓÓÒÑÐÏÍËÊÈÆÌ£µïîííìëéèçäâàÞÜÛÚ‰ÙØÖÔÓÓÑÒ£µïîîííìëéèèæåãááàà‚߃ÞÝÜÛÚÙÙÚ£¶ï îîííììêéèèçæåå„ä€ã€âááßÞÞ᣷ïîî€íìëêêééˆè ççææååäãã磸ï€îíìëë‚ê†éƒè飺ð€ïˆî‚íƒì€ëí£»ðƒïŠî…íñðƒï£Ïñ…ð£Óñð£×ò£×ò£×ò£×ò£×ó£×ó£×ó£×ô£×ô£×õ£×õ£×õ£×õ£×õ£×ö£×ö£×÷£×÷£×÷£×ø£×ø£×ø£×ø£×ø£×ù£×ù£×ù£×ú£×ú£×ú£×û£×û£×û£×û£×û£×û£×û£×ü£×ü£×ü£×ü£×ü£×ý£×ý£×ý£×ý£×ý£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×þ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿ£×ÿÿÿÿÿÿÿÿÿ€t8mk@ +012222222222222222222222222222222222222222222222221/+#  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýõàµw; *ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô«7 3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðV<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷^ CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùZ"EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüV$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüS$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüS$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$GÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$FÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$FÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$FÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüQ$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüR$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüQ$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüQ$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüP$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüP$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüO$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüN$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüN$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüM$EÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüK$DÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúE$Dÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô:$Dÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá)$Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ $Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö?$Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ $BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒ,$Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò6 $Bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿù< $BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþA$BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿD $BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE"$BÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE"$AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE#$AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE#$AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE#$AÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE#$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE#$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿE$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿD$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿD$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿD$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿD$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿC$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿB$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿA$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$>ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ?$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$$<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ>$";ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<" 6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ7 .EWenssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssofXF/ $6EOWZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZWOE6$ $.5:<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<:5.$  "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"    ic08~‰PNG  IHDR\r¨fðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@AIDATxœíÝ]Œå~ðÇã÷+"‹4 *mO ‰”"PÚP¤"¨ª 8¥:-‡\qß» !D\œ\ ÔÛÂU/‘ZD‚¨JEK¥"Uˆ¢R$JDQ‘*v»Á”H6àÄ^ÛãéÅøoÿýî;Þ]¯ßÝ÷ùI–í™±=Ùø}æýš1@DÞ*Lz“»¢Œçä — —ìK  Ô»×ë\Ú_ßEò®zÞªç‘ÚžãJ*¨[ À^·˜2Ö¹²¿4\°Cm-k½{¹…ýZš°Ò¤w@) >úW,,--ýk±Xœ™ð>y'Š"DQ´n™©ÛíFÂN§ÓX[[«7Ífó‡+W®¬¬¬¬ü÷… þýã?þ??h`º¶À ˜0WލUÿ¿¹¼¼üoåryj²»å—¼…_o«ojû°Ñh|wóæÍ•Ë—/øòË/Ÿÿì³Ïjn"®!´1h. ‚‰q!äÈ_ìÝæÜ³¼¼ü~¹\žžèžy&oèíºÝîPᢨ¿,Š"LMM¡Ýn_ýþûïÿãÕW_ýëóçÏޏV°†8t€¶™+ ~eÄð;KKKÿT©TªÝ3l¤ð›Gÿn·».Â0D·ÛÅôô4*•JýË/¿ü‡ÇüW®"nt0¨ 0¶Y0é葾"âp©o‚¤…ÔD½^Ç?þ8{äÈ‘_~ñÅï:tè·‡}ƒ&  $¯¸zø¯?X(ÀÛöÞ‚ è?°n½nó±&ïaŠ¢ívµZ {÷îýí÷Þ{zê©ûÌ‚!01.0¨è9ü"l]Õ·Þ´ímG~}“f7Â0ÄåË—Q*•ö½öÚkÿì³ÏC`b\ `4!IGp¹7û ÒFÌ0û••T«Õ¹W^yå×'Ožü]0&•Ð}øŸ?aICš4Ò† ÓFÚí6–––0???sîܹ·“áJ˜øï0ÝÄ,øú±A½^G­VÃÂÂÂÌK/½Ä˜€ÿá2«ü& 3­ójµöîÝ;söìÙ ½àèÀ6q1hУY²æ,//£Z­¢R©Ì¾øâ‹NžÍšÀ˜1(—¤6¿9[ž h;ò ³™P«ÕP­Vû¯/—Ë 1cPæÑ9i]Ö6i7½<þæ›oÐétP©TP,kcÆ «4lÛ%ü ˆ¿zúüƒN§ƒÕÕULOO#A€b±È#%²tóèo;¡È\®_/^ ¸ùÚ+W® \.­ïC`  ÿˆKRÁN ó,ì¦Àwß}‡0 Q©Tú5¹/‹³§Nbl!%Êšì“rŸVømë[­êõ:¦¦¦¬5R©ÄØB êÛhg ³“P?7›úÊ@²,­)Ðn·ûËÌaEé )W(ž=uê;S8pOžQ}0éå׿ $ëå5¶iÁA Ýn£Õjann®ÿ:ý}0C@X~«€!ÂÙ 7¥õGyóÞ¬ DQ„V«5´5 ¶K’Ëð!&`mZRMÍ6ô3¤`ë(Ô³õè@±X´JÇ GÖc €Ff;êë#·ÙTK0úúõ†úä^O:IÍRíØ00hK™…ß¼Z°,Oªèû0 ×½¯Ì 6`ŸÀ6hÓÒ:k73AH º­yÔÐMÝ0†9DØÃ  u„&﨎­ºo.ò‡€9YH÷ 0´EòBÒ¬B½\Æýu@¿v3! ‡K¥ÒìóÏ?ïu0hË¥õøÛ&þ$m—ôÞú>OÈó¤s|¾Ú0€¶„m 6êÄ.éôK=Ð÷£ÔÌ>^mÀÛš€³£œ ¸óéé¿f@Ø~8Ô¼Hh=ÂgtÀlNè}é™=}ú´w£¬ЖÈS}ìóö³F²>3OMÀ6YH ô¶}á…¼ª 0hìÌIAZRÁÏS ×ë{ú<ƒ¬ûB¡àU0hÃFmÓ'1Â,ÔyßÛ Û©Äf˜í…‚7!À m—gâîå=³BÀv‰1]æƒ/!àl' ílfçŸ9%8©sÐ\?êgÚ:m—)·‘“¤ÃPšØÅƒÎGv>[Ç ­­/…ÔøÑ ýÿ›! kÀ ¹‘tî€qÞ¢(š=sæÌ…r¹ü篿þúb—…€³@þ1‡eæÞFÞ'é$¤<'éèMIž]\\| À® EÖL¾<¯«×ëý+úy:lM‚n·;47Àž”ß+@|Q‘]  óÊ<º½oc›\«ÕP«ÕÐl6Ñl6±¶¶†µµ5´Z-´Ûmt:„aˆééiT*„aˆ©©©þóÛn» ³³³˜™™AµZÅôô4fggQ­V‡®$E:Úívÿ€!À ±I*ô¶þM÷þëÂ.´Õj¡Óéôokkkèv»CŽr ÃphJ±üèèüü<8€»îº wÞy'n¿ývÌÏÏ£Z­bÏž=ý÷•ÀIOÔ±ƒC€@c‘vÄÏÓ<Ð}i3mUý´Ï‘ X]]Åõë×qéÒ¥þ²={ö`ÿþý8xð î¹ç,,,`nnN§_Q×|kmmíÏÞ|óÍKˆkRuØQ!À ±J:©'m ùÜö#æ{%}¦žQ¨·Po#¿/Øn·±¼¼Œ¥¥%t»]ÌÌÌàÞ{ïÅ}÷݇ýû÷c~~^× fÏž=ûëV«õó·ß~û ìÐ`ÐXØ.n^âKî¥SÎ6לÒkNJëñ7›æçèý4÷WáóÏ?Ç¥K—0==ÇãþûïǾ}ûP©TÐh4æÎ;÷ÎÕ«Wÿäƒ>øÄÍ. ´ʦT,øÙ×_ýæÔÔÔž‰îeÒÇ|lÞÂ0D·Ûíßä¹´åÃ0jï·Z-´Z­þQWwJ?€´ñuÀlóÛú4ý: s;i&„aˆC‡áÁÄÂÂÚí6ÆO<ñÄ­¬¬\pqt±BÀ騳gÀq£€Yø%Â0´€tÄIHáo4C£i£ ò¹zŸ’þ f˜ï¡_ßn·qðàA?~sssh4+GŽùcWÜ 6h[تèúW…lsøõ\~™·ßétP.—û¯1«ófMÀºÂk«îÛ ¾^/ï!V©T°´´„¯¾ú 'NœÀáÇïþôÓOÿîØ±c¿".øÀ ð;  [2FLo«ÛûÅb±?ì&?-V*•†&ïÈö²ÜƶÂ/÷¶‘ óuº) ?úè#\¹r<òȱ?üð¯Nœ8ñ<âh".øf8ƒ@[&k²lc;)H/×A GÜr¹ÜŸè#ÛéõiGny¬ïÍÇIÏ“BD@†XYYÁ»ï¾‹Ç{ìOßyç/ž~úé¿A\N6ŠÙ›Œ]ñ~”÷LXX\\üE)í×È YÓtÓŽ¸rovÞéBg{sd@ŸÖ+m§ú&l»V€¾HHÚr}­µµ5|ûí·…xà÷£(ú—O>ùäÄ},ü€Ã€µZ€;ĨúªG¤SOw šƒú&Ûš¡?[/OkèÇIËdÿ¥"Íßw܇zèÛ£Gþ!€+ˆ›Ä5§Â€GXÚ6ºƒ.éô`}t—±û(Šúòé'0  ­­ŸUý·ÕJôº¤Ó#zýõë×±´´tçûï¿æÑGý‚k 0hllºë±w)Ô²LÖëÓwËårÿµÒI(€I͆¤£¿Ùô°-×ËÌ¡@³À ˆ¥¥%<üðÃÏ<óÌ3¯Ÿ?þ¿×äè_€#!À&mZVµÚv¢Žm>€,ït:CëôÍ6‘(­›Ëó4Ìõæ¿A>Oï‹îp”çûöíÃþñøñã à€5ÄA ó&Ž5Ú´<§úÙ5Y.5Y¯_#×fBÒŸ-ôg$íoR@ØŽô:ÈlË~úé'Að{O>ùäo\¼xñ' ¿3µ•Yøõs3dž¾ô²Ëöæ$!)`æk…n:ØŽüæ>Ùªýæú´›úñêêêüsÏ=÷øÅ‹ÿñiÃz’ÐÄ1hËÙ SR˜í]ØMòZ9òÛŽÊz;ýº´}Ò¯±Õ ÌÚ„­Ùavʺf³Ü}÷ÝàoOî >ú³@»GžI@z[ýÎ> .drÔ–Ëv™!¡òIG\‘õX_)ØÖtÐÛK8És3ltÁ×û¤ÞãnÄ—/önçl$]‚vÛD[Èÿ¹ «™×ïÓM÷˜GoÛg$õC˜û¨_/’jIÍY/Ûíö> @~[ „µg€v¶¤«óèeú=õ¹ú2ÅÀÐ2½MZ¡ÌÚÙV×0L¶&­CÐÖ<0÷§\.W—5 iL€¶LÞs€õ}ÀðµûÍö¹Þ^÷þ›ëm7é$$sŸôçÙª}Ès½.!”¬/ü ÚÝlµ€¤ª¹° êÚ€„„¹¬IUýQö×|Ý\±ñuÇ¥¥67€MÚm²jæe¹l! …^_L÷ä'UùõL¼ûj£Ã'O_€­ãÔz5«þ¬¤å‡!É]¶@6¾y)®¤#¿ëOë 3å ‚QößVõOú|=_ÃUg¾ØÎí\IUÛ6z>ÚXWÝΪÈ2ýx”áɤ‹ùYÒÈ ¹`Iï¹s…`Иd…€ÛO›$$ëÍ‚˜UøF-ôI}fs`”Ìk°\Ö™ `ж±mGRÝ/`þª¯~Ÿ´¡½4¶ˆ¤žÿ´!Bó½Ìð± }º†@c“Võ7—Ùèm“‚#m_²¶±½Ož¾…¤‰jÒ8› «Í†`oèûiÞ@Ò{©áA'ªý€Æn+B@Kz]Þ&À(Ÿ™6I(Ïs`ýù.aжȲ\¯ÏÛ“¿Ù‘§)a{ž@.g;<h÷Ésš°í5"ÏÑÖ´Ù@u~ARG§«œ Ú’ |žN:ÛÑ7ë}²ÎÈ ˆ¬QÛò<µW0h"²ªÿyÜI…Ë<Õw;Œ®`ÐĤö´ªÿ8öÁ4JM$ëýÙؘÈåªmQú´­šëŸöÞ[ôÎV\òÌVUÿ·r_òî“ëUý$ rNÖØû$ä/Õœq €œ·“:×\.ì6 Ú‘¶» ¹8›Å Êa”³ wÑÉ3'Á5îPÑØ1ˆ<æl€¥ÝÂ噀îî€ÈcÎ6x=Ú-\þ³@ä1‘ÇDcyŒ@ä1‘ÇDcyŒˆÆÌåï1kDcyŒ@ä1ö™ËßcÖˆ<Æ ò€Ècì 3—¿Ç¬yŒ@ä1‘ÇDcyŒ@ä1‘ÇDãD ¢1sù{Ì‘ÇDcyŒ}Dcæò÷˜5"1ˆ<Æ ò€Èc "1ˆ<Æ ò€ÈcœD4f.Y ò€Èc "9ÛÓm'¢¼‚ÀÝ㬻{FDcÇ ò€Èc "1ˆ<Æ ò€Èc "1ˆ<Æ ò˜³Sy:0í.Y ò€Èc "1ˆ<ÆN@¢1sù{Ì‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDãT`¢1sù{Ì‘ÇDcyŒ@ä1‘ÇDã0 ј¹ü=f €Èc "1ˆ<Æ ò€Èc "1ˆ<Æ ò€Èc "1ˆ<Æ ò€Èc<hÌ\þ³@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1‘ÇDcyŒ@ä1 šô‰sßmpðE´IN~§] €HÝBÝ \Ù7¢Mé}—C] ×'®4éP"Ä €Íf³^©TºQÔ6ûK‰œÒ/Ü…B!j·Û7¬!þ~wáHáÜ(P€"€ €)ÓöØ`@µ·¼ÒÛŽ5rYñѾ…¸ÐßpÀu?hô–·0¨LŒ 5ICIÇâ?Z€øµq”Á ÷I´›ˆ }ƒ/…~â5nÿ·ïW³·NÒ´„8 p£æBdÒßãâïr ñw¹Ý»…`À:ºý¯ xñ‘¿Ô»±ð“ë¤pw06!ÐCý.€üÁºˆ wG-ï NP©úKõŸ!@.2›³!µZ]øõhÀD¹Àpèç!? >í ò]ÖAà\áÜ `ðGÓ㤠>«ÿ´SèïpÃàLáÜ*PuoxóžÈe‘åÞœäD¸Z 8ù‡v‹(á1Ñ8ü?(½~ÖVzÆIEND®B`‚ic09ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ IDATxœíÝ[ŒdÇ}ßñÿéî¹qwÉåî’")Ê” “4C/9KîJ „,b!`œ‰8Š` ò¶l ɲ Á/¶_Œ äûÅvóIŽ$~ˆ`HI‰FHhФ k)J¼-—˽ïÎìÌô%=ÕSýŸÕ©Ó—éé®ïht÷ésNŸn·~õ¯:§ Á8“>`:“>åh Òľ'¾C`8e@ŒW˜þnŠÄ×Tc5ðzYÊ:* áÚÉjèC÷Ö6Ös]¡F;ÖÀw륄4Týb ~Ùc½¶” ÿ²ûØc†Æ¤` 5úîyMDê[÷î¹^‡ÆHÓ‘þFº­–wÔ:±Çþ}è½(4XÛ¬ž½»Õ¤–æ·nsÒ ±Àw ô³íŽtÿŽˆ´¶û·–÷zG=¶B‚–éÇ@öh¤ºB ¿küë"²("Däæ­Ç ±Cƒ¿?;éÆÛ5öMï~së¾¥»›DúƒD‹aÀjü]ïQDnyóÍ7Ÿ›Ø»¬ÓéH§“Ö^¦®×jµZív{³Ýno¬¯¯¯mnn^[__¿rýúõËkkkç®^½zö7Þ8óÒK/½ùÇüÇ?‘5Y‘Ò ²3¸0ªÞsÐ È=Õ.ÝèûMº%ÿƒ"rç›o¾ù'uÀnk·Ûå+Izã þòN§#EQH³ÙܸvíÚ™‹/¾~îܹWWVV^ÿÒ—¾ôÍo|ã§e;¸Û¦ô‡Ðp@D"ý“ütÏßMú[‘[EäÎÓ§O}ÇìºqôþýFÞz½Ü\¯×åÚµkg.\¸ðÃמþùÿ÷¿ñß‘Ué‚Ò­4e»:PeÞ€Ýûw }ëæ€ÿ=¡ãvUj$$ø ~¬Ñ·Ö­ÕjR…¬¯¯_ÚÜÜ|mmmíå/|á þ‡ø‡§d; ¸ªA ”7þnü߀¯Nè8]•Rþ¦ñ×ï¡÷eUôúFCêõº4›Í·[­ÖégŸ}ö/>þñÿ¹&Ý0:< Æ=0Óá²cëñœtÀ!逯Lè8]3®ÞJéßq}¬Zàž7 i42??¿¶ººúÆ·¿ýí/ìcû¯Ò ×¥?ÄæZù*Y°.ú£C»3o7‘¢(’{þVãïnëëëríÚ5¹~ýúÒâââ½?þøo¾øâ‹Ÿÿ½ßû½""‡¥{ ï¢l_Ãßä«Ïþ¡s„ ðG¾sÆ¿+û»Û¼tÿá8,Ý ÀŸÐq»b”½ÿ”ñýP°ÊþÖ:úV¯×eiiI<(Ífsí»ßýî7>øÁþŽˆ\þj€¾èPÙÙÀL¡ÐϺ€¾€Šª4þÖ½^'¶f³)W¯^•·ß~[Ddéĉ?õ /|þ}ï{ß½Ò½×’tƒ½«êùCîÿy‘U`¦ð‡ÝßÈ»q×ûŸ“î?K"rDº×øÒ„Ž»P=¶^lP/²³go5þÖ$A]!𗹡÷ÚÜÜœÜzë­rðàAYYY¹öÙÏ~ö“_ü⟑«²}Ú ¾² ??@Œ{`&Pè ý€5ÈBQØýƒAÿ”}èF¾(ŠÞqÄŽÇoøý}ollÈÊÊŠœ?^Ž9²ÿsŸûÜþµ_ûµÇ¤{V«¸àïWÜcæ`FÑ Ù—þÕsæEä&¹å3ŸùÌOOè8]jt‘2îz=¶½«„& ¶Z-Y[[‘C‡ÕÞûÞ÷þóýû÷ïë_ÿúÛÒÿ{w aBf€¬ßð«@VFbC ±çºW¯‡ÿõN§#ÍfSVVVäܹsrðàÁâW~åWþàþè>,ÝK|ï“í_ùtÕÿ×>©`&1©­Ÿõ?¶ÀLŠ•ìÝézÞ0è¤?},VÉß?¥°Ýn÷]G ÓéÈÆÆ†œ={Vjµš9r¤øð‡?ü;KKK ¿ø‹¿èæõ¬‡ÜÚº¯I·RàW˜€©Fƒ¶M7þ¡J¥QWô²Ø…~üçÖÍßnüÝóN§#›››òÖ[oÉÕ«WåСCÅOþäO~öÉ'ŸüéÎ p•N•Ì,€-D”5ðƒ†« à?¶&†BÂÚÚš¼ùæ›Òl6åðáÃÅc=ö›O?ýôÏHw8à&! ¹€²ÿy­ d)¥üŸ²®k¼ËÆþcû¶zþºñmwùòeyýõ×ennN>\œ8qâ3O?ýôǤ[  ¹cT6¦û­›‹êùëý´ÛmYYY‘7ÞxCöïß/·ÜrKqüøñ_ê©§Üp!3 Rï~Ôïç?vçýë¿^Ïß6´¯ÐþégΜ‘óçÏË-·Ü"óóóʼn'~ýé§Ÿþ¸€$£ þŒ}G_è'õleëë3ÜíÆrúôii·ÛrðàA‘âøñãŸ" #‘r*ŸÕ›/k¼CeÿÐ2}Š`謷þùóçå­·Þ’ýû÷˾}ûDDŠG}”€™G°k¬Æ¾ì’é=ýÐk±!wM3gÎÈÚÚšõä“OÊÏýÜÏ}>ò±ù!L*ÆNçA‚´n¸CûK½ˆPȹsçäòå˲oß>ë}\ €©Gd\կݨªY§ZsDDVWWåôéÓ277'ûöí“Z­¦Ï^(Ž;FÀÔ#˜¸ÔYþ¡ž¾{›ˆ˜2)ÐYYY‘µµ59pà€¹-!³€`d¬F¶jß:50Ô¸ÇözV‚õú… äÌ™3²°° óóóRE¯àUŠååeB¦€ˆŒæTÀ*Û–õØSßߺ¸PÕ÷±~€heeEšÍfo.€~€iGlœ!¡l¢ 5‹?¶¯²õ\O>tçÏŸ—ëׯ÷MÔó¶ž0•*¤·>È0€µ] |®· /X×ÖÖäÌ™3Òh4dqqQjµZì}‹åååOýÙŸý!Sƒ g·‡üeUƒE¬ä[7ü튢K—.ÉÆÆ†ÜtÓM½¿_ðŸ‹HñÈ#05*db]l½aC€U°Ç^·öç†K߃€iC06¡Þxêú±ÆÝZkØ­÷öÇö-ëëëröìYi4²°°`] ·¿pìØ1Bö<€>£HíÕR¨R)(›7`½æ¿~ùòeÙÜÜ”¥¥%s psØë2È\€”É}zyYo^õ¾û¶Óû(+ý[.^¼(7nÜèUÜ…öçMdb ö4€ÆYH©T™Üçîu?BUëõ«W¯Êùóçenn®4ü +"„L€ RÆòõòØ2kyYÏ߯XUâÂ… Òn·{“#¥ÿà ØkL£‹×ë²ï²žzJC¯ÇïCC z½k×®ÉÆÆ†ÌÏÏK£ÑèUêõzð½Õ­xøá‡ ØS‚RêÐ ú”}W©„–émõ:ÖÿÊæhW®\‘7nÈÜÜœˆH_/ßW°öIÀ^D0´”qýÐz±e±r¾Hÿ¥yCëëm­õCáÁY]]•Ë—/÷zýz¼ß_V24@ÀžA5ª¡€”^¼^oœCU‡.]º$""sss½ßð«„L€R£ž ·‹m[V•ý­mbcýe!auuU677enn®×øû÷z@?Ö!ࡇ"`¢F"¥Ç •ßCûŒõúCÛ†üØ0ÿÚ•+Wd}}½7æ úA},„ìIR«Ã„€Ðsý¸ÓéDß76 `5îÖ:zÙÕ«We}}]êõz_>üª€ÿØ='`’’j( ´Nly¬ìï–…zÜVc/²s¡Æ€ív[._¾¼ã<·køýÇ¡Àpö€JRøÔSS†¬ŠnœS÷¥ïS^÷o×®]“N§Ó›à7èz`YPÛ°ëÆ"u( ly(XÛ¥ AXëÇ}ý7nÈæææŽÓõ%‚ýÆ=ôz„ì6€ÊF5 ´¯Ð²*U€ØûûËuÙ?öº;À÷Í ðKþ¡°u+Ž=JÀ®hLú¦Mjï˜uE±s2Þ ûÐûrÏÝ2ÿõZ­f¾¯Û{½ÓéôÛN§#ív»÷Ü=vë¸Ç­VKjµZßën¿~`ii©÷oA½^ïmçÞÇ-s÷FCšÍfßñ»ýºÏ罯 ò ¿ð Ÿ|}­­ûšˆ´¥Ûøw¼{ Š €±I©„Êû£¨¤ŸµÿÐDÀëׯ÷*V¯ßïÑëJ€uú ¾yU*;€j( ¥T_ÖÈ—ã‡ÆöËŽÑߦÓéÈÚÚÚŽ{Øø5ABÆŠ`(ƒŽó§¬W¥ Ú.¥J –«W¯ö ø·ØÄ@Bö€¡" [õâca!õ=ýí666zcþ";'ºß `¯#‰Aøa÷k­“Úãí#´}Q}À-ýÀ¨B@½^'`ävMJHHíÅ— ”ÿë×ô2ë}EDÖ××ess³¯é¡«ÿ ¶öCÀHŒÌ  |Õý »m(DX¯é0°¾¾.­VkGc-ª7?Pغ¨ ÂȌԨB@Ê6±ýÄÊø¡uËæE!ëëëÒl6û–•…£7_9xËŠŸø‰Ÿ `h#7Š|j㞺¾µ}, „–­®®ö.êc…¿Ç.ü ¡B@£Ñ`8C#ØueU€Ô†¹lÐ<€”}†‚€ˆÈæææŽ}ú=üXÐE¤wæ€ßðëS õŃÀ°Æ"¥±Å>bCUç¤nã.¤ß+µ 'ŠÈ޹î±Ic?`lÝ¿PÑ0¥MýB×õéþ¿¦_sËôr·Ÿ¢(¤Ýn÷–»ÆÓ-³ªºßn·ûžëß(Šî©€þoø÷Ögó·ÜcýÛî^D¤Ñhô&Štƒ‚û<[ÇëB¿€J¨›A{ðÃì;Vâ·ÇJýþc×`‹ˆ´Z­¾ `íO‹”J€¾wÜãP•JA0VÖúc%þ”×ÝóPãïÿâ`lþ€oss³¯ª0®à&Š0z{BJC®—ÅÆíS+ ±9¡PÐn·û†ÆB ÀD•õæ«î§¬šZmp­9 Íf³7 ÷­Ã@•àÖ 0JcW¥a¯Òsç>üutÃîæ„ö7h°N,»N!ƒ"ØUì²ç©ûöÇ÷õúVÉ>¶_»ÝŽîÛzQ„ë5BE°§¥6þÃôúcó,Íf³wšžµþ°Ã„쀩ã7ª¡ëøë¹Ç©%ÿ²}´Z­¾`mç¯?ÉP«ÕЇ~˜€vÍ0ãö¡×ýóóS¶­:¼`qC)ûÚ ! ( Bv Ø“i˜c ½µ®5ÀºéíRæXïEÀ^B°çU ƒTR«NgÇY“ UÏ À!ØUƒôìÙgê˜Ù~ôþŠÀ¼ƒI…‰†# "SjAÂÚ¯EQì8 ¶­µÎnW°Ì´a‚Bh[ë CÛ°Wì)%øØkÃ6ö±¹þë±àoznó0!@Dž°¼¼LÈÀTˆ5¸!ºtzÍÚ.6ôwèýv;¸} B0©=õXžºÏ”÷*Š¢´¬¯÷cý@Ù{ï… +[7B@†fJYÏ^?·Jüšο['%„ÞÓZg7B€Ûž€e5´)ñy±uªìs\! V«I£Ñ;øÛИôL›ªÿãŽ+ÏkÖ¥xkµšy«—ïãëÆ×í§V«õÞg!ÀÿÖçò÷i}>wlîøýÇõz½÷Ù†4›M©×ëÒjµzÏ­ïH?‘byyùSO<ñDççþç¿ùHî<Èšˆ´¥Ûøw¼{ìqTìyƒõèeº®—YÏ«w%ÀïÑÇ*¡9ÞöÅòòò§Ÿx≠•€™E°§„×AÝÔ³b¼n”‡±B€¿,¤[ Ì0€™”ÒXû lèÇ}BëòØRB€^6ª`Í  €™k\cáq~kÙ ×$¨rœúýCÕ:øÛ¸çnû­÷#Ì(€‰E9}Ø÷, îÞš°B€nøýÇz¬ß Ö6î9•€ÙG05 ±y¡ànÖ5\#: ã îq(ÔëõÞµB!À»f ÀÔdBß ô¸»^æ7œ£0Žà÷àc•€Z­f†=Œ@˜=Y³ÛعÿÖòqǰ!@/&¨eűcÇ3€`jTmxGY¦·ª£6îÐ!@¿_BÀ ˜*©o¬1õ[Wã‹Í¨r ƒgÐe}B@Þ¸pEãüÀàÜ„=ý#=¡†ßo8ý’¿nTÝå€E¶ÕÐezGýYBÏ­Ïã“)c‘í.ò—‡.ì¶q­ïÔmßét\.<}¨˜ ÖÏùÆéØD¿P8pËF90åøbÏC•? ø½y¿·oUÜúî3&ú©L)ˆÝÀú%uŸ!Ý>¦Ðs«ra…‰†ÒŸ?q06$ „€©D=]n·XßnH º÷阮·¾JN ô—¦ ÀT©ÒøÆËÔýY¯w:™ŸŸO<âá#øÃþ†¬I€`P;vìÓO=õ!` LЄ¾TÃ\¾×oÛí¶¬®®¼¯aß¿l\>ÔsÙy± ?øÕÝ„Ÿöß³xøá‡ S€`&ÄJ÷U¶Ñ=hËÆÆ†¼ýöÛåðüÉŽÖ¿A®×ëÒh4¤ÑhÈÜÜœÌÍÍõž»ß°B€_ð× øïO˜¹Éþ_}ëÖ‘¹­Û‚tÿh÷‰Èyç¹s瞘ȑ3(Ô#õÔ]hÍúw§¬¹åî¹[æNgët:ÒjµzË[­Voív[Z­Vïuý¸ÝnK³Ù”V«%Íf³·ÿÍÍÍÞºÍf³wsë»õÜÍÏ¥¥%¹ë®»ÌÏ×]wõ5ÆGŽ‘z½.‹‹‹róÍ7‹ˆÈÍ7ßÜ+ݧpŸÛ½ÿ9Ýq»×[­î|îxýïÓÿÎüïÜû®;Ï=÷ÜüìÏþìD䢈¬ŠÈ†ˆ4¥{j`{ë¾³usçvÔ=Æ€ë˜)çÆ³Ïk⟿Ì߇Jܽuk·Ûrýúu9uêÔŽuEDþþïÿÞ\n=?xð Ü~ûírÛm·É¾}ûäŽ;îùùy9tè,..ÊM7Ýdž*Ùh4¤^¯÷5ð~ÈÙÜÜÜqÿÚÞuú†Úív±¼¼üé§žzJ¶B@× ˜€©•üFZ¯jÄSÞW߇ΰ†üc±ŽÍmSv]½Ý¥K—äÒ¥Kò½ï}ÏÜ~aaAî¹çy×»Þ%‡’C‡ÉÍ7ß,ìû,nèÀïíonnJ³Ù”õõui6›"²3XÄ€½‹!†€‰v@¯«ÊÏ}åi]ªvå|=  Ëþ~¹Þõˆý!¿§ì—ü]ÏÙíËÚŸ>&‘þFU?·* ÖweUbß§ˆÈ{Þóù±û1¹óÎ;åöÛoï /øütØØØõõõCzxွ‰ €ìéžx¨GïOt+[×߯Zj”õk~ÏZW ô%‰uïÛ±¦pë¾òÊ+òÊ+¯ôÞkÿþýrï½÷Ê]wÝ%wÜq‡Üy罉ƒná‚,--ÉÆÆF/ XßëÖg(–——?ýôÓO·?ñ‰Oüyà?…•€]C€ 01)=Sk¹5&®'þù¯û“õø»žÜ¦'êù÷º:àzÿz⟻ùËý}„ŽÇúŒÖ÷ª~Xë‡ö«ƒDÙ¶µZMŽ=*ï~÷»åž{î‘ôÎ4pÕ7DpãÆ¾*‡ºu¾õ­oý‡_ú¥_ú/"rIªU#4þ Zïm…ô‡wóÃ@]º!à&¹ù·~ë·þåd€/Tú-÷ÇÕ]£WVF5ÌV¸°†b½5fî‡æèyz›Ø„Ð{XÛX¯Ÿ={VN:%ßüæ7åÔ©S²¶¶&­VKD¤{ý€ùùyYXXè].¹Ùlêýwß}÷ûzè¡s_ùÊW^‘nÃï7ô"ý½}¿€"€™š<ªXÕƒÔuDìÓétÐãü~u"tüþs«5äeÃeÃÖ¶V ¸~ýº¼úê«ò /ÈóÏ?/›››Òh4d~~¾7‘p~~^æææ¤(ŠÞé„[á«ø‘ù‘øÀœþË¿üË×d»Ç þ2Œ€L¥XO7¥|î?Ž•ÔcÀoàÝó²Š@¨ ú\nYJ/½,0xêé­º¸Ohßþ>Üë›››òÚk¯Éw¾óyýõ×¥ÝnËÒÒRo¾€\E ÓéïyÏ{þÑÝwßýÿú«¿zS¶+V™_) €™W6×Àõúë¢7ee½uL¡†<ÖÇJøþãX?Ô¸û÷Öãб\¹rE^~ùeùö·¿-ׯ_—ÅÅEYXXz½Þ»¡÷=÷ßÿ?®Õjßù›¿ù›éûé„€#€‰±z»Ãî/4žz¬w!ÔÐ[¾îÝ{§¿{þþÜ«—n5Ìn+¤\ª×_jØõrýºµ?ës¼ýöÛò /È¥K—䦛n’ÅÅÅ^p×èt:ÅñãÇ?ôýïÿ?øÁ®ÈöD@*c–û—Wù,€•••'&r¤ÀŒ õÎcË­Þº—ÍëÙÿnYèZ¡›>ÿߺ$°¿Oý¬@T6QQ¿«dX¬y¡ã)JÑëêc¹÷Þ{娱crûí·÷.oìN!ìt:í~ô£þîw¿ûªtÏX—îÙ-ÙîÖ‘p¥‰`¢† z]kÒ]YðC€úZjð/þ£Otͱ.0¤/úSõ{+û.bßcÙ~EÂ=d¢ï­cðo÷ÝwŸ<òÈ#røðáÞ%†766¤Ýno¼ÿýïÿÐåË—ß‘Ë"rCD6¥?øÃ„€!p! 3M7bþs«sˬ·^®/Ò£Ëæív»÷¸Óéô®£¯ß«¬‘uÏEÂçïÇzü±àŽ=V…°öªèê‹[×ÿ¬/½ô’œ:uJŽ?.ÇŽ“……Y\\”ù¿þë¿þo=ôпí ù |G¶/ÔwhÁƒFÀLñëµPc¨'ɹeúqlüÝ5ôõz½×ø»Ù±ÞO_اç”õº­@`mc½ˆôÂIJÅ ô~:Xó)üeÏ>û¬|ÿûß—“'OÊ;ßùNwí€Ï=÷Üç———ÿµÈŽ ùüåE`D0À0Qã±ÏÉ×Ë]Ißšà/ó¯è–ëñ|ÿÊ®ÔoýD°õ¾1~‰Í°æľÇTV…ÄZ®‡b7½¾ˆÈÑ£Gåĉ277'ív[®\¹òìñãÇÿ­ˆ\‘kÒhI|N€! S%Ôù¯‡ÊúÖë~/Ûïuëeºnͨw½~×Ðù½·\À­Ÿòycew½Ýà–I©D” Iè÷‘høò+ /¾ø¢œ={VNž<é~¥ð‘¯}íkŸyüñÇÿ½l7ø²³±÷‡\5€€Ó9 Ø“RNLY'Ök¶^/+«ë÷-o·B„[njçN·sרwë¹ç±óôõòЩ|þ¾­×­c²^Óïï.ýùb§)ºå«««òòË/Ë‘#GäÀrë­·þƒýÑ}í«_ýêkÒ½Pz`¬‘Ͻº$÷/‰!`ÂÊ&¨…–ë’³õº‹ `•þCuß=·~ È=÷ï­!ýYSψ…—²ï1Ö›mWö^z^ƒ®D„.¤¤öø±Ç“ûï¿_D¤óÉO~ò_=óÌ3/Iÿ™îǃüëXg €@&jÜ@Dú]ÿ¹[×ë×Àšà®kïŸ  ú@@¬Ï¡KïÖІþŒ)ßiŠP`ÐAÁªŽXCVèÒëZ!àÑG•|PŠ¢Øxàþi«Õ:#"W¥{?øsR«Ùc€‰ŠÍÌtÖskü^—ôÝ8¾^Ïß§>%н»ñ|é]äÆß‡»¹@àÏ5¨)îܽ›o`5Ê±Š‚ûÌúûÔÇ`½¿µ<ô÷ë7úîuÿµ0ä€g%IDAT¿ýÛ¿•V«%GþùçÿÓƒ>ø1éoô­Éþ̈ T”2æ`÷„zƺaók÷\Óç뻆ÚoÜV«ÕkèÝä>=Ð5øî5w¬ú‡‚b=jÿyÙ©€e¥~ëµXK­Î„‚†Õ»÷ƒŠÿ½††þîïþNå¾ûî{÷—¿üåO|ä#ùÒ?Àmé¯lÓøGL²3üõtƒ¯{ñzŸº§o-ó{²~õÀþc·ô>b¥}½Üzº÷‡&4Æ”­£ßOW!B ¿ßøëu­óÜsÏÉÒÒ’<ôÐCÿæäÉ“ÿë™gžqW´Æýõ5¨̼P`°fó[áÀ:UÏ]ÂVŸþ§÷¯g»û€²q}= Rzwë:‘Ðß²ÀP|øì>ð\»víméV6dçU©P°' Ú£¯º]Ùé€Ö:"ö$>¹{,"}½}ÿ48¿§®{î±àRvÚ£ÞÖZ?e?¡}†^/ [Ö:z¦¿üÇ®j _ÿÁ~ ïxÇ;îsŸûà/ÿò/ÿ…t¯Ø”íßtq½®` ÀÔ*›ù›ñoïïèÞ¯{¬‡ü†ßì~¿ä­2¿Wëõêc²zÕÖõôãA¥VÜãPE&ÔÃ×׈­ï?.ŠBÎ;W[^^þèwÜñÞzë­U±‡Ü—àBa` ÀLI9#@÷ð­ ûh~ï^o§Ï½÷/ú£ç8úÂ8îxüãõ…€[*ÑëwjÅÄZך³ …fñ[Ïc¥ÿÐ0ï­·Þª=zôž_ýÕ_}àw÷w/JwÀUüS[î#Àžk´RËÚ)U€”á¿GLm]Ðïý‡†ü÷Õ¬²{èylU¶ ƒU±pÁÆ:5Ð݇*""²ã˾f³)kkksËËË'EäYY•î\®¶wóöÆßC°g 3³ßß>v‘« bÏäw¯û ½H·‘ó{÷þ9íþþÚív¯AÔóüa•¹ý÷ןÑ:¾A¿·A~k™v„îÑëße°*î;ÕËõ~ß‹/Öî¸ãŽï|ç;œ>}úªlŸ èæèÐÛEòŸQS!µ‘+«è`]Pø ·£/ðãÊü®ÁÒÃþ{úC~Ãh}Lús”±>‡¿¯Ðó²}êmô2ýýÏä³.ŽrpÏ/]ºTÇ;Þqׇ>ô¡wýÉŸüÉŠˆÜíÆ_7üT<SÏõü­_ tÛºÞ¼H£å^×ÛúÏýÞª5ÐêýûÇf…ëy¨A¬ú]…ĆR××Ëô ½}¨ü¯Ã‚:Ž´Z­Æÿø?("/J·]s§ê*¿‡`Ov Ê>Båt] Ð÷>Š¢ØQÎÖ=|«gjü¬ã³–ëÏ­ï­ž(8éýƾKë;´ÂMìØõü‰²Þ¿>¶õõõúÝwß}ŸtÛ´ºô÷ü­A@¦HÕÉ€UæøÛê3ôlŒ_DvŒó[½}œîý¬ÆÎo,CÃú³†èãŽ}_ú{ í?Tü ú¼ú3ZŸÝZæïC‡‰k×®Õn»í¶wK÷ÂmîÂn¡al!T4ŠójÄ«  {ó¡1h=רû¼Û—ÕÃÕ¶q÷Væ{å¡Þ»~ÝÚ&¤^¯›ßMвÆÝgMžŒ}ŽPï/Óß•²üÏÐl6‹ƒÞ&ýÝøë›Hæ•€©2L ´ŸÐP€ÈÎ+ú%¿g›è:ÝϪX¥òAÃPès[bÝ—m¯× 5òúµP`òƒ™V€ÿöFcŸl_ÒÝ5þ~ À̱NÔ¯‰ˆÙ˜;:¸Þ§ßYëè×téÞz®ß³jƒ 9UöáïK‡‘”á'tCëTÀØ®¬„Þ{k%é~ÃÏ0€`Ot ¬Ñ×ÏS+þLöмÝÓ×ïéÖ…€P£[ÖW™Û¾L¬:à?ö‡ôgõ׳.ˆ¤·‹ý·ñнÿPÙŸ‰€[¦NY8ðšP5 µ±Õ½|½®ÕP…‚€>« ^e|ßí¯Ê6–²ªXXÛ¦T4¬Þ¿¿ÜzžP(køE=ÎÀž5ŠÉ€þ~ÊJåe½M¿üº²Ÿ"ý¿+¯§ö°}Ñ!ý¾)ß]¨šá/³ö 3þ÷¡Áºþ‚uœVpÒ¯ûûñž—þÀTJ )•‚PyZOðs¯YóÜz¡É~úâBºñ²Þ½ ^ëó•Ñßõ=ĆI¬ã í[Á@©øïa…ŸÐ°J»Ý.›ù/BèC°§Åñ”×B÷Ö>¬Æ¯ÓÙy=z«—ð÷g]&8Ô ê2¹>ÿøcûJamj”­cµ*)Ã-Öºeÿmô{»×¶‚X¬Ñ'(3+ÖU š5$`õ—5x©C~ãjˆ«ÌH ±^¼õ\oë?¶Â‰þM½~ï²*ƒ7¼küõ:YO$T4hÂ0©e~Ýè–…ÝèX=~«²zþ¡†96έ· ­Úlh`¬cÓãÿþwh]þWo›2 ¶‹Møão…`Ï«2–Ÿ²NjðÇÿõv>]â·†¬0+[ËBABïs·…†üÏç~ÁZÐÍ߯^ºÒ¢·cþ‰¦BJ#_¶mj 7걆ÎjCãßî±?®o}ÆØØû$•U'¬!w9e½žõÝXï!²$ôú[­ §Ì„”*Sôþ¬‰}Öìx?”õÜõ¸¾Õ`Æ‚‰5Ç`7•ÍÜÍo}7޾:£Þô¶¾BÀ€©1ª¡;øË­ý…‚€ÛN—âýrµ~ÿÔÉt¡Æ/´ÏIW|¡ãMüsôüýù¬8ò¶·Îù§Ñ7L•Q„½^lf~(8V¯Ô÷¶&¹ùzlÌ>u`l›*Û*öÅJþþ²ÐdÈA¿+”#˜9©!!TzŇzâ±²¶{nýŠ`ì8cc⃆Ëææ±éjˆõž±¡«úÛŸõ½©Ï@Ï¿€©“ZêO ’Ö°û¯Çzþ¡,t!ŸÐq–͈¯Ò€§  ²¿ÔyeC!eÇêOÊLy?”#˜J£þ:±Ik"åAÀ_æ Í!°öemÛwèýª X=lKêÜŠÐú)Ç*÷[Ÿi·¯s0‹¦Ö8B€HÚåmýmýõô²Pƒëq3ž]v<)ÛBY¥B/ú¬ˆ”ý`8£Œ¯H0ÕFDÂײשXÇ›$7H£« S65¶ÃLLô—ë‹•}ÿUÂlSoT!À_¯lf{êØ½Þ‡^/6¹°¬$_Öø•MÈ‹[•ýºý„Êúƒî3e=Ààf¨C€H¸7:-mÐ’~Jcní³¬—œº},ƒî'%ľ£²S-1Z3c”!À­+b«áå ýaJëÃHÝgÊD=)g1„Þ›03¥êxê>Ýú±qþÐ,ö*ï5è1¥xël‹²ÿVúÔ?ŒÀÌ©:Þ_e¿ëšúõAO±ÛëA  ëû‰}§U*#̨Ž`& 2Þ_uÿ!)¥íªã÷{}L|ÔÇTåŒ †P|Àôt¼÷qRç¤Îð/›sà^d"á ý  ÊõL²æ-Õ#Q¥¦Ç>yÀ®c®Ää{ åüÝQ+_Ì"!"!ΨˆÙ©€Y@€ È€ È€ ȧVÄi€€Y@€ È€ È€ È€ È€ È€ È€ È€ ÈPcÒ0mŠ¢˜ô!04*dˆ@†dˆ@†dˆ@†dˆëTÄu³€ "!"!"!"!.TÌ*dˆ@†dˆ@†dˆ@†dˆ@†dˆ@†dˆ@†dˆ@†dˆ@†“>€iSŤ€¡Q C2D C2D C2D C\ "®˜TÈ€ È€ È€ È€ È€ È€ È€ È€ È€ 5&}Ó¦(ŠIC£@†dˆ@†dˆ@†dˆ@†¸@E\0 ¨!"!"!"!"!"!"!"!"!"!jLú¦MQ“>†F€ È€ È€ È€ È€ q%ÀЏ `P C2D C2D C2D C2D C2D C2D C2D C2D C2D C2D CIÀ´)ŠbÒ‡ÀШ!"!"!"!"!"!"!~ °"~ 0 ¨!"!"!"!"!"!"!"!"!"!"!"!"!"!jLú¦MQ“>†F€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ È€ å:_/[09UÿÍÎúßôÜ@ˆõG”õ L ëßkþý6¶…}}ìM)ÿnóïø@?ëÃýµE¤µ»‡¨ %ñ¿‡°S(A6Eds‚LjkÊÎ@7€¦{þ"r}¢GˆY—nhoÝhø#“>€=Âÿ#ñÓ¢ûràjQÿLD–DdAºßßœˆÔ½[MD ïœþ7¹åÝ6·n7DdUDÖ¶–·¥ÿßpëßøìº…÷Xßü ÀêÖ²u™—nãߨº¹ÆßÝ0<ÿßbwkI·§ß”î¿Í.lˆ]°†²€~Vã¯C€Èö_Câ0¼Xpó³6¶n± @ö¾°“N›-é6èîÎoÜýõjÂŒšU‘mËö„?šÞ²–·s]:º]§M¿QwŒõ­×ý €[‡ÃñÇîý“Ýͯø!ÀoüÛÞ>[ýtÒ,¤û‡¤{ô¡ž?FË º o¡ ¿‡°ÍMl«{}ñ? 4%<ùÆFCwÎtÐsʪ€ã@ÄnÄýÒMÂ?FÚ ­ƒ€?$ +z!@";÷ØOŒz}÷UÈvÃOïÆ't†–»V‹¡†Ÿ°…°“®è×ܸ¿;;@7þbÜ£l+”Ýÿ7¶YÖÌQ?è’? ?Œ‡uµÖX]€ °…Ð¥¯èk«×üSc ?!Fú‚_(¤4ü„¡‘òYå{ݸëSüèùÀî ·¬XGo›=¬~¡1|ÝÈ[õ>£¥îØ¿P£Oã¿…Æj'«Œ_6¹ãe5þÖóXƒOãï¡¡ ‹5ê4ø0Y±@P 4\©bßß!LF¬a§Ñ/Aã5^|¿0r°Gü¤ÿDÕ!œ IEND®B`‚seafile-6.1.5/dmg/seafileLayout/Icons/LayoutItem.7DCEB33C-3B26-463C-9D52-D2E99ADD0AD0.icns000066400000000000000000000766561323477647300267150ustar00rootroot00000000000000icns}®TOC His32bs8mkil32:l8mkit32 ¡t8mk@ic08 ic09Ýis32bŽ!g!‡gÂg†_s®€°vv„w^râ€á ãáÞÞÜÙ×ÖÔÔsr×Õ:ÓªÒÏÍÌÊÈÉsoÎÎÏÏÎÍ¢¨ÉÉÈÆÆÄonËËÌËÁ§Ò›»ÆÅÄÃÄllÈÇ—¬›³¥«–“ÁÁkkö!로¡Ÿ©•¼¼liögÞ›ÇÛ™¼È¸¸ihö¸Läµ€³‘€³ hö¸ÅL䮬­°ž…€®fö¸€ä ¦¦§§±¹¨¨©fö¬Ðäˆ\^öää‰%Ž0z0‡zÎz†r„º€»†…o‚è€ç êçåäãâàßÝÞƒ‚ÞÜ ÛµÙ××ÕÓÒÓƒ~€×,Ø××°µÓÓÒÑÑÏ~~×ÔÕÕË´Ú©ÆÐÐÎÎÏ||ÓÑž¤·©¿³«¹¤£ÍÎ|zö 뮬®­·¬§ÈÊ|zögÞªÒΪªÈÒÆÇzzö¸LäÁ¡ŸÁÁÂ{ö¸ÅLä½»½À¬–½¼Àxö¸€ä ´´¶¶¿Æ¶¶ºvö¬Ðäˆnoöää‰-ŽQšQ‡šàš†ŒŸÌ€Í†Ÿœ€ôòôôññðîíìëïšœëêêçêèÆæåäãâá圚é‚å)ÃËáâááàäš—èãääÜÈçÀÙááàà䘖è᷼˿ÒÈÂϾ¿Þã––ö=ëÇÅÈÇÏÇÄÜã”–ögÞÃáàÆÆÛáÚÞ–”ö¸LäÖ××ÖÁÀ×ÖÚ–ö¸ÅLäÖÕÕ×ǺÕÕÛ–ö¸€äÍ Ó×ÍÍÕ”ö¬Ð䈊öää‰4s8mkE¥¥¥¥E¥ÿÿÿÿ¥†ÆææææÆÆÆÆÆÆÆÆÆ‡¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿº¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿº»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÿÿÿÆÆÆÆÆÆÆÆÆÆÆ³ÿÿÿ!#%')(&$""il32:áf„Žf“fÄ„ÉÄfs‘ކÄŽ66µ†½·‹œf‚”–·¶fUEj™}qH„ª××ÙØÚרר×ÖÕÓÓÒÏÐÏÐÏÎÎÊÌË¢~Ž®Ñт҂Ñо€ÎÌËÊÊÉÉÈÇÆÇȧ‡‡«Ð‚ÑÏÐÑÐÏÏέ¿ÍÌËÊÊÉ€ÈÇÆÆÅ¢~zªÎπРÏÏÎÌÎˤËÊÊ€ÉÈÇÇ€Æâvs¦Ì͆ÎÍÅÌŸ´ÊÉÈÇÈÇÆÆÄÅÆÆŸok¢Ë€ÌÍÌÌËÌË˾¦ÊÀ ÂÇÇ€Æ ÅÄÃÃÂÄœkd ˆÊ¤±ÆÊœ¨ÅÅÄÃÄÄÃÂÜbWžÈÈÇÈÈÉɀȷ¡Å¼Å¯œºÄÂÁ€ÂÁ˜ZY˜Å€Æ‚ÅĦ»ÆÂÜ¡ÂÁÀ¿À¿À˜UR•… »©•¾ÃÀÁÁ§›­»¾€½'¼½½¼“OJ“¿½¿ÀÀ‡‹­œ¶”’–µ› °Œ•¼»¼»»JK€¼½¼”ž®¤—¹žž¥¤§©ž ·¡š‚¹LHA‹º¹º¹¹‰®—“²š‘—–’š®’ž°‘·¶·¶·Š>5ƒ´¶¶µ¶ÆÅ¢Ž¯¶ÀÄÅž¹«•±Ãó³´´µ…<-}³²³²³³±’²³²¶Ž‘„²|<5ýúý°¨°±¬°°®¯¯®¯±Ÿ¢¯°®t7.ú|gLñ­£±­¬¬­­«­®„“«­¬­­¬m3)úö¬$ñ«±±«¬«€¬«¬¯½µ«¬««ª«e3 ù¬Å$ñŠc€b`b ^]V ý߸äLñ–ú|¬èîñü–úèõ™ýñùšáq„™q’qÏ„ÓÏqs‘™†Î™FFÀ†È˦q‚¡–ÃÁqU\z™ŒX‘´ÞÞßßàÞ߀ÞÝÜÛÛÚØÙ€Ø ××ÓÖÕ®š¸Ù„ÚÙØÈ€×ÕÕÓ ÒÑÑÒÒ³”‘µØ‚Ù×ÙÙØØ××¹ÉÖÕÔÓÔÓÒÓÒÒÑÑЮ‹‡²××‚Ø ÙØØ×Ö×Ó²ÕÔÔ€Ó€Ò€Ñήƒ±ÖÖ†×ÖÏÕ­ÀÓÓÒ ÐÐÏÐÑЬ}w®ÔÕÕÖÕ È³ÓʰÍÒÒÐÑÑЂΠ«xs¬ÓÔÓÔÓÔÔÓ ±½ÐÔ«µÐÐÏÎÎςΨtf«‚ÒÓÓ€Ò¯ÏÈм¬Æ€Î„Í¥hi¦€ÐÑ‚Ðά³ÇÐÎά¯ÍÍÌËÌËÌ¥aa¡ÎÍ€Î.ȶ£ÈÎÌÍÌ´«»ÈÉÈÉÉÈÉÈÈ¡`\¡ËÈËÌÌ•šºª«Â£Ÿ ¤Á«­½¤Ÿ‚È ZZœ‚È£¬º²¨Ä¬­³³­µ¶¬®Ã²«‚Ç›[V™‚Ç3˜ž»¦¢À§¡§¦¢©»£­½¢¢ÄÃÄÃÄ›NG’ÂÃÃÂÃÑѯž¼ÃÌÏÐÐÎËÇ·¥¾ÎÎÁÁ€Â”MAŒƒÁÀ œÀ…ÁáƒÁÀ‹NIýúýÀ¶Ž½Á»ÀÀ½¾¾½¾À­ž±¾À½…JCú|gLñ¼¬°Á¼»»¼¼º¼¼”£º¼»¼¼»~?0úö¬$ñ»ÁÁº»º€»º»¾Ëú»ºx?ù¬Å$ñusu qpiý߸äLñ–ú|¬èîñü–úèõ™ýñùšà.…„­….‘…à„âà…s.«†Þ«^^ÓÛÛÚƒÛÕ‹»….·–ÖÕ…–™£˜y¡Æê€ë…êèççåæ‚åäååÁ¢ªË€æçç…æØ€åääã€â‚áƨ Çƒæå€æ€åÌÚåä€ãâƒáàÄ›šÆ‚倿‚åáÇäãã€âƒáàÁ—Á‰åÞäÅÔâãƒáà€áÁ‡Áäåå‚äÚÈãÚÅÞƒá‚àÁˆˆ½âãâãâ‚ãâÇÑáãÄÍá…àßß»ˆƒ»€á‚â áâÖÆàÚàÑÅÙà…ßÞºw»†áàÂÈÙáàÞÄÈßÞÝÝÞÝÝÞÝÞºwtºàßßààÚ̾Ûà€ÞÌÄÐÛÝ„Ü#·ri·ÝÜÝÞݱµ³ÏÂÄÖ¿¸¹ÀÔÅÇÔ»À¼ÜÛÜÜÛ·js³‚ܼÅÏÈÁ×ÇÅËÊÇÍÍÇÊ×Ëǂ۲nl°‚Û¶»ÐÁ¿Ô¿ÁÃÁÄÒÂÈÕÂÁÚÙÚÙÚ¯md«×ÙááȽÑÙÝàáàßÝÛÐÅÖàà×Ú¬nb¦ƒ×ÖÀ½Ö†×ÀÁ„פadýú ýÖгÓ×ÕÖÖÕ‚ÖÈÁÌÖÖÕÖÖÕžcWú|gLñÕÇÊÖ…ÕÒÕÒ»ÃÓ‚Õ ™Y`úö¬$ñÒÖÖÒÒ€ÓÒÒÓÓÒÓÕÜ×‚Ò ÓYPù¬Å$ñŽ ŽŽ‚Pý߸äLñ–ú|¬èîñü–úèõ™ýñùšl8mk!|ÁÁÁÁÁÁÁ|! |àÿÿÿÿÿÿÿà| !¾ÿÿÿÿÿÿÿÿÿ¾AAúÿÿÿÿÿÿÿÿÿúÌÌÌÌÌÌÌÌÌÌÌÌÌÌ|!¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË| ,ËËËËËËËËËËËËËËËËËËËËËËËËËËËË.¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ±¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ³™ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ‰ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕŒ|ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ€oÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕrcÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕeWÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕZMÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕQDÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕG:ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ>3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÿÿÿÿÿÿãããããããããããããããããããããããÌÿÿÿÿÿÿÿHHHHHHHHHHHHHHHHHHHHHHE%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿit32 ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿf„ŽfÝÿ€fÄ„ÉÄfsŽÝÿ€Ž†ÄŽ6ŽÝÿ6µ†½·‹œf€Ýÿ”–·¶fUÝÿEj™}qHÝÿ„ª××ÙØÚרר×ÖÕÓÓÒÏÐÏÐÏÎÎÊÌË¢~ÝÿŽ®Ñт҂Ñо€Î ÌËÊÊÉÉÈÇÆÇȧ‡Ýÿ‡«Ð‚ÑÏÐÑÐÏÏέ¿ÍÌËÊÊÉ€ÈÇÆÆÅ¢~ÝÿzªÎπРÏÏÎÌÎˤËÊÊ€ÉÈÇÇ€ÆâvÝÿs¦Ì͆ÎÍÅÌŸ´ÊÉÈÇÈÇÆÆÄÅÆÆŸoÝÿk¢Ë€ÌÍÌÌËÌË˾¦ÊÀ ÂÇÇ€ÆÅÄÃÃÂÄœkÝÿd ˆÊ¤±ÆÊœ¨ÅÅÄÃÄÄÃÂÜbÝÿWžÈÈÇÈÈÉɀȷ¡Å¼Å¯œºÄÂÁ€ÂÁ˜ZÝÿY˜Å€Æ‚ÅĦ»ÆÂÜ¡ÂÁÀ¿À¿À˜UÝÿR•… »©•¾ÃÀÁÁ§›­»¾€½¼½½¼“OÝÿJ“¿½¿ÀÀ‡‹­œ¶”’–µ› °Œ•¼»¼»»JÝÿK€¼½¼”ž®¤—¹žž¥¤§©ž ·¡š‚¹HÝÿA‹º¹º¹¹‰®—“²š‘—–’š®’ž°‘·¶·¶·Š>Ýÿ5ƒ´¶¶µ¶ÆÅ¢Ž¯¶ÀÄÅž¹«•±Ãó³´´µ…<Ýÿ -}³²³²³³±’²³²¶Ž‘„²|<Ýÿ5ýúý°¨°±¬°°®¯¯®¯±Ÿ¢¯°®t7Ýÿ .ú|gLñ­£±­¬¬­­«­®„“«­¬­­¬m3Ýÿ )úö¬$ñ«±±«¬«€¬ «¬¯½µ«¬««ª«e3Ýÿ ù¬Å$ñŠc€b`b^]V Ýÿý߸äLñ–Ýÿú|¬èîñü–Ýÿúèõ™ÝÿýñùšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿq„™qÝÿqÏ„ÓÏqsŽÝÿ€™†Î™FŽÝÿFÀ†È˦q€Ýÿ¡–ÃÁqUÝÿ\z™ŒXÝÿ‘´ÞÞßßàÞ߀ÞÝÜÛÛÚØÙ€Ø××ÓÖÕ®Ýÿš¸Ù„ÚÙØÈ€×ÕÕÓÒÑÑÒÒ³”Ýÿ‘µØ‚Ù×ÙÙØØ××¹ÉÖÕÔÓÔÓÒÓÒÒÑÑЮ‹Ýÿ‡²××‚Ø ÙØØ×Ö×Ó²ÕÔÔ€Ó€Ò€ÑήƒÝÿ±ÖÖ†×ÖÏÕ­ÀÓÓÒÐÐÏÐÑЬ}Ýÿw®ÔÕÕÖÕ È³ÓʰÍÒÒÐÑÑЂÎ«xÝÿs¬ÓÔÓÔÓÔÔÓ ±½ÐÔ«µÐÐÏÎÎςΨtÝÿf«‚ÒÓÓ€Ò¯ÏÈм¬Æ€Î„Í¥hÝÿi¦€ÐÑ‚Ðά³ÇÐÎά¯ÍÍÌËÌËÌ¥aÝÿa¡ÎÍ€Îȶ£ÈÎÌÍÌ´«»ÈÉÈÉÉÈÉÈÈ¡`Ýÿ\¡ËÈËÌÌ•šºª«Â£Ÿ ¤Á«­½¤Ÿ‚È ZÝÿZœ‚È£¬º²¨Ä¬­³³­µ¶¬®Ã²«‚Ç›[ÝÿV™‚ǘž»¦¢À§¡§¦¢©»£­½¢¢ÄÃÄÃÄ›NÝÿG’ÂÃÃÂÃÑѯž¼ÃÌÏÐÐÎËÇ·¥¾ÎÎÁÁ€Â”MÝÿAŒƒÁÀ œÀ…ÁáƒÁÀ‹NÝÿIýúýÀ¶Ž½Á»ÀÀ½¾¾½¾À­ž±¾À½…JÝÿ Cú|gLñ¼¬°Á¼»»¼¼º¼¼”£º¼»¼¼»~?Ýÿ 0úö¬$ñ»ÁÁº»º€»º»¾Ëú»ºx?Ýÿù¬Å$ñusuqpiÝÿý߸äLñ–Ýÿú|¬èîñü–Ýÿúèõ™ÝÿýñùšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿ€.…„­….Ýÿ…à„âà…sŽÝÿ.«†Þ«^Ýÿ^ÓÛÛÚƒÛÕ‹»….Ýÿ·–ÖÕ…Ýÿ–™£˜yÝÿ¡Æê€ë…êèççåæ‚åäååÁ¢ÝÿªË€æçç…æØ€åääã€â‚áƨÝÿ Çƒæå€æ€åÌÚåä€ãâƒáàÄ›ÝÿšÆ‚倿‚åáÇäãã€âƒáàÁ—ÝÿÁ‰åÞäÅÔâãƒáà€áÁÝÿ‡Áäåå‚äÚÈãÚÅÞƒá‚àÁˆÝÿˆ½âãâãâ‚ãâÇÑáãÄÍá…àßß»ˆÝÿƒ»€á‚â áâÖÆàÚàÑÅÙà…ßÞºÝÿw»†áàÂÈÙáàÞÄÈßÞÝÝÞÝÝÞÝÞºwÝÿtºàßßààÚ̾Ûà€ÞÌÄÐÛ݄ܷrÝÿi·ÝÜÝÞݱµ³ÏÂÄÖ¿¸¹ÀÔÅÇÔ»À¼ÜÛÜÜÛ·jÝÿs³‚ܼÅÏÈÁ×ÇÅËÊÇÍÍÇÊ×Ëǂ۲nÝÿl°‚Û¶»ÐÁ¿Ô¿ÁÃÁÄÒÂÈÕÂÁÚÙÚÙÚ¯mÝÿd«×ÙááȽÑÙÝàáàßÝÛÐÅÖàà×Ú¬nÝÿb¦ƒ×ÖÀ½Ö†×ÀÁ„פaÝÿdýú ýÖгÓ×ÕÖÖÕ‚Ö ÈÁÌÖÖÕÖÖÕžcÝÿ Wú|gLñÕÇÊÖ…ÕÒÕÒ»ÃÓ‚Õ™YÝÿ `úö¬$ñÒÖÖÒÒ€ÓÒÒÓÓÒÓÕÜׂÒÓYÝÿPù¬Å$ñŽŽŽ‚PÝÿý߸äLñ–Ýÿú|¬èîñü–Ýÿúèõ™ÝÿýñùšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿt8mk@!|ÁÁÁÁÁÁÁ|! |àÿÿÿÿÿÿÿà| !¾ÿÿÿÿÿÿÿÿÿ¾AAúÿÿÿÿÿÿÿÿÿúÌÌÌÌÌÌÌÌÌÌÌÌÌÌ|!¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË| ,ËËËËËËËËËËËËËËËËËËËËËËËËËËËË.¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ±¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ³™ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ‰ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕŒ|ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ€oÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕrcÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕeWÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕZMÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕQDÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕG:ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ>3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÿÿÿÿÿÿãããããããããããããããããããããããÌÿÿÿÿÿÿÿHHHHHHHHHHHHHHHHHHHHHHE%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿic08 ‰PNG  IHDR\r¨fðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ ãIDATxœíÝMlgÇñßì®íµÇiâ¶*I“8´QÚ¦P¨ªT@TJ%NôP©B‰PÕR…¸äB$nQï¸Eõ‚DUˆSÊ­ šÒÚ’W»vlïë¼<ÏŸÃì®mD%HR;“ÿ÷#­e­Ç³;òÎwžyÙubfàSm»Ÿ€íCÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽ5¶û àÖ$I²­ofÛúø¸5ŒÇà»w•/Ì¿øò 'Ž9rüÓ¦¸xñâïöê/ÏIoÿs+ŸîLàn±gÏÌ‹'_8qòä‰ï5j>m²cÇž< I3µã¯ž={¶³uOw"vîK{çŽ9üŒ,ÈóBŸv“ÅGŽ~æÍ¿,“î»»Ÿ6¶WÂQÜjž8öìÉoþøô~Ûl6ÇÊŸ˜¤ÿ~† ˳üò¿®¼}3÷ÖŸßúÕÆ]^?ÕÆ.À]âä‰ïü V¯eyþ?LŒí}pï“7ó8Ïí}Î$鯥Sg_{퇽›™îŒ*îÙï¾rôáý÷oÏoåã¶; ï¼óÑÏó‹ŸÞÔHwF÷¯úÉáÏ?|øñGzT’jI9ø¯mº@È¢”$’Y¹c`*¿7“¢EI&3)Ĩ$Idf›¦“¤¢0Õê‰Ì¤wÞ}jfÇÔ¼¤ooåòâö"759©FcLY^HÉp¯¸òÛú×ÿè™IË+kÚ5;3º/F+Wø8ÂhÚ2&)dllL“ãD®8þ€—öº !åVÚ†[u­´!Øh ^níM1š¢™n¬¶µºÖ)ïƒß‰å^nùm=Éú¦¬£‹ƒ¦›Mµ{}-.¯jçÌ´êI­Üâ'¶>»d0)/‚2Ë»[»´¸Ý@ÅõóN7*”ûü¡¼R¯<õgúãŸþªÉfCyˆ:tpŸZí®šÍqõ³\{ï’Š"U-IÔhLèÀƒsj÷RµÖzª×zÿëšœ(/0zü‘ƒåõ–Œ.- &å#€ª#—Ä©´È …ÁÉýLÉàò™ÓššœÔ®Såþ~4Ú·G—¯­hjj\ã;d2¥YÐZ;ÕÎé¦:ÝL+«]=vxŸn´•¦…Âè"€õQFÈsŤA*ŽT\·H‹"^È3¼~_’:LynÚ5;­V;UQD¥EP‘çêeAéx!³šŠ"*As»wªÝëhÇT¢4‹ZYé•gFïHu[Vlã¢ã6 ×^íý4O²¼P-)é–ûëÒמzL&éƒ\U¯_h~ÿœõ1~x¯õúhW¡<`•QÌE-,w”$‰¾|t¿$i¥Unè‡ï/J¬®< I´$lÃ"ã6"×Ïb‘eyb&G#€Ä¤¥•®¢™VVûJ¢ToŒ©ˆQkLÒæÑÂÐôŽ ¥WVôá¿•ÔïÛô³õ= ^¯Ÿ(i1¨8PqÍfÍ^yù…GBؼ1®×ëúõ›ïªßÍ´´ÜÒ—¾xP–$ʳ¨ÆØàýÁFïŽ̤{v5µ¼šje¥£™™©ÁËŒ¤Vþ^?Ë’¼¨ñaG*.ÍZ !èÌ™3Z\\ÔåË—õúë¯kuuU¡0uº==tè~%ºŠ<*I¤P¬ŸÚ“l4´!¨V«kvvJ—¯¶´:VÓää„jµÚúiÀXþ^šæõ¢Ó%Ç…@—/Mš$>}ZÇ×Å‹G?‹4wï¬vÞ³CYZÈ,È,n¸Ië÷I’YTR«ë©¯ÎëÐÁ9•dcPˆåôý¬ÇÆã.À±â.-¬,›™Þxã =ÿüóºpá‚N:%I:ÿ»?\úç·q“£©VÛüÁ¢Eaƒ@{éïïõoéÉcÛñ™€c´?þXóóó:þ¼Ž=ª—^zIçÎÓììì·>£‡ ’>”ô ‡¨$PqyžÛ™3gôÄOèé§ŸÖøø¸êõº¦§§Õh4>óÿÊë§Ú@Ååynãããºvíšfff4==½¥ÿ.˜×Oµ€Š‹1Z»ÝV³ÙÔÄÄÄ–ÿ¯p^?ÕFÇ8 8FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽÀ18FÇà#€cpŒŽýàßG”…Q)IEND®B`‚ic09݉PNG  IHDRôxÔúðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ IDATxœíÝMŒ]ç]Çñÿ½3cÇ™8MÜV%i‡6rÛ A• ˆJ©ÄŠ.*U("ªºBª›l¨‚Ä.êž»¡n¨J±ª"PÙDSÚB[â¼Øµ=ö¼Ý—sÎÃâ΋]QNêéÍïó‘®5ºsî¹÷,<çû<çåŽZkdŸôî>H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ Z=éܹÑht¢ïßZ;Ñ÷îœ$ CðŽñ >ÿÅÏ=}ñâŧ~Ò¯¼òÊßÿÙ—ÿòŪoþçÝüdÀÏï<°ùùg>÷ô3Ï<ýûk«ãG~ÒbO>ùñGªª6ÇO}ù…^ؽ{øYã¼\}ðüÅ‹ªÚðÈ|ÞÕOzT¹xññO}ý_®óàgZUÕõWŸ}á+_ùÃý;Yð³Á ,±Oÿî—žøàÃïý½îßüõ»ù¾;»»/ë[?øó¿ù‹?½£™à䙀%ö¿òØŸ<þó|ü£þÀ‡«ªÆ£Åäÿø¶µê‡ªÑ¨ªµÅV‹Ÿ[«ÚPU­Z«ê‡¡F£QµÖn[®ªªëZWFÕZÕ·¾ýÝÍ{6.TÕoßÍíÞ>–ØÆ™3µººV³yW5:<ê¸óoÇÿþØD_kU×¶nÖ}ç6ž†¶ØáAp´ì"ZUbmm­Îœ>å$bXbþÛîï]îûn1Jo‡£úv´Óîûv4‚_Œö[ C«¡µº~c§nÜÜ]®4Ú?ƒÃ窃ùýÉ´F㕚χzóÊVÕá4ÿQ<X<×QUµ2U?TMg““Únà­°Ä&“Ùv×Wµƒ)üÃY€vCkÕ‹çûƒÇ›»õƒW/×0´ºðþw×¶nÔdÖÕІ£þQLÔñÎZuýÁºZU7ŸÞ<éí%6íF;ÃÐUkÃÁhXì ûþèçvmhÕ†¡^{ójÝ8S]?ÔÆÆ™êæ­^{ãz #ý¡µêûVCËLÀÑ;¶ªUõ³Úïjûä¶x«,±ííùÎpËο?š8>pq(`±ÌÕë;Õ­Îß®ö&Óšw}=ð®ÍÚÙŸÔîÞä`ô¿8_àÖó ê`]u°Þ®o5ÙÙ÷]°Ä,±ñÊÎÞl^Õ‹“ówàýÁt}×NýWuÝP¯]þQ­­Žko2­õÓÕUçï߬ªV¯¿yýèøÿ0 Õ·Ì*FFŽÎ˜O'îKÌ}`‰M'ý~?_ìäosxÇŸƒë÷¦³Y]»v³&û]]xè}µvj­f]ts ³ëëµ³?©+×nÔ½›gke4^ŒøGíxu£ƒ€j5ïúšµùÞÝÝZàí$`‰Mæ»{Cõ‹cþýâN}‹KÿZýã?ýkY_­y?Ôc>TÛ;{µ¾~ª&³yýÛw^­®›Öx4ªÕÕÓõÈûÏ×Îþ´¶oî×Êxµ¾ûý×ëÌéÅ †>ú¡G÷h££[ õ­j>3ËLÀ ÓnÞUpqß·ܾgóÞ³µqæLÝwïÆâxÿÐ걇¨KolÕÆÆ©:}êžjÕj:ëëæÎ´î=»^»{³Úº±Wyü¡º|}§¦Ó®ú£›Ï2ôóy £UKLÀÛë¦]×÷íðF>‡÷ﯪÚÝÕ|Þê¾sgk{gZ]7Ô´ë«›ÏkÖ×ôTW­«ë†ê»¾ÎßoíìïÖ=£šÎ†ÚÚÚ_œ xp5ÀÑwŒFÕW_{Û­;ÁMÞ"KlçÆ¤›Lç£Ù¼«ñhqNïâx}Õ¯}â#Õªê{ÿñzíOººððùZ]Y«Ç?ø`­®¬*Xœ08Ô¼ê}燺|m·F£QýòWUÕÖöb øýB£¶Rói?Ú¨?MÞ&–Ød6t³Ù|ÔZU׆£€Q«ººµWCkµucR£¡jeu­ºa¨›»³ªº}¶àÐÙ{N×ôµ­úþ]©ÑÊ{nûÝñ‘€¾ö÷'£m›€%&`‰­¯Û—¾ø¹õýíƒñ•••ú믻&{³ºzm»~é­6Õ|6ÔêÚÁ÷ôíè»g Z«z×}ëuíÆ´¶¶vkssã`‹ £ñâu“Ùl4ïÆ?ÞÀ°Ä¦³íêû¾žþùºråJ]ºt©¾úÕ¯Ö7ªïZíîí×{oVWª›5UõÝñ¥}Uíhj¿ïûWêܹºôúvÝX×™3§k<_8,^7ÎWºÝ=KÌ€`‰Í¯žiUUÏ=÷\=õÔSõÊ+¯ýnh}÷¹º÷]÷ÔlÚUk}µ6Üòè«êø¹ªªÖ†Wê¿z¡{ô|Uµƒ×õ5 }õÃbùÉlßà–œÿİÄ^½¼u­µV_ûÚ×곟ýl½üòËõì³ÏVUÕK÷¯þ×wë~ZÇ£Û~ßuí``çê¿gÿÊ[úðÀ‰ÝúÝßÀr†¡ýð‡?¬ .ÔK/½TO<ñD}á _¨_|±Î;÷[?¥·í«êûUõ½v8u,Kl>Ÿ·çŸ¾>ö±Õ'?ùÉ:uêT­¬¬ÔÙ³gkuuuô¿¯á­ñ÷–—€%6ŸÏÛ©S§ê7Þ¨ÍÍÍ:{öìO}§+?`y XbÃ0´Z__¯Ó§OßÕ•€e& Ë €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ý7åÅáGB¾1WIEND®B`‚icnV ¿€seafile-6.1.5/dmg/seafileLayout/Icons/LayoutItem.830478CF-49D6-4772-AC6C-3A56A329536F.icns000066400000000000000000000741101323477647300265630ustar00rootroot00000000000000icnsxHTOC His32s8mkil32jl8mkit32 àt8mk@ic08 lic09ÿis32ŽN‡N¯N†DZš€œƒ\^^\DZ×€Ö ØÖÒÒÏËÉÇÅÅXZÉÇ+ÅÂÃÀ¼»¹¶¸XW½½¿¿¾¼º¹··¶´³±UT¹º»º¹¹··´³²±°°RR¶€µ ´³²°¯¯­¬­­QOª®­«¨©¨€§¦PO¤¥¤£ƒ¢¡ON›œ€œ›™‚›NM“””“”’“””–••–”KMŽŽŽ‚LB‹AB*‹Ž(i(‡iÃi†as¯†u`rã€â åáßÞÝÜÙØÕÖpr×Ô ÓÑÐÎÎÌÊÈÉpn€Î-ÏÎÎÌËÊÉÈÇÇÅnlÎËÌÌËËÉÈÇÆÆÄÄÅjkÊÇÈÈÇÆÆÄÃÃÂÁÂÃkhÂÂÁ¾¾½¿ij½¼»»ƒº»jh·€¶€µ´µ´¶hh°€¯°®®‚°¯´ggª¨¦¦ƒ¨­f\3‹%ŽI‰I‡‰Ù‰†{‘Ć‘|€òïòòîîíêéèçì‹çååâåã€àÞÝÜÛàŒ‰äà ßÞÞÛÜÛÛÙÞ‰ˆãÝ€ÞÝÝÜ€ÛÚÙÞ‡…ã‚ÛÚÙÙØ€×Ý……ÞØ×Ø€×ÕÖÕ݃…Ù‚ÔÓÒ€ÓÒÒ×……ÔˆÏÎÓ†…ÔʈÍÔ†ƒÍ‰ÃÍ„y‹|y;‹-s8mkE¥¥¥¥E¥ÿÿÿÿ¥†ÆææææÆÆÆÆÆÆÆÆÆ‡¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿº¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿº»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿³ÆÆÆÆÆÆÆÆÆÆÆÆÆÆ³!#%')(&$""il32jáP„vP“P³„¸³Ps‘w†±w''¡†¨¤‹…P‚{–¢ Pq4U™eV1k”ÉÊÌËÍÊËÊËÉÈÇÅÅÿÀ¿À¿¾½¹»ºŠfwšÁ‚ÀÂ"ÁÁÀ¿¾½½»º¹¹¸·¶µ´µ¶mn–ÀÁÁÂÁÁ¿ÁÁÀ¿¿¾€½»º¹¹·€¶´³´²Œgb”¾¿ ÀÀÁ¿¿¾»½»ºº¹¹¸¸·¶µµ´³³°Š\Z»½¾½½¾ƒ½»º¹¹¸·¶µ¶µ³³±²³³‰WUŒº€»½»»º»€º¹¹¸·€µ€³ ²±°°¯±†RMЏ‡¹·€¶´´²²±°±°°¯°¯¯„IC†¶¶µ¶¶··¶³µ³²€°±¯¯®®­€®­€DB²€³„²±°°¯®¯®®­¬«¬««¬«¬~>?}¯®¯ ­®®­¬­«ª¬«ª©€¨ §¨¨§z94z«¨«¬¬€«¬«ª«€¨§§¨¦¦¥‚¦¥¥w92v€§¨§¦‚§€¥£¢¤¤€£¢ƒ£ r00r¤£¤££¤£¢¢¡¢¢ ¡‚ ¡¡ ¡ ¡q.)j ŸŸ  Ÿ Ÿ ‚žššžœšœœžk&'b›š›š›œš€›€š›‹š b*!Y•–—–—˜—“——–——––—˜™–——–—˜–Y%!O““”’ƒ”““””’” “”“””“QI€‘’‘’’‘’“’€“’€“’’“‘’‘J;CEFFŒGFGEG€FDC<ýà`„‰`‘`Æ„ÉÆ`sІÄŠ: :´†½·‹˜`‘–·¶`qKj™}oH€¦×רØÙר€×ÕÔÓÓÒÏÐ€Ï ÎÎÊÍÌ {Š«Ñ„ÒÑÐÎÌÌÊÊÉÉÈÇÇÈȦ„~¨Ð‚ÑÎÐÑÐÏÎÎÍÎÍÌËÊËÊÈÉÈÈÇÇÆ¡{w¥Î΀πРÏÏÎÍÎÍÌÌËˀɀȀÇÄ¡rl¢Í͆ÎÍÍËËÊÊÉÈ ÆÆÅÆÇÆœmg ËÌÌ͂̀ÊÉ€ÈÆÇÇÆ€Ä ÃÄœfaœÊËÊËÊËËÊÉ€ÈÇÇÆÆÅÄÄÅÄÃÄÃÚbW›‚ÈÉÉÈÇÈÆÆÄÃÄ–ZY–€ÆÇ„ÆÅÄÄÃÂÀÂÁÀÁÀÁ•UR’ÃÂÃÂÁÂÀÀÁÀÀ¾½¾¾½¾½½OJÀ½ÀÁÁ€ÀÁ€À¾ˆ½¼½½¼JKމ½¼¼„»ºƒ»ŒLKŠ…»º»ºº¸ºº¸¹·¸¸··¸¸·¸·¸ŠHA‚¶··¶·¶·‚¶ ´µ¶¶µ´¶¶µµ€¶…BA{‚´µ´´µ´³|B3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÊããããããããããããããããããããããããããããÌ#EJHHHHHHHHHHHHHHHHHHHHHHHHHE%it32 àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿP„vPÝÿ€P³„¸³PsŽÝÿ€w†±w'ŽÝÿ'¡†¨¤‹…P€Ýÿ{–¢ PqÝÿ4U™eV1Ýÿk”ÉÊÌËÍÊËÊËÉÈÇÅÅÿÀ¿À¿¾½¹»ºŠfÝÿwšÁ‚ÀÂÁÁÀ¿¾½½»º¹¹¸·¶µ´µ¶mÝÿn–ÀÁÁÂÁÁ¿ÁÁÀ¿¿¾€½»º¹¹·€¶´³´²ŒgÝÿb”¾¿ÀÀÁ¿¿¾»½»ºº¹¹¸¸·¶µµ´³³°Š\ÝÿZ»½¾½½¾ƒ½»º¹¹¸·¶µ¶µ³³±²³³‰WÝÿUŒº€»½»»º»€º¹¹¸·€µ€³²±°°¯±†RÝÿMЏ‡¹·€¶´´²²±°±°°¯°¯¯„IÝÿC†¶¶µ¶¶··¶³µ³²€°±¯¯®®­€®­€DÝÿB²€³„²±°°¯®¯®®­¬«¬««¬«¬~>Ýÿ?}¯®¯ ­®®­¬­«ª¬«ª©€¨§¨¨§z9Ýÿ4z«¨«¬¬€«¬«ª«€¨§§¨¦¦¥‚¦¥¥w9Ýÿ2v€§¨§¦‚§€¥£¢¤¤€£¢ƒ£r0Ýÿ0r¤£¤££¤£¢¢¡¢¢ ¡‚ ¡¡ ¡ ¡q.Ýÿ )j ŸŸ  Ÿ Ÿ ‚žššžœšœœžk&Ýÿ'b›š›š›œš€›€š›‹šb*Ýÿ!Y•–—–—˜—“——–——––—˜™–——–—˜–Y%Ýÿ!O““”’ƒ”““””’”“”“””“QÝÿI€‘’‘’’‘’“’€“’€“’’“‘’‘JÝÿ;CEFFŒGFGEG€FDC<ÝÿÝÿÝÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿ€`„‰`Ýÿ`Æ„ÉÆ`sŽÝÿІÄŠ: Ýÿ:´†½·‹˜`Ýÿ‘–·¶`qÝÿKj™}oHÝÿ€¦×רØÙר€×ÕÔÓÓÒÏЀÏÎÎÊÍÌ {ÝÿŠ«Ñ„ÒÑÐÎ ÌÌÊÊÉÉÈÇÇÈȦ„Ýÿ~¨Ð‚ÑÎÐÑÐÏÎÎÍÎÍÌËÊËÊÈÉÈÈÇÇÆ¡{Ýÿw¥Î΀πРÏÏÎÍÎÍÌÌËˀɀȀÇÄ¡rÝÿl¢Í͆ÎÍÍËËÊÊÉÈÆÆÅÆÇÆœmÝÿg ËÌÌ͂̀ÊÉ€ÈÆÇÇÆ€ÄÃÄœfÝÿaœÊËÊËÊËËÊÉ€ÈÇÇÆÆÅÄÄÅÄÃÄÃÚbÝÿW›‚ÈÉÉÈÇÈÆÆÄÃÄ–ZÝÿY–€ÆÇ„ÆÅÄÄÃÂÀÂÁÀÁÀÁ•UÝÿR’ÃÂÃÂÁÂÀÀÁÀÀ¾½¾¾½¾½½OÝÿJÀ½ÀÁÁ€ÀÁ€À¾ˆ½¼½½¼JÝÿKމ½¼¼„»ºƒ»ŒLÝÿKŠ…»º»ºº¸ºº¸¹·¸¸··¸¸·¸·¸ŠHÝÿA‚¶··¶·¶·‚¶ ´µ¶¶µ´¶¶µµ€¶…BÝÿA{‚´µ´´µ´³|BÝÿÝÿ3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÊããããããããããããããããããããããããããããÌ#EJHHHHHHHHHHHHHHHHHHHHHHHHHE%ic08 l‰PNG  IHDR\r¨fðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ /IDATxœíÝÍ‹]wÇñÏïÜ™Tc-T¤ŽQLš±ED¢›ÔEÁ’ ‚‹º­K]ôOèRBv.ݹ¶VÁ…k@¡´EÔm}ˆI&sÎ9߯‹ópï„4ÉÜÉ™Ïû™ÇûHrÞç÷ûsoJf €§ê¤€“Cc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0Fc0¶sÒ§”r¢÷Ÿ™'zÿx8Œc0Æà4ùÐÅ /}ýÚË/_þÊý.òö›oþêõŸþì'ºõö_·ùÐðx"§Åùó|ék×^þÎ÷^ùîî¬Ú»ßÅ^xáêž$}ú|ܸ~ýúÝí=@<Ž˜œÍù_Ú¿übD»·¬kÝïOD»wiÿò‹¿øí;_Ô.|ä¤6N#€SâÒgŸýäþþsWç˦ÿIJzï#Ï?ÿ¹«çÎ=ýùŸßÿî7¯3…8=À)ño~ëûe¶³»ZÕÿÃ¥Ëî3{{_xûùø'žIIºðôG¯ß¸ñêüAnÂqÜi»òÕ¿¿_$U¥üWGNJµ!•"evƒ”Ñ}’R‘RÓ†J)ÊLu·•)¥RM“ªfE™ÒÿüÖÙ§ž<{AÒµ­?i<2`âž<û>ÙÝÕbÕ¨”aÖ?lü¹þ˜›?éÎàËè6ìágÝ×))û ¿¿lÿu‰îÖÏœ™é‰÷?Á"òÄñ8qóƒÃw›6Ç4²Û`£ÿÓ4©ì7ìÈTD*ÚTD÷ý‡ˆþ6¢"„†ß÷)ëÑ@©¦N­æ·ß=¹gŽGÀÄ,ÿ‰¶Q„T”GþK‘JŸøˆ~CN©ÍTU†iÀðóÏËBãÑÆ"B µº;¯oß3Ã6€‰[Ü=¸S·m·QK*]$¥J–~>Ìæ;•ú½{?P?ÇÏìæþ›×ˆè®™*¥¨iVeªëåÁVŸ,90quÝÜi£ºGѸÊW©¨Õ0—Ï{°±ç×0uÈñGÝš@¬3U•¢VR½œßÞÒÓÄ1!·XUÑÔŠ  Ëü¥[Ù/ë­x½ñç¸N0ìçûôŸû¿~±/ËzêPJö—OE4š7³;Û{¦8`âçM¿¸§¿4l°Ã<~½Á·Ù.ìVýsæKÝ:Bôÿ! ã5ÇïSMÓª^,x-ÁÄ€‰Ëj~Xס&6ÖÿJ®ïŽè¶ôa!pø:3Çs¤aZý^¿[PÖREE‘Òª^q&àÄ€‰k—‹yÓ¤Úv=‡—Öõæaqš õñý2ŽJwQçôÓ„{§ÃIAu¨^-·öDq,ÀÄÝ]äa­š¶QÛ¦f³Ò¿MX·Ê?öäݦ.µ¡q—?| c„—­ÏRG2»#€É#egÙD£¦í¶Ô¦M ÿ޾p=:iÜø‡“ªqd°9ŠX¯#jã:’T·+Í«ŠL˜¸PÛ4M“m¬÷îÝfZÆHk0¬þgäÆIBR–PFY£¿âx ¡?`ü­¢©†×c¢ÀÄ-Ûf±X–e]kVªñÔÞ#€ã ~)à zQI 5Ñýr§ ‹‚Ý€YÕÝ@Þƒ’3­ê¦,VM»­ç‰ãA&.4o˦DH­b |¿Sï_¸yp (ÆÑ‚Rjî9rÐÆÑï×ë­æóEÙÑœÀÄ€‰[ÕUÎç‡Õª•ªôèÕ•Jë…Àng¯¦Míìöóý6ÇÿW`8/¨T}_”º©Þó`#¦ƒLÞR‡‹eÝÁýE»”¢(úþt+E¥¤Úæè BÃáÂhUÕ¬¿þp$asîŸÝ("¥Åªž­êšL˜¸ÕA•«ºÞÞÔcxA`j=goc=%8r\`<hógë›'EJ@÷2¢årÁ¿S€¿Ä‰ËÅ­ß¾}óŸo¼ñóÝj¶qðÆÇÿóÇ5„Èõ; ¢,çÿªoÞúÇÃ=zœ4ÞpâJ);’ö$}JÒ®Öçò§VÒß$ý%3·q8&`âøÏAñ0xK0ÀŒ1Œ1ŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒÀŒýã ƒH¶µ IEND®B`‚ic09ÿ‰PNG  IHDRôxÔúðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ÂIDATxœíÝÍ«eÙ]Çáß:·ª£mlJP‘X–bwºL‘ÖIÇAÀ™Òq"‡:ðOp(MÏ:slŒ‚Ǿ€ "BH‚¨ÓøÒvwu{ïÙ{-{Ÿ—*Ò •ª[}êûðäŒ@ LÀ‹â^½÷¥_}ë˯¾þú/}Ô]¾ùõ¯ÿÕWÿôÏþ¤Þûæ¿Þä[>~¼îÜùþ/ýÊ[_þ­ßùÊoß¾ØÜý¨»}á oÞ­ªúÉ;ý·ß~ûÛ{ƒÀÇ)xLw~ðµû¯±÷ùîÕnWõ§÷ùîk÷_ÿâ_üí·~¾¾ïÞ=ï· BàóŸÿ™7_yåÓø$¯ó÷÷7_5…//€_ûõßøÝvqëöõõîÿpïvû3wïþÜ“¼ÎþØgFUÕ½OÿðÛï¼óûÛ'yàã¡9ŽÎ׿ü{Ÿ»w÷G~óSw^ùÅ›|Ý÷Þÿ௿õÿãøË?ú§›|]àé1gìÞø©?xýÕϾúÆÏ޿ߪjÓ–ÁÿÍ#'5÷ªÖªÆX&zU¾üÞG¯ªQ}TMs¯ÖZ1ªÕò\cT5M£6­Æ¨úÇþÆËŸúäË÷ªê­ÿÐÀS!àŒ}òåï©—nß®Ëë©ZÛÏúï7þãøuœÞ²œÁoôeþ¿­÷åçÑGUuÿÞwý¹õåÙ_zé¢>ñ½Ÿ°ˆΘÀpƶ~{šÇa#ÝDzÁîëŸi5Ö {£zÕçQ½/¿ïã ÷õ9ú2DÐkÿ÷kD´ãhÀÔGM»Q×Û÷¿ýü>9ðÝ2gìÁÕåÿôyªÞ«ZGþ·VÕÖÄï}ݪyŒÚ´ý4Àþö“ï'Ë‚K„NFz¯ê5ׇÛÝ»Ïî“Ïš€3vùáƒvó¼lÔ«ª-PU£Úhëü~6±©uï~¨uŽŒeîÿô½/écTk­Z«ºØ´»^»ÝÕƒý°ÀS%àŒívÓs_†î{«Ã*¿Mµšk?—?K€“=ÿÚOŒÃ=z¯ÃH²& ŽQ›Öj®ªÝÕöýú˜À3 àŒ]^oôiW}ôjµ_æß–•ýí¸?nüÇaÀ~?mõûºào]ì7Úqê µ±ÞTïSm§‹nî“O›€3öðáöÁ´.î«“ÿªý{?ÜàÏc9\pYõ?ÃüUË:‚¾NüïÃàðÈÃi®Ýå¥k ÀpÆÆfûp·ë5õ“õmï=bÙÒïîcÎPµŸë^ÿ². Ú~}Á¨V­ú¨ºÞ]; œ1gl¾ºÜNÓ¨y>ÎáW7꧇¦ êx|;Œ´å$Bc.€ušàñ)€ýIv½v×WoìƒO€3öáåx8÷¹¦yªyuqѪµe¨œí·ý ÿeAàÜë°Ë¿ÿÚk?Fpr)¡ã™ƒjì0cA0gMÀëíÖÕÔ§šæeK=Í£öÿ=z=Àãè@¯:lü÷'ÚFNGŽëëä1UU»ùº¶›€3&àŒõš§išÆÜ{÷ËfºB ª5°_ý?ú89IPÕh½FoÇbXx8`=Àá{Ÿ«O›ýµ‡3$àŒ]=œ§ËË«vµÛÕEÛNí{ràakû ÿ¬ú¦ªzM}ùË[m¿(p9àb³<Áx,Ú¸¨ëÝÔ.¯§ù¦>'ðô 8c½¶ÓåÕÔz¯š«FZí7øëNýz ÀÓƒZõÃhAªé±#æþèïÇõsm·—íVmÀpÆ®w›±Ý>Ü\ïzµM[`9T¯mê¸pÙÙ¯iuëö:ß?uÁທ¿^; Õ20¯—®Çž³Ï£¶Û˶›6ßñ`Cà<8kWõðòjÓ—ƒûOíªÞª¯þYVþµjmÔ<=z‚ ýá‚}žj³¹X¿?’àtî,££êòzwq½Û 8cÎØõƒÍ¸Þín-sûËqú‡i€5æ~œx一à €No;xz2¡¾ž`¹L@«««KÿwÀ™óÎØ¸|ï¿ßÿÝÿüÚ×þüöæâä4À'_ÿŸÏxXCÐ×SŸîæ÷uàjûà¿vï¾÷ßÝ»ž§6†Q<8W­µ[Uu·ª~¢ªn×ñ\>ÏÒ\UÿVUÿ2Ƹ‰×žg¬µ'ÙËzüÿçkó¼ßpó2Œ@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ ú_)V…HŒ+9›IEND®B`‚icnV ¿€seafile-6.1.5/dmg/seafileLayout/Icons/LayoutItem.CFA83A1B-E783-4354-88A9-255F0F623398.icns000066400000000000000000000657231323477647300265750ustar00rootroot00000000000000icnskÓTOC @is32us8mkil32ol8mkit32 Üt8mk@ic09§is32uŽ!g!‡gÂg†_s®€°vv„w^râ€á ãáÞÞÜÙ×ÖÔÔsr×Õ+ÓÑÒÏÍÌÊÈÉsoÎÎÏÏÎÍËÊÉÉÈÆÆÄonËËÌËÊÊÉÁ«™Ž™ª¼llÈ€Ç ÆÆ¾¡¾ãû㾟nkÀÂÁ §¾êͼÍê¾|iº»º–ãÍ€ºÍã„h³€´³³û¼€ÿ¼ûŠh€­¬­«“ãÍ€ºÍã…h§¨€§ ¦™¾êͼÍê¾y^ƒ\ a~¾ãûã¾~c3„H{†Š‡~Q%Ž0z0‡zÎz†r„º€»†…o‚è€ç êçåäãâàßÝÞƒ‚ÞÜ ÛÙÙ××ÕÓÒÓƒ~€×,Ø××ÕÔÓÓÒÑÑÏ~~×ÔÕÕÔÔÓɱœŽœ°Ç||ÓÑÒÒÑÐÈ¥¾ãûã¾¥}zƒÍ ®¾Û—`—Û¾ƒz‚ÈÇšã—€[—ã‡zÀÂÁÁû`€ÿ`ûŠz½€¼½»—ã—€[—ãˆx¸¶ ´¢¾Û—`—Û¾‚oƒn r‚¾ãû㾂t;„H{†Š‡~Q-ŽQšQ‡šàš†ŒŸÌ€Í†Ÿœ€ôòôôññðîíìëïšœëêêçêèææåäãâá圚é‚å ääáâááàäš—èã€ä ããØ»¡Ž ºÙ˜–è‚áÖ¬¾ãûã¾­’–äßÞßÞÞº¾Ø‹:‹Ø¾Ž–߂۟㋀0‹ãŒ”ۂ׎û:€ÿ:û‹”ÛÓÕã‹€0‹ãŒÕ‚Í °¾Ø‹:‹Ø¾Šƒ ‹Š¾ãû㾊‡D„H{†Š‡~Q4s8mkE¥¥¥¥E¥ÿÿÿÿ¥†ÆææææÆÆÆÆÆÆÆÆÆ‡¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿº¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿï¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿý¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿð¾ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝ³ÆÆÆÆÆÆÍêÿÿÿÿÿê¼!#%'CÎøÍ‹8"il32oáf„Žf“fÄ„ÉÄfs‘ކÄŽ66µ†½·‹œf‚”–·¶fUEj™}qH„ª××ÙØÚרר×ÖÕÓÓÒÏÐÏÐÏÎÎÊÌË¢~Ž®Ñт҂ÑÐÏ€ÎÌËÊÊÉÉÈÇÆÇȧ‡‡«Ð‚ÑÏÐÑÐÏÏÎÍÎÍÌËÊÊÉ€ÈÇÆÆÅ¢~zªÎπРÏÏÎÌÎÌËËÊÊ€ÉÈÇÇ€Æâvs¦Ì͆ÎÍÌË€ÊÉÈÇÈÇÆÆÄÅÆÆŸok¢Ë€ÌÍÌÌË̀ˀÊÉ€Ç€Æ ÅÄÃÃÂÄœkd ˆÊÉ€ÈÆÆÅÅÄÃÄÄÃÂÜbWžÈÈÇÈÈÉÉÈÆÇÆÅ€ÃÄÂÁ€ÂÁ˜ZY˜Å€Æ„ÅÄÃÂÂÁÀ¿À¿À˜UR•†Â ÁÂÂÁÀÁ¿¿À¿¿¾€½ ¼½½¼“OJ“¿½¿ÀÀ€¿À€¿€½¼¼½¼¼»€¼»¼»»JK€¼½„¼€»¹¹ºº€¹¸ƒ¹ HA‹º¹º¹¹º¹¸¸·¸¸··¶··¶¶±£••£ˆ>5ƒ´¶¶µ¶µ¶‚µ²²µ´³²®›¾ãû㾈\-}³²³²³³²€³€²³„² Ÿ¾êͼÍê¾5t®¯°¯¯°¯¬°°®¯¯®¯°°±“ãÍ€ºÍã†.k¬¬­«ƒ­¬¬­­«€­û¼€ÿ¼ûŠ)c†«¬«€¬«€¬“ãÍ€ºÍ㈠T]bŠc€bu¾êͼÍ꾃”3|¾ãû㾂{•ˆ‰Š‰ˆ¾áq„™q’qÏ„ÓÏqs‘™†Î™FFÀ†È˦q‚¡–ÃÁqU\z™ŒX‘´ÞÞßßàÞ߀ÞÝÜÛÛÚØÙ€Ø ××ÓÖÕ®š¸Ù„ÚÙØ×ÕÕÓ ÒÑÑÒÒ³”‘µØ‚Ù×ÙÙØØ××Ö×ÖÕÔÓÔÓÒÓÒÒÑÑЮ‹‡²××‚Ø ÙØØ×Ö×ÖÕÕÔÔ€Ó€Ò€Ñήƒ±ÖÖ†×ÖÖÔÔ€ÓÒ ÐÐÏÐÑЬ}w®ÔÕÕÖ‚ÕÓ€ÒÐÑÑЂΠ«xs¬ÓÔÓÔÓÔÔ‚Ó€ÒÑÑÐÐÏÎÎςΨtf«‚ÒÓÓÒÑÒÐЃ΄Í¥hi¦€ÐÑ„ÐÏ€ÎÍ΀ÍÌËÌËÌ¥aa¡ÎÍÎÍÌÍËËÌËËÉÈÉÉÈÉÈÈ¡`\¡ËÈËÌÌ€ËÌ€ËɌȠZZœ‹È„ÇÆƒÇ›[V™…ÇÆÇÆÆÄÆÆÄÅÃÄÄÃýªššª–NG’ÂÃÃÂÃÂÂÂÁÁÂÂÁÁ» ¾ãûã¾cAŒ’Á §¾Û—`—Û¾I„¼¾ À¾¾À¾»ÀÀ½¾¾½¾€À˜ã—€[—ã†C{»»¼»ƒ¼»»¼¼º€¼û`€ÿ`ûŠ0w‚º»»ºº»º€»º€»—ã—€[—ãˆgp‘u}¾Û—`—Û¾ƒ”3|¾ãû㾂{•ˆ‰Š‰ˆ¾à.…„­….‘…à„âà…s.«†Þ«^^ÓÛÛÚƒÛÕ‹»….·–ÖÕ…–™£˜y¡Æê€ë…êèççåæ‚åäååÁ¢ªË€æçç…æåääã€â‚áƨ Çƒæå€æƒåä€ãâƒáàÄ›šÆ‚倿ƒåääãã€âƒáàÁ—Á‰åääããâãƒáà€áÁ‡Áäååƒäããââ„á‚àÁˆˆ½âãâãâ‚ãââáâá…àßß»ˆƒ»€á‚âáâá‚à…ßÞºw»†áƒàß ÞÝÝÞÝÝÞÝÞºwtºàß߀àÞ€ßÞÞÝÞހ݄Ü·ri·ÝÜÝÞÝÞ݈ÜÛÜÜÛ·js³‰ÜÛ²nl°‡ÛÚÛÚÙ‚Ú Ð·žŽž·ªmd«×†Ù€×Ù×Ö‚× Î¨¾ãûã¾—xb¦’×µ¾Ø‹:‹Ø¾„džÕÖÖÕƒÖÕÖÖÕƒÖ×ã‹€0‹ã‡W–ŽÕÒ€ÕŽû:€ÿ:ûŠ`‘Ó†Ò€Ó ÒÒÓÓÒÓÓҜ㋀0‹ã‰PƒŽ‘‹¾Ø‹:‹Ø¾…”3|¾ãû㾂{•ˆ‰Š‰ˆ¾l8mk!|ÁÁÁÁÁÁÁ|! |àÿÿÿÿÿÿÿà| !¾ÿÿÿÿÿÿÿÿÿ¾AAúÿÿÿÿÿÿÿÿÿúÌÌÌÌÌÌÌÌÌÌÌÌÌÌ|!¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË| ,ËËËËËËËËËËËËËËËËËËËËËËËËËËËË.¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ±¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ³™ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ‰ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕŒ|ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ€oÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕrcÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕeWÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕZMÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕQDÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕG:ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ>3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðH'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ&Úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿù%ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÊãããããããããããããããããããããðÿÿÿÿÿÿÿ„#EJHHHHHHHHHHHHHHHHHHH^¾ÿÿÿÿÿ²! {ÆøÆ{ it32 ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿf„ŽfÝÿ€fÄ„ÉÄfsŽÝÿ€Ž†ÄŽ6ŽÝÿ6µ†½·‹œf€Ýÿ”–·¶fUÝÿEj™}qHÝÿ„ª××ÙØÚרר×ÖÕÓÓÒÏÐÏÐÏÎÎÊÌË¢~ÝÿŽ®Ñт҂ÑÐπΠÌËÊÊÉÉÈÇÆÇȧ‡Ýÿ‡«Ð‚ÑÏÐÑÐÏÏÎÍÎÍÌËÊÊÉ€ÈÇÆÆÅ¢~ÝÿzªÎπРÏÏÎÌÎÌËËÊÊ€ÉÈÇÇ€ÆâvÝÿs¦Ì͆ÎÍÌË€Ê ÉÈÇÈÇÆÆÄÅÆÆŸoÝÿk¢Ë€ÌÍÌÌË̀ˀÊɀǀÆÅÄÃÃÂÄœkÝÿd ˆÊÉ€ÈÆÆÅÅÄÃÄÄÃÂÜbÝÿWžÈÈÇÈÈÉÉÈÆÇÆÅ€ÃÄÂÁ€ÂÁ˜ZÝÿY˜Å€Æ„ÅÄÃÂÂÁÀ¿À¿À˜UÝÿR•†Â ÁÂÂÁÀÁ¿¿À¿¿¾€½¼½½¼“OÝÿJ“¿½¿ÀÀ€¿À€¿€½¼¼½¼¼»€¼»¼»»JÝÿK€¼½„¼€»¹¹ºº€¹¸ƒ¹HÝÿA‹º¹º¹¹º¹¸¸·¸¸··¶··¶¶±£••£ˆ>Ýÿ5ƒ´¶¶µ¶µ¶‚µ²²µ´³²®›¾ãû㾈\Ýÿ-}³²³²³³²€³€²³„²Ÿ¾êͼÍê¾Ýÿ5t®¯°¯¯°¯¬°°®¯¯®¯°°±“ãÍ€ºÍã†Ýÿ.k¬¬­«ƒ­¬¬­­«€­û¼€ÿ¼ûŠÝÿ)c†«¬«€¬«€¬“ãÍ€ºÍãˆÝÿ T]bŠc€bu¾êͼÍ꾃Ýÿ”3|¾ãû㾂{Ýÿ•ˆ‰Š‰ˆÝÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿq„™qÝÿqÏ„ÓÏqsŽÝÿ€™†Î™FŽÝÿFÀ†È˦q€Ýÿ¡–ÃÁqUÝÿ\z™ŒXÝÿ‘´ÞÞßßàÞ߀ÞÝÜÛÛÚØÙ€Ø××ÓÖÕ®Ýÿš¸Ù„ÚÙØ×ÕÕÓÒÑÑÒÒ³”Ýÿ‘µØ‚Ù×ÙÙØØ××Ö×ÖÕÔÓÔÓÒÓÒÒÑÑЮ‹Ýÿ‡²××‚Ø ÙØØ×Ö×ÖÕÕÔÔ€Ó€Ò€ÑήƒÝÿ±ÖÖ†×ÖÖÔÔ€ÓÒÐÐÏÐÑЬ}Ýÿw®ÔÕÕÖ‚ÕÓ€ÒÐÑÑЂÎ«xÝÿs¬ÓÔÓÔÓÔÔ‚Ó€ÒÑÑÐÐÏÎÎςΨtÝÿf«‚ÒÓÓÒÑÒÐЃ΄Í¥hÝÿi¦€ÐÑ„ÐÏ€ÎÍ΀ÍÌËÌËÌ¥aÝÿa¡ÎÍÎÍÌÍËËÌËËÉÈÉÉÈÉÈÈ¡`Ýÿ\¡ËÈËÌÌ€ËÌ€ËɌȠZÝÿZœ‹È„ÇÆƒÇ›[ÝÿV™…ÇÆÇÆÆÄÆÆÄÅÃÄÄÃýªššª–NÝÿG’ÂÃÃÂÃÂÂÂÁÁÂÂÁÁ» ¾ãûã¾cÝÿAŒ’Á§¾Û—`—Û¾ÝÿI„¼¾ À¾¾À¾»ÀÀ½¾¾½¾€À˜ã—€[—ã†ÝÿC{»»¼»ƒ¼»»¼¼º€¼û`€ÿ`ûŠÝÿ0w‚º»»ºº»º€»º€»—ã—€[—ãˆÝÿgp‘u}¾Û—`—Û¾ƒÝÿ”3|¾ãû㾂{Ýÿ•ˆ‰Š‰ˆÝÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿ€.…„­….Ýÿ…à„âà…sŽÝÿ.«†Þ«^Ýÿ^ÓÛÛÚƒÛÕ‹»….Ýÿ·–ÖÕ…Ýÿ–™£˜yÝÿ¡Æê€ë…êèççåæ‚åäååÁ¢ÝÿªË€æçç…æåääã€â‚áƨÝÿ Çƒæå€æƒåä€ãâƒáàÄ›ÝÿšÆ‚倿ƒåääãã€âƒáàÁ—ÝÿÁ‰åääããâãƒáà€áÁÝÿ‡Áäååƒäããââ„á‚àÁˆÝÿˆ½âãâãâ‚ãââáâá…àßß»ˆÝÿƒ»€á‚âáâá‚à…ßÞºÝÿw»†áƒàß ÞÝÝÞÝÝÞÝÞºwÝÿtºàß߀àÞ€ßÞÞÝÞހ݄Ü·rÝÿi·ÝÜÝÞÝÞ݈ÜÛÜÜÛ·jÝÿs³‰ÜÛ²nÝÿl°‡ÛÚÛÚÙ‚ÚзžŽž·ªmÝÿd«×†Ù€×Ù×Ö‚×Ψ¾ãûã¾—xÝÿb¦’×µ¾Ø‹:‹Ø¾„ÝÿdžÕÖÖÕƒÖÕÖÖÕƒÖ×ã‹€0‹ã‡ÝÿW–ŽÕÒ€ÕŽû:€ÿ:ûŠÝÿ`‘Ó†Ò€Ó ÒÒÓÓÒÓÓҜ㋀0‹ã‰ÝÿPƒŽ‘‹¾Ø‹:‹Ø¾…Ýÿ”3|¾ãû㾂{Ýÿ•ˆ‰Š‰ˆÝÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿt8mk@!|ÁÁÁÁÁÁÁ|! |àÿÿÿÿÿÿÿà| !¾ÿÿÿÿÿÿÿÿÿ¾AAúÿÿÿÿÿÿÿÿÿúÌÌÌÌÌÌÌÌÌÌÌÌÌÌ|!¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË| ,ËËËËËËËËËËËËËËËËËËËËËËËËËËËË.¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ±¯ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ³™ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ‰ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕŒ|ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ€oÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕrcÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕeWÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕZMÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕQDÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕG:ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ>3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðH'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ&Úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿù%ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÊãããããããããããããããããããããðÿÿÿÿÿÿÿ„#EJHHHHHHHHHHHHHHHHHHH^¾ÿÿÿÿÿ²! {ÆøÆ{ ic09§‰PNG  IHDRôxÔúðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@jIDATxœíÝOŒ]ç]Çáß{ZÛàþ!¢$´a"+ •À"Qj5ªhWUe0Tªºä6!"buÏ‚ .ŠPÊ ³h‘@* $©Enˆ•Ö$ÎØž™{ï9/‹sïÜ™Pd<ãÜ|ŸGJf2sîÜ{™÷sß÷=gºÖZYÖîö Žž€@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@ $ €@¿Û/¸}]×ÝÕço­ÝÕçnŸ$ %xÇøÐ>ÿŸ¾pöìÙ'Þꈗ^zé…ßÿŸõÛ¿õ×'NœX¿Óªê¾B`2L_¹ò_¿çûÚßíO÷.!øý«Ë¼\¼ð™_];vl}2þŽîÖïàþs·ó<Ÿ¼ÿ“­ªêõoýò³_üâonÝÎÏÞÌÀ ûø/ýÎcÞ÷Ù{¾ïôÏåóÞ¸yóï^|ñßÿà/ÿè÷nk&¸ûÌÀ ûÈO|ðwyxã‘}ôG­ªZëÆÉÿµ}7jÕU]WÕÚ¸0Ðjü¼µª¡ UÕªµª~ªëºj­í;®ªj6kµv¬«Öª^|ùßNþÞS¨ª_8Êóî+ìÔÉ“uüøzM¦³ªn±ê¿üÛòß&úÆÁ¿íûò0Œÿ݆yì;ÆA«ªnëëëuòÝﲉV˜ÿa…ílÝz­ïgã»ô¶g`ŸÚ}ßvßÁïö[ C?îýú0Ì0Žðã;ÿ¶Ì€nyl?´šN‡ÚÚÚ|í¨Ï¸sÌÀ Û¼5y£õã€ÞØøßU·{•À0¯€1–Kðøúb¶ í›-Ø ÃPUÕ×ööìõÃ9+à(Xa;Û››³6­ù÷Ú¿ò¿½÷?¦«1Ú°wÀoÕªÛ]Ø]ÿÆÇ ­U×uÕuUÇֺꇪÉöÃ=;à0 XaÛÛ“ÍY_Ë©ûùèÝU·»`ïÆ¿…¶˜ÿŸg°XC¨qÐo‹)ÿù±Ë%qݰoU³éΛ‡†Àa°ÂvfÝa˜UkCµEtÝ8ŠwËQ|9ø/óE û¦ùçþ†ùlÂb?@-fZ+“ÚšÕæ‘œ$p(¬°ÍÍé¡ ã;øÅôýî¾½åºÕþl„q“ß0,^WUÃÞǵڷ$0þ¤V³¾Õö-KV˜€¶vìÆ­É´Æëüç_k]Û·ioié×ÿW-–ÿ—k㘿¼Š`÷ž‹é€=sÓmw„&`…íl÷[ý´U?ñƒúžm­ ÕíNä×îÀ>^ ÐÍo´g@k»Ó c ´y$´šÎúš´é­Ã?Cà°XaÛÓ›·†ê«ïûúñN}ã¥mwÕòüb"¼×ÏžU;0Í?O‡Ý™‚VÕ– ûV5˜€U&`…uéÙtV}?Í}ߪÛs¿¥và³yì¿ÏÏþ+ÚráÁïöÓi Ýq+LÀ »5Û™Íú¾ ®ß¯Ÿ/¾¹Øý߆VÝü> m¨ª®Uºå…óN'·êÍk¯Ö›o¼ZÛ›oÔ‰Óï«÷¼ïk:Ý^¿µÙfGr’À¡°Ân\ßžmïL»ÉtVkóý¿¿sßsuàÞua­ª†êçQp¬g÷ýŸM¶êÚ+ÿZ?xoýìO>QgΜ©«W¯ÖåË—ë•+ß¼÷ÁøžûŽê<;OÀ Ûž ³ÉdÚµV5kÃrŸþž]þ»-°ÿ.¿Õí^ð7ÑX7¸þWëáï­Çø¡ºòç\/õKõþªûØ'ªªÞ»uãÚÏUÕ_Ò©‡Ì‚vâÄZÛÚÞ^›N‡êûñúü¾Æ­-¿ÖÆ“É0ÿC@­¦³ñ1}ßj6?.¾×ZÕëWkcc£®|åùºv鹦·êÚ¥çêÊWž¯z÷ú±ÜíónŸXa;“ÍÚÚÚ^ZUõmÏÔ«–øg~ €êºª~¶ÿA‹Çô}_kkÇv?¹y½Îœ9S/õKõÄþãîsþÍgª>ô¹_¯ãÇ=zè'+lzídÛžMkûn4؇=ƒÿþû´ù¾€ý÷ ˜Vï:õžºzõj½ÿߪ~ñÇv¹ç§/ÔÕ«WkÚ¿Æ9GCÀ ûÖkoüçõ7ÞüΟ}ù…õõõý;ÿº·xÌÿfo?ÜsbvúòåËï¯ù×ëó=|ìõÏ—/×t:ûòí¿rànëZkßý(àm©ëºãUõPU}°ªÖkw²ÿÿïܹs÷>ùä“¿rþüùnllì» àÒ¥KÏïììüÚ3Ï<ó;õ|ÀѰºƒ×ûÝaO=õÔŸ?}¯®¯ ­®®­¬­«ª¬«ª©€¨ §¨¨§z94z«¨«¬¬€«¬«ª«€¨§§¨¦¦¥‚¦¥¥w92v€§¨§¦‚§€¥£¢¤¤€£¢ƒ£ r00r¤£¤££¤£¢¢¡¢¢ ¡‚ ¡¡ ¡ ¡q.)j ŸŸ  Ÿ Ÿ ‚žššžœšœœžk&'b›š›š›œš€›€š›‹š b*!Y•–—–—˜—“——–——––—˜™–——–—˜–Y%!O““”’ƒ”““””’” “”“””“QI€‘’‘’’‘’“’€“’€“’’“‘’‘J;CEFFŒGFGEG€FDC<ýà`„‰`‘`Æ„ÉÆ`sІÄŠ: :´†½·‹˜`‘–·¶`qKj™}oH€¦×רØÙר€×ÕÔÓÓÒÏÐ€Ï ÎÎÊÍÌ {Š«Ñ„ÒÑÐÎÌÌÊÊÉÉÈÇÇÈȦ„~¨Ð‚ÑÎÐÑÐÏÎÎÍÎÍÌËÊËÊÈÉÈÈÇÇÆ¡{w¥Î΀πРÏÏÎÍÎÍÌÌËˀɀȀÇÄ¡rl¢Í͆ÎÍÍËËÊÊÉÈ ÆÆÅÆÇÆœmg ËÌÌ͂̀ÊÉ€ÈÆÇÇÆ€Ä ÃÄœfaœÊËÊËÊËËÊÉ€ÈÇÇÆÆÅÄÄÅÄÃÄÃÚbW›‚ÈÉÉÈÇÈÆÆÄÃÄ–ZY–€ÆÇ„ÆÅÄÄÃÂÀÂÁÀÁÀÁ•UR’ÃÂÃÂÁÂÀÀÁÀÀ¾½¾¾½¾½½OJÀ½ÀÁÁ€ÀÁ€À¾ˆ½¼½½¼JKމ½¼¼„»ºƒ»ŒLKŠ…»º»ºº¸ºº¸¹·¸¸··¸¸·¸·¸ŠHA‚¶··¶·¶·‚¶ ´µ¶¶µ´¶¶µµ€¶…BA{‚´µ´´µ´³|B3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÊããããããããããããããããããããããããããããÌ#EJHHHHHHHHHHHHHHHHHHHHHHHHHE%it32 àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿP„vPÝÿ€P³„¸³PsŽÝÿ€w†±w'ŽÝÿ'¡†¨¤‹…P€Ýÿ{–¢ PqÝÿ4U™eV1Ýÿk”ÉÊÌËÍÊËÊËÉÈÇÅÅÿÀ¿À¿¾½¹»ºŠfÝÿwšÁ‚ÀÂÁÁÀ¿¾½½»º¹¹¸·¶µ´µ¶mÝÿn–ÀÁÁÂÁÁ¿ÁÁÀ¿¿¾€½»º¹¹·€¶´³´²ŒgÝÿb”¾¿ÀÀÁ¿¿¾»½»ºº¹¹¸¸·¶µµ´³³°Š\ÝÿZ»½¾½½¾ƒ½»º¹¹¸·¶µ¶µ³³±²³³‰WÝÿUŒº€»½»»º»€º¹¹¸·€µ€³²±°°¯±†RÝÿMЏ‡¹·€¶´´²²±°±°°¯°¯¯„IÝÿC†¶¶µ¶¶··¶³µ³²€°±¯¯®®­€®­€DÝÿB²€³„²±°°¯®¯®®­¬«¬««¬«¬~>Ýÿ?}¯®¯ ­®®­¬­«ª¬«ª©€¨§¨¨§z9Ýÿ4z«¨«¬¬€«¬«ª«€¨§§¨¦¦¥‚¦¥¥w9Ýÿ2v€§¨§¦‚§€¥£¢¤¤€£¢ƒ£r0Ýÿ0r¤£¤££¤£¢¢¡¢¢ ¡‚ ¡¡ ¡ ¡q.Ýÿ )j ŸŸ  Ÿ Ÿ ‚žššžœšœœžk&Ýÿ'b›š›š›œš€›€š›‹šb*Ýÿ!Y•–—–—˜—“——–——––—˜™–——–—˜–Y%Ýÿ!O““”’ƒ”““””’”“”“””“QÝÿI€‘’‘’’‘’“’€“’€“’’“‘’‘JÝÿ;CEFFŒGFGEG€FDC<ÝÿÝÿÝÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÝÿÝÿÝÿ€`„‰`Ýÿ`Æ„ÉÆ`sŽÝÿІÄŠ: Ýÿ:´†½·‹˜`Ýÿ‘–·¶`qÝÿKj™}oHÝÿ€¦×רØÙר€×ÕÔÓÓÒÏЀÏÎÎÊÍÌ {ÝÿŠ«Ñ„ÒÑÐÎ ÌÌÊÊÉÉÈÇÇÈȦ„Ýÿ~¨Ð‚ÑÎÐÑÐÏÎÎÍÎÍÌËÊËÊÈÉÈÈÇÇÆ¡{Ýÿw¥Î΀πРÏÏÎÍÎÍÌÌËˀɀȀÇÄ¡rÝÿl¢Í͆ÎÍÍËËÊÊÉÈÆÆÅÆÇÆœmÝÿg ËÌÌ͂̀ÊÉ€ÈÆÇÇÆ€ÄÃÄœfÝÿaœÊËÊËÊËËÊÉ€ÈÇÇÆÆÅÄÄÅÄÃÄÃÚbÝÿW›‚ÈÉÉÈÇÈÆÆÄÃÄ–ZÝÿY–€ÆÇ„ÆÅÄÄÃÂÀÂÁÀÁÀÁ•UÝÿR’ÃÂÃÂÁÂÀÀÁÀÀ¾½¾¾½¾½½OÝÿJÀ½ÀÁÁ€ÀÁ€À¾ˆ½¼½½¼JÝÿKމ½¼¼„»ºƒ»ŒLÝÿKŠ…»º»ºº¸ºº¸¹·¸¸··¸¸·¸·¸ŠHÝÿA‚¶··¶·¶·‚¶ ´µ¶¶µ´¶¶µµ€¶…BÝÿA{‚´µ´´µ´³|BÝÿÝÿ3ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ5/ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ1+ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ.'Öÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×*&ØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ)&ÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛ(%Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿß(ÊããããããããããããããããããããããããããããÌ#EJHHHHHHHHHHHHHHHHHHHHHHHHHE%ic09ÿ‰PNG  IHDRôxÔúðiCCPICC Profile(‘UÝoÛT?‰o\¤? ±Ž‹¯US[¹­ÆI“¥éB¹ÍØ*¤ÉunS×6¶ÓmUŸöo ø€²xB Äö²í´ISAÕ$¤=tÚ@h“ö‚ªp®¯S»]Ƹ‘¯9çw>ïÑ5@ÇWšã˜I`Þò]5Ÿ‘Ÿ˜–;V! ÏA'ô@§¦{Nº\..Æ…GÖÃ_!ÁÞ7ÚëÿsuV©§$žBlW=}ñi€”©;® ÞFùð)ßAÜñ<â.&ˆXax–ã,Ã38Sê(b–‹¤×µ*â%Äý31ùl ó‚µ#O-êºÌzQvíšaÒXºOPÿÏ5o6Zñzñéòæ&â»Õ^wÇÔ®k¹IÄ/#¾æø&ñ½Æ\%x/@ò™š{¤ÂùÉ7ëSï Þ‰¸jø…©P¾hÍ”&¸mryÎ>ª†œkº7Š=ƒߪÓB‘ç#@•fs¬_ˆ{ë±Ð¿0î-LæZ~ë£%îGpßÓÆËˆ{èÚêÏYX¦f^åþ…+Ž_sÖ-³Tä>‰D½ Æ@îקƸ-9àã!r[2]3ŽBþ’c³ˆ¹‘ónC­„œš›Ës?ä>µ*¡ÏÔ®ª–e½D|Ž%4 `à î:X°2¨‡ ¾pQSL”PÔR”‰§aeíyå€ÃqĘ ¬×™5FiÏáî„›t…ìÇç )’Cd˜Œ€LÞ$o‘Ã$‹ÒrpÓ¶‹ÏbÝÙôó>4Ð+ãƒÌ¹žF_ï¬{ÒЯô÷kû‘œi+ŸxÀô˜ñú¯.ý°+ò±B.¼{³ëêL<©¿©Û©õÔ î«©µˆ‘ú=µ†¿UHcnfÑ<>F‡Ë ^Ãe||ÐpÿyvŒ·%bÍ:×iX'襇%8ÛI•ß”?•å å¼rw[—ÛvIøTøVøQøNø^ødá’pYøI¸"|#\ŒÕãçcóìƒz[Õ2M»^S0¥Œ´[zIÊJ/H¯HÅÈŸÔ- IcÒÔìÞ<·x¼x-œÀ½ÕÕö±8¯‚ZNxA‡-8³mþCkÒK†HaÛÔ³Yn1Äœ˜Ó ‹{ÅqHg¸•Ÿ¸u#¸ç¶Lþ˜ hŒ¯s ˜:6«Ìz!Ðy@}zÚgí¨íœqÙº/ïS”×å4~ª¨\°ôÁ~Y3M9Py²K=ê.Ðê °ï ¿¢¨Á÷-±óz$óß8ôÞY7"Ùtàk ûµHÖ‡wⳟ\8 7Ü…ðÎO$~ðjû÷ñ]¼›n5›ð¾êø`ããfóŸåfsãKô¿pÉüYqxÄ(Â@ÂIDATxœíÝÍ«eÙ]Çáß:·ª£mlJP‘X–bwºL‘ÖIÇAÀ™Òq"‡:ðOp(MÏ:slŒ‚Ǿ€ "BH‚¨ÓøÒvwu{ïÙ{-{Ÿ—*Ò •ª[}êûðäŒ@ LÀ‹â^½÷¥_}ë˯¾þú/}Ô]¾ùõ¯ÿÕWÿôÏþ¤Þûæ¿Þä[>~¼îÜùþ/ýÊ[_þ­ßùÊoß¾ØÜý¨»}á oÞ­ªúÉ;ý·ß~ûÛ{ƒÀÇ)xLw~ðµû¯±÷ùîÕnWõ§÷ùîk÷_ÿâ_üí·~¾¾ïÞ=ï· BàóŸÿ™7_yåÓø$¯ó÷÷7_5…//€_ûõßøÝvqëöõõîÿpïvû3wïþÜ“¼ÎþØgFUÕ½OÿðÛï¼óûÛ'yàã¡9ŽÎ׿ü{Ÿ»w÷G~óSw^ùÅ›|Ý÷Þÿ௿õÿãøË?ú§›|]àé1gìÞø©?xýÕϾúÆÏ޿ߪjÓ–ÁÿÍ#'5÷ªÖªÆX&zU¾üÞG¯ªQ}TMs¯ÖZ1ªÕò\cT5M£6­Æ¨úÇþÆËŸúäË÷ªê­ÿÐÀS!àŒ}òåï©—nß®Ëë©ZÛÏúï7þãøuœÞ²œÁoôeþ¿­÷åçÑGUuÿÞwý¹õåÙ_zé¢>ñ½Ÿ°ˆΘÀpƶ~{šÇa#ÝDzÁîëŸi5Ö {£zÕçQ½/¿ïã ÷õ9ú2DÐkÿ÷kD´ãhÀÔGM»Q×Û÷¿ýü>9ðÝ2gìÁÕåÿôyªÞ«ZGþ·VÕÖÄï}ݪyŒÚ´ý4Àþö“ï'Ë‚K„NFz¯ê5ׇÛÝ»Ïî“Ïš€3vùáƒvó¼lÔ«ª-PU£Úhëü~6±©uï~¨uŽŒeîÿô½/écTk­Z«ºØ´»^»ÝÕƒý°ÀS%àŒívÓs_†î{«Ã*¿Mµšk?—?K€“=ÿÚOŒÃ=z¯ÃH²& ŽQ›Öj®ªÝÕöýú˜À3 àŒ]^oôiW}ôjµ_æß–•ýí¸?nüÇaÀ~?mõûºào]ì7Úqê µ±ÞTïSm§‹nî“O›€3öðáöÁ´.î«“ÿªý{?ÜàÏc9\pYõ?ÃüUË:‚¾NüïÃàðÈÃi®Ýå¥k ÀpÆÆfûp·ë5õ“õmï=bÙÒïîcÎPµŸë^ÿ². Ú~}Á¨V­ú¨ºÞ]; œ1gl¾ºÜNÓ¨y>ÎáW7꧇¦ êx|;Œ´å$Bc.€ušàñ)€ýIv½v×WoìƒO€3öáåx8÷¹¦yªyuqѪµe¨œí·ý ÿeAàÜë°Ë¿ÿÚk?Fpr)¡ã™ƒjì0cA0gMÀëíÖÕÔ§šæeK=Í£öÿ=z=Àãè@¯:lü÷'ÚFNGŽëëä1UU»ùº¶›€3&àŒõš§išÆÜ{÷ËfºB ª5°_ý?ú89IPÕh½FoÇbXx8`=Àá{Ÿ«O›ýµ‡3$àŒ]=œ§ËË«vµÛÕEÛNí{ràakû ÿ¬ú¦ªzM}ùË[m¿(p9àb³<Áx,Ú¸¨ëÝÔ.¯§ù¦>'ðô 8c½¶ÓåÕÔz¯š«FZí7øëNýz ÀÓƒZõÃhAªé±#æþèïÇõsm·—íVmÀpÆ®w›±Ý>Ü\ïzµM[`9T¯mê¸pÙÙ¯iuëö:ß?uÁທ¿^; Õ20¯—®Çž³Ï£¶Û˶›6ßñ`Cà<8kWõðòjÓ—ƒûOíªÞª¯þYVþµjmÔ<=z‚ ýá‚}žj³¹X¿?’àtî,££êòzwq½Û 8cÎØõƒÍ¸Þín-sûËqú‡i€5æ~œx一à €No;xz2¡¾ž`¹L@«««KÿwÀ™óÎØ¸|ï¿ßÿÝÿüÚ×þüöæâä4À'_ÿŸÏxXCÐ×SŸîæ÷uàjûà¿vï¾÷ßÝ»ž§6†Q<8W­µ[Uu·ª~¢ªn×ñ\>ÏÒ\UÿVUÿ2Ƹ‰×žg¬µ'ÙËzüÿçkó¼ßpó2Œ@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ H@ ú_)V…HŒ+9›IEND®B`‚icnV ¿€seafile-6.1.5/dmg/seafileLayout/Info.plist000066400000000000000000000061041323477647300205010ustar00rootroot00000000000000 content identifier Layout.B0B66CEF-E35C-48F3-8D66-172544C96704 options backgroundImageName dmg_background.jpg fontSize 12 iconSize 128 layoutItems identifier LayoutItem.7DCEB33C-3B26-463C-9D52-D2E99ADD0AD0 name Applications position {426, 190} type file identifier LayoutItem.042D24CE-36D9-4328-A97F-BCF3DC524509 name Seafile Client.app position {219, 190} type file identifier LayoutItem.CFA83A1B-E783-4354-88A9-255F0F623398 name .Trashes position {128, 426} type file identifier LayoutItem.830478CF-49D6-4772-AC6C-3A56A329536F name .fseventsd position {336, 426} type file identifier LayoutItem.E417B39C-5B93-4D7D-AE5A-FC3B0CDFD9D7 name .DropDMGBackground position {400, 426} type file identifier LayoutItem.209D5BB3-143C-4DB8-8FB9-F1175B8184F2 name .DS_Store position {64, 426} type file identifier LayoutItem.D20D1139-FE25-445E-BBE3-E5374F90A06E position {340, 388} rtf {\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf470 {\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural \f0\fs24 \cf0 Drag Seafile Client to the Applications folder to install} size {282, 30} type text windowOriginTopLeft {100, 100} documentCreator DropDMG 3.1.1 documentType com.c-command.DropDMG.Layout formatVersion 1 seafile-6.1.5/dmg/seafileLayout/Preview.icns000066400000000000000000000102611323477647300210270ustar00rootroot00000000000000icns±TOC (is32s8mkil32äl8mkis32ŽÃÓÔÑÍÌÊÊÉɶÒÿñÿýÐÀƒÿÄÄØËÑÎÄ¿ÑÏÎÍÍÓ°œid\ZURMKG@<=xQZcjaVHD><@@w‰Sm„“pYPINdfƒŒd~´­Žpc[iz‰‘™„žºÅµ‚‚—«¬˜£§¹ÌÍËɾ°¯¾ÆÅž«ÃÌÕÒÐÓÑÊÈÑÕݦ³ÜÛÞÛ€ÙÔ×Ýäó®»óìëéèçææéíóþ°¿‰ÿ²³¯®­¬¬ª©¨§§©ŽŽÃÔÔÒÒÐÐÍÌÊÊÉɶÔðËõã÷íƒÿuÄÅÓÂÎÈÍÈÐÏÏÍÍÓ°«‘„|{tkd^UU]†ž}„’š”‡pe\[bk‰™¶ÄÂ¥‡vnu‹•” —±ÌÚÖÀ¤“‰—©· ª³ÇÜâáÙÉ´²ÁÏУ°Ë×äææäÝÔÒÚÞÞ§´Üá€ç*èçâßãå쫺ëéëéèéèääèìù¯½ùòñðïïíìíðõÿ²À‰ÿ²³¯®­¬¬ª©¨§§©ŽŽÃÔÔÒÒÑÑÍÌÊÊÉɶÔïÍѱһƒÿfÄÅÓÞſÒÏÏÎÍÓ°½Ã±ª±¯¦—‰~tw‰˜¶¼½ÊÑͧ•‡‡‘¥ °¿ÔæííÜÀ«¡¨¾Í©¶Òãò÷öìÚÊÀÌÚ宽åì÷ùùöîâàèîó°¿ðñ÷€ú ÷òñóô÷°Àöõ€ø*ùøöôõõú°¿ûöø÷÷øöóòôöÿ²Àÿùøø÷øöôôöùÿ²À‰ÿ²³¯®­¬¬ª©¨§§©Žs8mk_ÂÄÄÄÄÄÄÄÄÄÄÂ_ÈÿÿÿÿÿÿÿÿÿÿÿÿÈÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÄÿÿÿÿÿÿÿÿÿÿÿÿÄÉÿÿÿÿÿÿÿÿÿÿÿÿÉŸÑÑÑÑÑÑÑÑÑÑÑÑŸ  il32俺º‚»º¹¹¸¸·¶µµ´³²±°¯®­¬«ª¥ºç•öâ§»ÿÿõïƒÿ‹l‹ÿ¦ »ððÔ®ððèÁððc^‹ð¤º—ࢹ¹¸··¶µ´´³²±°¯®­¬«ª©¨§¦¥¤£¢ ¸h]TWIFQKGHC@>==;<971-*(,-.Ÿ·^YVbcRWPLKFFHFA?A=;52;2023¶PSRVbZdanaYVRKGED@?;;B79<:›µMPS[cls}{npg\QLNHCAABHKLJS™³IQXd|~‰ŠŠƒwaYTOJHGHG`juYX—²KT\o†…–œ§¢–}nd[YPOMOVcbigl–±Pafy’¤«³¯‰~pbedVU]dhowv•”¯_cv£­¹¼¶§ ™|qme`bix‰Š”‹’­pz€’©®ºÃþ¿²¤”‰{sqx‰Ÿ£¥Ÿ‘¬…‰¤³»ÄÈÈÆÅ»¸¹Ÿ’ŠŽ˜¨²·¬««ª•– ®ºÍÊËÌÉÈÆÂ½¯¥£¡£¯º½¾¼·¶¨¢§³½ÅËÍЀÌÊÊÅ¿¸·³¶¿ÄÈÌÉÁÂŒ§®¶½ÆÍÑÔÑÎÏÐÑÐÑÊÆÇÃÁËÍÐÑÏÌÍ‹¥¼ÀÆÍÒ××ÓÔÐÑÒ×ÖÑÎÊÆÊÐÔÕÖØÜÚ‰£ÊËÏÓÚÛØÙÖÔÕÖ×ÖÕÔÐÏÒÕÙÝÝâèéˆ ¡ÕØÛÝàÞßÝÜÛÝ€Ú ØÕÕÙÚÛàäçéìð‡Ÿâäææ€åâáàá ßÝÞàâäæêîðóö†žíììíìíëêéêèçèèéêíïòôöùú…œ÷€öõõ€ôóóòòññòóôôõ÷øúûüý„šþ€ýü…ûüüýýþÿÿƒ˜—ÿƒ–•”“’‘ŽŒŒ‹Š‰ˆˆ‡†……„„‚ƒ¿¿ºº‚»º¹¹¸¸·¶µµ´³²±°¯®­¬«ª¥ºç•öâ§ »ÿÿºŸÿÿÙËÿÿêß‹ÿ¦ »ðð†mðð³•ððÆ£‹ð¤º—à¢¹¹¸··¶µ´´³²±°¯®­¬«ª©¨§¦¥¤£¢ ¸˜‰}}mlttsuoigb_ZYURJEDFMQTŸ·‹„€†„y~}yytrqmc^_YVOMWQSV\¶{~{~‹†“š’ˆ‡tkgd^\XZaY^df›µwxˆ’ž¥¬­¢¤›zsricbbdipsu™³s|†”«±²½¼½¸¬“ˆwokjll„˜ˆˆ—²w‚¡¶¸ÆËÑÏDz¢—‹‚yvuv€Œ˜—˜–±€˜­´ÄÑÔÙ×̽²¥•“‚€‰‘—¡¨¦¶”¯•¨±¿ÐÖÜÞÚÒÍÆ±¥Ÿ—’›¦°¸·¼´’­Ÿ©°¾ÑÖÜááÞߨÏÄ»¯¦¢©®·ÇÉÅÈÄ‘¬°´¹ËÖÛà€ãâÝÛÛËÁ¹»¼ÂÍÓÖÎÌ˪»¼ÆÑÙåãåæåäâàÝÕÎÌËËÒØÙÚØÓШÃÈÑÙßãåæåäáÞÙØÕÖÛÝßáÞ×׌ §ËÑ×Þâåççæ‚ç äááÝÜáâããáÞÝ‹¥Ô×ÜáäééæèæççêéæäáÝßã€åæç剣ÜÞáäéêèêçæçèéèçæááâåæééëïãåèêì€ëêéëêêéèäãåææéìîïñô‡Ÿëìîï€îìëë€ì ëéççèéêìïòôöø†žó‚òññ‚ðï€í îîðòôöøúû…œùù€ø÷÷ö÷ööõõ€ô õõööøùúüýý„šþƒý€üûüý€þÿƒ˜—ÿƒ–•”“’‘ŽŒŒ‹Š‰ˆˆ‡†……„„‚ƒ¿¿ºº‚»º¹¹¸¸·¶µµ´³²±°¯®­¬«ª¥ºç•öâ§ »ÿÿ¸œÿÿtMÿÿ`‹ÿ¦ »ðð‚kððGGðð[Z‹ð¤º—ࢹ¹¸··¶µ´´³²±°¯®­¬«ª©¨§¦¥¤£¢ ¸Óµ²¢¢¦¬¯¯«£œ–‘‡‚|ynginyˆŸ·Å½º·³°´¹µ¶°¬ª¢•Š‚|ts}z‰“¶·¹¶¶ÀÀÌÊÎÊ»«—’‰„„‹ˆ‘›¡›µ³³¹ÂÊÖÛÝàÙÛÔȲ©¤™‘Ž“˜¢§­¼™³¯·ÁÌÜâäêéêèàÍ·¬¢œŸŸ´¼ÆÂײ´½È×åçïòôôðäÙÐĸ¯«ª«¶ÀÅÎÏË–±½ÇÑáåîôõ÷÷òëäÛÏÉĺ¸¿ÇÍÕÚØÚ”¯ÊÏÝâêôöøø÷õòíãÛ×ÎÉÉÐ×ÝäâäÞ’­ÔÛàèòõ÷øöòìèàÚÖÛÞãëëêê瑬Þáäíóöøù÷öõðêåææéîðñîìêªãåêïóøø€úùøù÷ôðïîîðòóòñíë¨æéïñõ÷øƒú ø÷õôòòóôõõóïîŒ §éìðóö÷øøùù€úùø÷öôó€õôòðï‹ ¥íïòôöøø÷øøù ø÷öóôôõôõôóñ‰£ðñóô÷ù÷ø€÷øù÷÷öóóòôôõõö÷öˆ¡óóõöƒ÷€ø ÷öóòòóóôõ÷øøù‡Ÿöö‚ø÷öö€÷öõòôôöøùúü†žùøùøø÷ø÷ôõ€ôõ÷ùúüýþ… œýüüûüûûúû€úù€øùûüý€þ„šÿˆþýý‚üýýþÿƒ˜—ÿƒ–•”“’‘ŽŒŒ‹Š‰ˆˆ‡†……„„‚ƒ¿l8mk?ÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ?çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ#)033333333333333333333330)#  seafile-6.1.5/doc/000077500000000000000000000000001323477647300137205ustar00rootroot00000000000000seafile-6.1.5/doc/Makefile.am000066400000000000000000000001531323477647300157530ustar00rootroot00000000000000CLIENT_MANUALS = seaf-daemon.1 seaf-cli.1 dist_man1_MANS = $(CLIENT_MANUALS) EXTRA_DIST = cli-readme.txt seafile-6.1.5/doc/cli-readme.txt000066400000000000000000000031051323477647300164620ustar00rootroot00000000000000 Seafile command line client =========================== For the full manual about seafile CLI client, see [https://github.com/haiwen/seafile/wiki/Seafile-CLI-client] Table of Contents ================= 1 Requirement: 2 Get Started 2.1 Initialize 2.2 Start seafile client 2.3 Download a library from a server 2.4 stop seafile client 3 Uninstall 1 Requirement: --------------- - python 2.6/2.7 - If you use python 2.6, you need to install python "argparse" module see [https://pypi.python.org/pypi/argparse] 2 Get Started -------------- 2.1 Initialize =============== mkdir ~/seafile-client ./seaf-cli init -d ~/seafile-client 2.2 Start seafile client ========================= ./seaf-cli start 2.3 Download a library from a server ===================================== First retrieve the library id by browsing on the server -> it's in the url after "/repo/" Then: seaf-cli download -l "the id of the library" -s "the url + port of server" -d "the folder where the library folder will be downloaded" -u "username on server" [-p "password"] seaf-cli status # check status of ongoing downloads # Name Status Progress # Apps downloading 9984/10367, 9216.1KB/s 2.4 stop seafile client ======================== ./seaf-cli stop 3 Uninstall ------------ First stop the client: seaf-cli stop Then remove the data: rm -rf ~/.seafile-client rm -rf ~/.ccnet # note this should not be erased if you run the server on the same host rm -rf seafile-cli-1.5.3 seafile-6.1.5/doc/seaf-cli.1000066400000000000000000000010131323477647300154600ustar00rootroot00000000000000.\" Manpage for seafile-client .\" Contact freeplant@gmail.com to correct errors or typos. .TH seafile 1 "31 Jan 2013" "Linux" "seafile client man page" .SH NAME seaf-cli \- the command line interface for seafile client .SH SYNOPSIS seaf-cli [OPTIONS] .SH DESCRIPTION .BR seaf-cli is the command line interface for seafile client. .SH SEE ALSO ccnet(1), seafile-applet(1), seaf-daemon(1), seafile-web(1) .SH AUTHOR Lingtao Pan (freeplant@gmail.com) .SH WEBSTIE http://www.seafile.com .LP https://github.com/haiwen/seafile/ seafile-6.1.5/doc/seaf-daemon.1000066400000000000000000000010221323477647300161540ustar00rootroot00000000000000.\" Manpage for seafile-client .\" Contact freeplant@gmail.com to correct errors or typos. .TH seafile 1 "31 Jan 2013" "Linux" "seafile client man page" .SH NAME seaf-daemon \- the daemon of seafile client .SH SYNOPSIS seaf-daemon [OPTIONS] .SH DESCRIPTION .BR seafile-daemon is the daemon of seafile client. It's started by seafile-applet(1). .SH SEE ALSO ccnet(1), seaf-web(1), seafile-applet(1), seaf-cli(1) .SH AUTHOR Lingtao Pan (freeplant@gmail.com) .SH WEBSTIE http://www.seafile.com .LP https://github.com/haiwen/seafile/ seafile-6.1.5/include/000077500000000000000000000000001323477647300145765ustar00rootroot00000000000000seafile-6.1.5/include/Makefile.am000066400000000000000000000001611323477647300166300ustar00rootroot00000000000000 seafiledir = $(includedir)/seafile noinst_HEADERS = seafile-error.h seafile_HEADERS = seafile-rpc.h seafile.h seafile-6.1.5/include/seafile-error.h000066400000000000000000000013321323477647300175050ustar00rootroot00000000000000#ifndef SEAFILE_ERROR_H #define SEAFILE_ERROR_H #define SEAF_ERR_GENERAL 500 #define SEAF_ERR_BAD_REPO 501 #define SEAF_ERR_BAD_COMMIT 502 #define SEAF_ERR_BAD_ARGS 503 #define SEAF_ERR_INTERNAL 504 #define SEAF_ERR_BAD_FILE 505 #define SEAF_ERR_BAD_RELAY 506 #define SEAF_ERR_LIST_COMMITS 507 #define SEAF_ERR_REPO_AUTH 508 #define SEAF_ERR_GC_NOT_STARTED 509 #define SEAF_ERR_MONITOR_NOT_CONNECTED 510 #define SEAF_ERR_BAD_DIR_ID 511 #define SEAF_ERR_NO_WORKTREE 512 #define SEAF_ERR_BAD_PEER_ID 513 #define SEAF_ERR_REPO_LOCKED 514 #define SEAF_ERR_DIR_MISSING 515 #define SEAF_ERR_PATH_NO_EXIST 516 /* the dir or file pointed by this path not exists */ #endif seafile-6.1.5/include/seafile-rpc.h000066400000000000000000000732051323477647300171500ustar00rootroot00000000000000 #ifndef _SEAFILE_RPC_H #define _SEAFILE_RPC_H #include "seafile-object.h" /** * seafile_get_session_info: * * Returns: a SeafileSessionInfo object. */ GObject * seafile_get_session_info (GError **error); /** * seafile_get_repo_list: * * Returns repository list. */ GList* seafile_get_repo_list (int start, int limit, GError **error); gint64 seafile_count_repos (GError **error); /** * seafile_get_trash_repo_list: * * Returns deleted repository list. */ GList* seafile_get_trash_repo_list(int start, int limit, GError **error); int seafile_del_repo_from_trash (const char *repo_id, GError **error); int seafile_restore_repo_from_trash (const char *repo_id, GError **error); GList * seafile_get_trash_repos_by_owner (const char *owner, GError **error); int seafile_empty_repo_trash (GError **error); int seafile_empty_repo_trash_by_owner (const char *owner, GError **error); /** * seafile_get_commit_list: * * @limit: if limit <= 0, all commits start from @offset will be returned. * * Returns: commit list of a given repo. * * Possible Error: * 1. Bad Argument * 2. No head and branch master * 3. Failed to list commits */ GList* seafile_get_commit_list (const gchar *repo, int offset, int limit, GError **error); /** * seafile_get_commit: * @id: the commit id. * * Returns: the commit object. */ GObject* seafile_get_commit (const char *repo_id, int version, const gchar *id, GError **error); /** * seafile_get_repo: * * Returns: repo */ GObject* seafile_get_repo (const gchar* id, GError **error); GObject * seafile_get_repo_sync_task (const char *repo_id, GError **error); /** * seafile_get_repo_sync_info: */ GObject * seafile_get_repo_sync_info (const char *repo_id, GError **error); GList* seafile_get_repo_sinfo (const char *repo_id, GError **error); /* [seafile_get_config] returns the value of the config entry whose name is * [key] in config.db */ char *seafile_get_config (const char *key, GError **error); /* [seafile_set_config] set the value of config key in config.db; old value * would be overwritten. */ int seafile_set_config (const char *key, const char *value, GError **error); int seafile_set_config_int (const char *key, int value, GError **error); int seafile_get_config_int (const char *key, GError **error); int seafile_set_upload_rate_limit (int limit, GError **error); int seafile_set_download_rate_limit (int limit, GError **error); /** * seafile_destroy_repo: * @repo_id: repository id. */ int seafile_destroy_repo (const gchar *repo_id, GError **error); int seafile_unsync_repos_by_account (const char *server_addr, const char *email, GError **error); int seafile_remove_repo_tokens_by_account (const char *server_addr, const char *email, GError **error); int seafile_set_repo_token (const char *repo_id, const char *token, GError **error); int seafile_get_download_rate(GError **error); int seafile_get_upload_rate(GError **error); /** * seafile_edit_repo: * @repo_id: repository id. * @name: new name of the repository, NULL if unchanged. * @description: new description of the repository, NULL if unchanged. */ int seafile_edit_repo (const gchar *repo_id, const gchar *name, const gchar *description, const gchar *user, GError **error); int seafile_change_repo_passwd (const char *repo_id, const char *old_passwd, const char *new_passwd, const char *user, GError **error); /** * seafile_repo_size: * * Returns: the size of a repo * * Possible Error: * 1. Bad Argument * 2. No local branch (No local branch record in branch.db) * 3. Database error * 4. Calculate branch size error */ gint64 seafile_repo_size(const gchar *repo_id, GError **error); int seafile_repo_last_modify(const char *repo_id, GError **error); int seafile_set_repo_lantoken (const gchar *repo_id, const gchar *token, GError **error); gchar* seafile_get_repo_lantoken (const gchar *repo_id, GError **error); int seafile_set_repo_property (const char *repo_id, const char *key, const char *value, GError **error); gchar * seafile_get_repo_property (const char *repo_id, const char *key, GError **error); char * seafile_get_repo_relay_address (const char *repo_id, GError **error); char * seafile_get_repo_relay_port (const char *repo_id, GError **error); int seafile_update_repo_relay_info (const char *repo_id, const char *new_addr, const char *new_port, GError **error); int seafile_update_repos_server_host (const char *old_host, const char *new_host, const char *new_server_url, GError **error); int seafile_disable_auto_sync (GError **error); int seafile_enable_auto_sync (GError **error); int seafile_is_auto_sync_enabled (GError **error); char * seafile_get_path_sync_status (const char *repo_id, const char *path, int is_dir, GError **error); int seafile_mark_file_locked (const char *repo_id, const char *path, GError **error); int seafile_mark_file_unlocked (const char *repo_id, const char *path, GError **error); char * seafile_get_server_property (const char *server_url, const char *key, GError **error); int seafile_set_server_property (const char *server_url, const char *key, const char *value, GError **error); GList * seafile_get_file_sync_errors (int offset, int limit, GError **error); /** * seafile_list_dir: * List a directory. * * Returns: a list of dirents. * * @limit: if limit <= 0, all dirents start from @offset will be returned. */ GList * seafile_list_dir (const char *repo_id, const char *dir_id, int offset, int limit, GError **error); /** * seafile_list_file_blocks: * List the blocks of a file. * * Returns: a list of block ids speprated by '\n'. * * @limit: if limit <= 0, all blocks start from @offset will be returned. */ char * seafile_list_file_blocks (const char *repo_id, const char *file_id, int offset, int limit, GError **error); /** * seafile_list_dir_by_path: * List a directory in a commit by the path of the directory. * * Returns: a list of dirents. */ GList * seafile_list_dir_by_path (const char *repo_id, const char *commit_id, const char *path, GError **error); /** * seafile_get_dir_id_by_commit_and_path: * Get the dir_id of the path * * Returns: the dir_id of the path */ char * seafile_get_dir_id_by_commit_and_path (const char *repo_id, const char *commit_id, const char *path, GError **error); /** * seafile_revert: * Reset the repo to a previous state by creating a new commit. */ int seafile_revert (const char *repo_id, const char *commit, GError **error); char * seafile_gen_default_worktree (const char *worktree_parent, const char *repo_name, GError **error); int seafile_check_path_for_clone(const char *path, GError **error); /** * seafile_clone: * * Fetch a new repo and then check it out. */ char * seafile_clone (const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *worktree, const char *token, const char *passwd, const char *magic, const char *peer_addr, const char *peer_port, const char *email, const char *random_key, int enc_version, const char *more_info, GError **error); char * seafile_download (const char *repo_id, int repo_version, const char *peer_id, const char *repo_name, const char *wt_parent, const char *token, const char *passwd, const char *magic, const char *peer_addr, const char *peer_port, const char *email, const char *random_key, int enc_version, const char *more_info, GError **error); int seafile_cancel_clone_task (const char *repo_id, GError **error); int seafile_remove_clone_task (const char *repo_id, GError **error); /** * seafile_get_clone_tasks: * * Get a list of clone tasks. */ GList * seafile_get_clone_tasks (GError **error); /** * seafile_sync: * * Sync a repo with relay. */ int seafile_sync (const char *repo_id, const char *peer_id, GError **error); /** * seafile_get_total_block_size: * * Get the sum of size of all the blocks. */ gint64 seafile_get_total_block_size (GError **error); /** * seafile_get_commit_tree_block_number: * * Get the number of blocks belong to the commit tree. * * @commit_id: the head of the commit tree. * * Returns: -1 if the calculation is in progress, -2 if error, >=0 otherwise. */ int seafile_get_commit_tree_block_number (const char *commit_id, GError **error); /** * seafile_gc: * Start garbage collection. */ int seafile_gc (GError **error); /** * seafile_gc_get_progress: * Get progress of GC. * * Returns: * progress of GC in precentage. * -1 if GC is not running. */ /* int */ /* seafile_gc_get_progress (GError **error); */ /* ----------------- Task Related -------------- */ /** * seafile_find_transfer: * * Find a non finished task of a repo */ GObject * seafile_find_transfer_task (const char *repo_id, GError *error); int seafile_cancel_task (const gchar *task_id, int task_type, GError **error); /** * Remove finished upload task */ int seafile_remove_task (const char *task_id, int task_type, GError **error); /* ------------------ Relay specific RPC calls. ------------ */ /** * seafile_diff: * * Show the difference between @old commit and @new commit. If @old is NULL, then * show the difference between @new commit and its parent. * * @old and @new can also be branch name. */ GList * seafile_diff (const char *repo_id, const char *old, const char *new, int fold_dir_diff, GError **error); GList * seafile_branch_gets (const char *repo_id, GError **error); /** * Return 1 if user is the owner of repo, otherwise return 0. */ int seafile_is_repo_owner (const char *email, const char *repo_id, GError **error); int seafile_set_repo_owner(const char *repo_id, const char *email, GError **error); /** * Return owner id of repo */ char * seafile_get_repo_owner(const char *repo_id, GError **error); GList * seafile_get_orphan_repo_list(GError **error); GList * seafile_list_owned_repos (const char *email, int ret_corrupted, GError **error); /** * seafile_add_chunk_server: * @server: ID for the chunk server. * * Add a chunk server on a relay server. */ int seafile_add_chunk_server (const char *server, GError **error); /** * seafile_del_chunk_server: * @server: ID for the chunk server. * * Delete a chunk server on a relay server. */ int seafile_del_chunk_server (const char *server, GError **error); /** * seafile_list_chunk_servers: * * List chunk servers set on a relay server. */ char *seafile_list_chunk_servers (GError **error); gint64 seafile_get_user_quota_usage (const char *email, GError **error); gint64 seafile_get_user_share_usage (const char *email, GError **error); gint64 seafile_server_repo_size(const char *repo_id, GError **error); int seafile_repo_set_access_property (const char *repo_id, const char *ap, GError **error); char * seafile_repo_query_access_property (const char *repo_id, GError **error); char * seafile_web_get_access_token (const char *repo_id, const char *obj_id, const char *op, const char *username, int use_onetime, GError **error); GObject * seafile_web_query_access_token (const char *token, GError **error); char * seafile_query_zip_progress (const char *token, GError **error); GObject * seafile_get_checkout_task (const char *repo_id, GError **error); GList * seafile_get_sync_task_list (GError **error); int seafile_share_subdir_to_user (const char *repo_id, const char *path, const char *owner, const char *share_user, const char *permission, const char *passwd, GError **error); int seafile_unshare_subdir_for_user (const char *repo_id, const char *path, const char *owner, const char *share_user, GError **error); int seafile_update_share_subdir_perm_for_user (const char *repo_id, const char *path, const char *owner, const char *share_user, const char *permission, GError **error); int seafile_add_share (const char *repo_id, const char *from_email, const char *to_email, const char *permission, GError **error); GList * seafile_list_share_repos (const char *email, const char *type, int start, int limit, GError **error); GList * seafile_list_repo_shared_to (const char *from_user, const char *repo_id, GError **error); GList * seafile_list_repo_shared_group (const char *from_user, const char *repo_id, GError **error); int seafile_remove_share (const char *repo_id, const char *from_email, const char *to_email, GError **error); int seafile_share_subdir_to_group (const char *repo_id, const char *path, const char *owner, int share_group, const char *permission, const char *passwd, GError **error); int seafile_unshare_subdir_for_group (const char *repo_id, const char *path, const char *owner, int share_group, GError **error); int seafile_update_share_subdir_perm_for_group (const char *repo_id, const char *path, const char *owner, int share_group, const char *permission, GError **error); int seafile_group_share_repo (const char *repo_id, int group_id, const char *user_name, const char *permission, GError **error); int seafile_group_unshare_repo (const char *repo_id, int group_id, const char *user_name, GError **error); /* Get groups that a repo is shared to */ char * seafile_get_shared_groups_by_repo(const char *repo_id, GError **error); char * seafile_get_group_repoids (int group_id, GError **error); GList * seafile_get_repos_by_group (int group_id, GError **error); GList * seafile_get_group_repos_by_owner (char *user, GError **error); char * seafile_get_group_repo_owner (const char *repo_id, GError **error); int seafile_remove_repo_group(int group_id, const char *username, GError **error); gint64 seafile_get_file_size (const char *store_id, int version, const char *file_id, GError **error); gint64 seafile_get_dir_size (const char *store_id, int version, const char *dir_id, GError **error); int seafile_set_repo_history_limit (const char *repo_id, int days, GError **error); int seafile_get_repo_history_limit (const char *repo_id, GError **error); int seafile_check_passwd (const char *repo_id, const char *magic, GError **error); int seafile_set_passwd (const char *repo_id, const char *user, const char *passwd, GError **error); int seafile_unset_passwd (const char *repo_id, const char *user, GError **error); int seafile_is_passwd_set (const char *repo_id, const char *user, GError **error); GObject * seafile_get_decrypt_key (const char *repo_id, const char *user, GError **error); int seafile_revert_on_server (const char *repo_id, const char *commit_id, const char *user_name, GError **error); /** * Add a file into the repo on server. * The content of the file is stored in a temporary file. * @repo_id: repo id * @temp_file_path: local file path, should be a temp file just uploaded. * @parent_dir: the parent directory to put the file in. * @file_name: the name of the target file. * @user: the email of the user who uploaded the file. */ int seafile_post_file (const char *repo_id, const char *temp_file_path, const char *parent_dir, const char *file_name, const char *user, GError **error); /** * Add multiple files at once. * * @filenames_json: json array of filenames * @paths_json: json array of temp file paths */ char * seafile_post_multi_files (const char *repo_id, const char *parent_dir, const char *filenames_json, const char *paths_json, const char *user, int replace, GError **error); /** * Add file blocks at once. * * @blocks_json: json array of block ids * @paths_json: json array of temp file paths */ char * seafile_post_file_blocks (const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, gint64 file_size, int replace_existed, GError **error); int seafile_post_empty_file (const char *repo_id, const char *parent_dir, const char *new_file_name, const char *user, GError **error); /** * Update an existing file in a repo * @params: same as seafile_post_file * @head_id: the commit id for the original file version. * It's optional. If it's NULL, the current repo head will be used. * @return The new file id */ char * seafile_put_file (const char *repo_id, const char *temp_file_path, const char *parent_dir, const char *file_name, const char *user, const char *head_id, GError **error); /** * Add file blocks at once. * * @blocks_json: json array of block ids * @paths_json: json array of temp file paths */ char * seafile_put_file_blocks (const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, const char *head_id, gint64 file_size, GError **error); int seafile_post_dir (const char *repo_id, const char *parent_dir, const char *new_dir_name, const char *user, GError **error); /** * delete a file/directory from the repo on server. * @repo_id: repo id * @parent_dir: the parent directory of the file to be deleted * @file_name: the name of the target file. * @user: the email of the user who uploaded the file. */ int seafile_del_file (const char *repo_id, const char *parent_dir, const char *file_name, const char *user, GError **error); /** * copy a file/directory from a repo to another on server. */ GObject * seafile_copy_file (const char *src_repo_id, const char *src_dir, const char *src_filename, const char *dst_repo_id, const char *dst_dir, const char *dst_filename, const char *user, int need_progress, int synchronous, GError **error); GObject * seafile_move_file (const char *src_repo_id, const char *src_dir, const char *src_filename, const char *dst_repo_id, const char *dst_dir, const char *dst_filename, int replace, const char *user, int need_progress, int synchronous, GError **error); GObject * seafile_get_copy_task (const char *task_id, GError **error); int seafile_cancel_copy_task (const char *task_id, GError **error); int seafile_rename_file (const char *repo_id, const char *parent_dir, const char *oldname, const char *newname, const char *user, GError **error); /** * Return non-zero if filename is valid. */ int seafile_is_valid_filename (const char *repo_id, const char *filename, GError **error); int seafile_set_user_quota (const char *user, gint64 quota, GError **error); gint64 seafile_get_user_quota (const char *user, GError **error); int seafile_check_quota (const char *repo_id, GError **error); char * seafile_get_file_id_by_path (const char *repo_id, const char *path, GError **error); char * seafile_get_dir_id_by_path (const char *repo_id, const char *path, GError **error); GObject * seafile_get_dirent_by_path (const char *repo_id, const char *path, GError **error); /** * Return a list of commits where every commit contains a unique version of * the file. */ GList * seafile_list_file_revisions (const char *repo_id, const char *path, int max_revision, int limit, int show_days, GError **error); GList * seafile_calc_files_last_modified (const char *repo_id, const char *parent_dir, int limit, GError **error); int seafile_revert_file (const char *repo_id, const char *commit_id, const char *path, const char *user, GError **error); int seafile_revert_dir (const char *repo_id, const char *commit_id, const char *path, const char *user, GError **error); char * seafile_check_repo_blocks_missing (const char *repo_id, const char *blockids_json, GError **error); /* * @show_days: return deleted files in how many days, return all if 0. */ GList * seafile_get_deleted (const char *repo_id, int show_days, const char *path, const char *scan_stat, int limit, GError **error); /** * Generate a new token for (repo_id, email) and return it */ char * seafile_generate_repo_token (const char *repo_id, const char *email, GError **error); int seafile_delete_repo_token (const char *repo_id, const char *token, const char *user, GError **error); GList * seafile_list_repo_tokens (const char *repo_id, GError **error); GList * seafile_list_repo_tokens_by_email (const char *email, GError **error); int seafile_delete_repo_tokens_by_peer_id(const char *email, const char *peer_id, GError **error); int seafile_delete_repo_tokens_by_email (const char *email, GError **error); /** * create a repo on seahub */ char * seafile_create_repo (const char *repo_name, const char *repo_desc, const char *owner_email, const char *passwd, GError **error); char * seafile_create_enc_repo (const char *repo_id, const char *repo_name, const char *repo_desc, const char *owner_email, const char *magic, const char *random_key, int enc_version, GError **error); char * seafile_check_permission (const char *repo_id, const char *user, GError **error); char * seafile_check_permission_by_path (const char *repo_id, const char *path, const char *user, GError **error); GList * seafile_list_dir_with_perm (const char *repo_id, const char *path, const char *dir_id, const char *user, int offset, int limit, GError **error); int seafile_set_inner_pub_repo (const char *repo_id, const char *permission, GError **error); int seafile_unset_inner_pub_repo (const char *repo_id, GError **error); GList * seafile_list_inner_pub_repos (GError **error); gint64 seafile_count_inner_pub_repos (GError **error); GList * seafile_list_inner_pub_repos_by_owner (const char *user, GError **error); int seafile_is_inner_pub_repo (const char *repo_id, GError **error); int seafile_set_share_permission (const char *repo_id, const char *from_email, const char *to_email, const char *permission, GError **error); int seafile_set_group_repo_permission (int group_id, const char *repo_id, const char *permission, GError **error); char * seafile_get_file_id_by_commit_and_path(const char *repo_id, const char *commit_id, const char *path, GError **error); /* virtual repo related */ char * seafile_create_virtual_repo (const char *origin_repo_id, const char *path, const char *repo_name, const char *repo_desc, const char *owner, const char *passwd, GError **error); GList * seafile_get_virtual_repos_by_owner (const char *owner, GError **error); GObject * seafile_get_virtual_repo (const char *origin_repo, const char *path, const char *owner, GError **error); char * seafile_get_system_default_repo_id (GError **error); /* Clean trash */ int seafile_clean_up_repo_history (const char *repo_id, int keep_days, GError **error); /* ------------------ public RPC calls. ------------ */ GList* seafile_get_repo_list_pub (int start, int limit, GError **error); GObject* seafile_get_repo_pub (const gchar* id, GError **error); GList* seafile_get_commit_list_pub (const gchar *repo, int offset, int limit, GError **error); GObject* seafile_get_commit_pub (const gchar *id, GError **error); char *seafile_diff_pub (const char *repo_id, const char *old, const char *new, GError **error); GList * seafile_list_dir_pub (const char *dir_id, GError **error); GList * seafile_get_shared_users_for_subdir (const char *repo_id, const char *path, const char *from_user, GError **error); GList * seafile_get_shared_groups_for_subdir (const char *repo_id, const char *path, const char *from_user, GError **error); GObject * seafile_generate_magic_and_random_key(int enc_version, const char* repo_id, const char *passwd, GError **error); #endif seafile-6.1.5/include/seafile.h000066400000000000000000000144221323477647300163620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef SEAFILE_H #define SEAFILE_H char * seafile_create_repo (SearpcClient *client, const gchar *name, const gchar *description, const gchar *worktree, const gchar *passwd, const gchar *relay_id, int keep_local_history, GError **error); int seafile_create_repo_async (SearpcClient *client, const gchar *name, const gchar *description, const gchar *worktree, const gchar *passwd, const gchar *relay_id, int keep_local_history, AsyncCallback callback, void *user_data); int seafile_destroy_repo (SearpcClient *client, const char *repo_id, GError **error); int seafile_set_repo_token (SearpcClient *client, const char *repo_id, const char *token, GError **error); char * seafile_get_repo_token (SearpcClient *client, const char *repo_id, GError **error); int seafile_set_repo_property (SearpcClient *client, const char *repo_id, const char *key, const char *value, GError **error); GList * seafile_get_repo_list (SearpcClient *client, int offset, int limit, GError **error); GObject * seafile_get_repo (SearpcClient *client, const char *repo_id, GError **error); char *seafile_get_config (SearpcClient *client, const char *key, GError **error); int seafile_get_config_async (SearpcClient *client, const char *key, AsyncCallback callback, void *user_data); int seafile_set_config_async (SearpcClient *client, const char *key, const char *value, AsyncCallback callback, void *user_data); int seafile_calc_dir_size (SearpcClient *client, const char *path, GError **error); /* server */ int seafile_add_chunk_server (SearpcClient *client, const char *server_id, GError **error); int seafile_del_chunk_server (SearpcClient *client, const char *server_id, GError **error); char *seafile_list_chunk_servers (SearpcClient *client, GError **error); char * seafile_repo_query_access_property (SearpcClient *client, const char *repo_id, GError **error); GObject * seafile_web_query_access_token (SearpcClient *client, const char *token, GError **error); GObject * seafile_get_decrypt_key (SearpcClient *client, const char *repo_id, const char *user, GError **error); char * seafile_put_file (SearpcClient *client, const char *repo_id, const char *file_path, const char *parent_dir, const char *file_name, const char *user, const char *head_id, GError **error); char * seafile_put_file_blocks (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, const char *head_id, gint64 file_size, GError **error); int seafile_post_file (SearpcClient *client, const char *repo_id, const char *file_path, const char *parent_dir, const char *file_name, const char *user, GError **error); #define POST_FILE_ERR_FILENAME 401 #define POST_FILE_ERR_BLOCK_MISSING 402 char * seafile_post_file_blocks (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, gint64 file_size, int replace_existed, GError **error); char * seafile_post_multi_files (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *filenames_json, const char *paths_json, const char *user, int replace_existed, GError **error); int seafile_set_user_quota (SearpcClient *client, const char *user, gint64 quota, GError **error); int seafile_set_org_quota (SearpcClient *client, int org_id, gint64 quota, GError **error); int seafile_set_org_user_quota (SearpcClient *client, int org_id, const char *user, gint64 quota, GError **error); int seafile_check_quota (SearpcClient *client, const char *repo_id, GError **error); int seafile_disable_auto_sync_async (SearpcClient *client, AsyncCallback callback, void *user_data); int seafile_enable_auto_sync_async (SearpcClient *client, AsyncCallback callback, void *user_data); int seafile_is_auto_sync_enabled_async (SearpcClient *client, AsyncCallback callback, void *user_data); #endif seafile-6.1.5/integration-tests/000077500000000000000000000000001323477647300166365ustar00rootroot00000000000000seafile-6.1.5/integration-tests/README.md000066400000000000000000000002001323477647300201050ustar00rootroot00000000000000### Seafile Integration Tests The purpose of integration tests is to build a seafile release package and run tests against it. seafile-6.1.5/integration-tests/autosetup.py000077500000000000000000000170741323477647300212550ustar00rootroot00000000000000#!/usr/bin/env python #coding: UTF-8 import os from os.path import abspath, basename, exists, dirname, join import sys import argparse import re from collections import namedtuple import requests from pexpect import spawn from utils import green, red, debug, info, warning, cd, shell, chdir, setup_logging USERNAME = 'test@seafiletest.com' PASSWORD = 'testtest' ADMIN_USERNAME = 'admin@seafiletest.com' ADMIN_PASSWORD = 'adminadmin' MYSQL_ROOT_PASSWD = 's123' ServerConfig = namedtuple('ServerConfig', [ 'installdir', 'tarball', 'version', 'initmode', ]) def setup_server(cfg, db): '''Setup seafile server with the setup-seafile.sh script. We use pexpect to interactive with the setup process of the script. ''' info('uncompressing server tarball') shell('tar xf seafile-server_{}_x86-64.tar.gz -C {}' .format(cfg.version, cfg.installdir)) if db == 'mysql': autosetup_mysql(cfg) else: autosetup_sqlite3(cfg) with open(join(cfg.installdir, 'conf/seahub_settings.py'), 'a') as fp: fp.write('\n') fp.write('DEBUG = True') fp.write('\n') fp.write('''\ REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'ping': '600/minute', 'anon': '1000/minute', 'user': '1000/minute', }, }''') fp.write('\n') def autosetup_sqlite3(cfg): setup_script = get_script(cfg, 'setup-seafile.sh') shell('''sed -i -e '/^check_root;.*/d' "{}"'''.format(setup_script)) if cfg.initmode == 'prompt': setup_sqlite3_prompt(setup_script) else: setup_sqlite3_auto(setup_script) def setup_sqlite3_prompt(setup_script): info('setting up seafile server with pexepct, script %s', setup_script) answers = [ ('ENTER', ''), # server name ('server name', 'my-seafile'), # ip or domain ('ip or domain', '127.0.0.1'), # seafile data dir ('seafile-data', ''), # fileserver port ('seafile fileserver', ''), ('ENTER', ''), ('ENTER', ''), ] _answer_questions(setup_script, answers) def setup_sqlite3_auto(setup_script): info('setting up seafile server in auto mode, script %s', setup_script) env = os.environ.copy() env['SERVER_IP'] = '127.0.0.1' shell('%s auto -n my-seafile' % setup_script, env=env) def createdbs(): sql = '''\ create database `ccnet-existing` character set = 'utf8'; create database `seafile-existing` character set = 'utf8'; create database `seahub-existing` character set = 'utf8'; create user 'seafile'@'localhost' identified by 'seafile'; GRANT ALL PRIVILEGES ON `ccnet-existing`.* to `seafile`@localhost; GRANT ALL PRIVILEGES ON `seafile-existing`.* to `seafile`@localhost; GRANT ALL PRIVILEGES ON `seahub-existing`.* to `seafile`@localhost; ''' shell('mysql -u root -p%s' % MYSQL_ROOT_PASSWD, inputdata=sql) def autosetup_mysql(cfg): setup_script = get_script(cfg, 'setup-seafile-mysql.sh') if not exists(setup_script): print 'please specify seafile script path' if cfg.initmode == 'prompt': createdbs() setup_mysql_prompt(setup_script) else : # in auto mode, test create new db setup_mysql_auto(setup_script) def setup_mysql_prompt(setup_script): info('setting up seafile server with pexepct, script %s', setup_script) answers = [ ('ENTER', ''), # server name ('server name', 'my-seafile'), # ip or domain ('ip or domain', '127.0.0.1'), # seafile data dir ('seafile-data', ''), # fileserver port ('seafile fileserver', ''), # use existing ('choose a way to initialize seafile databases', '2'), ('host of mysql server', ''), ('port of mysql server', ''), ('Which mysql user', 'seafile'), ('password for mysql user', 'seafile'), ('ccnet database', 'ccnet-existing'), ('seafile database', 'seafile-existing'), ('seahub database', 'seahub-existing'), ('ENTER', ''), ] _answer_questions(abspath(setup_script), answers) def setup_mysql_auto(setup_script): info('setting up seafile server in auto mode, script %s', setup_script) env = os.environ.copy() env['MYSQL_USER'] = 'seafile-new' env['MYSQL_USER_PASSWD'] = 'seafile' env['MYSQL_ROOT_PASSWD']= MYSQL_ROOT_PASSWD env['CCNET_DB'] = 'ccnet-new' env['SEAFILE_DB'] = 'seafile-new' env['SEAHUB_DB'] = 'seahub-new' shell('%s auto -n my-seafile -e 0' % setup_script, env=env) def start_server(cfg): with cd(cfg.installdir): shell('find . -maxdepth 2 | sort | xargs ls -lhd') seafile_sh = get_script(cfg, 'seafile.sh') shell('{} start'.format(seafile_sh)) info('starting seahub') seahub_sh = get_script(cfg, 'seahub.sh') answers = [ # admin email/pass ('admin email', ADMIN_USERNAME), ('admin password', ADMIN_PASSWORD), ('admin password again', ADMIN_PASSWORD), ] _answer_questions('{} start'.format(abspath(seahub_sh)), answers) with cd(cfg.installdir): shell('find . -maxdepth 2 | sort | xargs ls -lhd') # shell('sqlite3 ccnet/PeerMgr/usermgr.db "select * from EmailUser"', cwd=INSTALLDIR) shell('http -v localhost:8000/api2/server-info/ || true') # shell('http -v -f POST localhost:8000/api2/auth-token/ username=admin@seafiletest.com password=adminadmin || true') shell('netstat -nltp') def _answer_questions(cmd, answers): info('expect: spawing %s', cmd) child = spawn(cmd) child.logfile = sys.stdout def autofill(pattern, line): child.expect(pattern) child.sendline(line) for k, v in answers: autofill(k, v) child.sendline('') child.logfile = None child.interact() def get_script(cfg, path): """ :type cfg: ServerConfig """ return join(server_dir(cfg), path) def server_dir(cfg): """ :type cfg: ServerConfig """ return join(cfg.installdir, 'seafile-server-{}'.format(cfg.version)) def apiurl(path): path = path.lstrip('/') root = os.environ.get('SEAFILE_SERVER', 'http://127.0.0.1:8000') return '{}/api2/{}'.format(root, path) def create_test_user(cfg): data = {'username': ADMIN_USERNAME, 'password': ADMIN_PASSWORD, } res = requests.post(apiurl('/auth-token/'), data=data) debug('%s %s', res.status_code, res.text) token = res.json()['token'] data = {'password': PASSWORD, } headers = {'Authorization': 'Token ' + token} res = requests.put( apiurl('/accounts/{}/'.format(USERNAME)), data=data, headers=headers) assert res.status_code == 201 def main(): ap = argparse.ArgumentParser() ap.add_argument('-v', '--verbose', action='store_true') ap.add_argument('--db', choices=('sqlite3', 'mysql'), default='sqlite3') ap.add_argument('installdir') ap.add_argument('tarball') args = ap.parse_args() if not exists(args.installdir): print 'directory {} does not exist'.format(args.installdir) sys.exit(1) if os.listdir(args.installdir): print 'directory {} is not empty'.format(args.installdir) sys.exit(1) if not exists(args.tarball): print 'file {} does not exist'.format(args.tarball) sys.exit(1) m = re.match(r'^.*?_([\d\.]+).*?\.tar\.gz$', basename(args.tarball)) version = m.group(1) cfg = ServerConfig(installdir=args.installdir, tarball=args.tarball, version=version) setup_server(cfg, args.db) start_server(cfg) create_test_user(cfg) if __name__ == '__main__': setup_logging() main() seafile-6.1.5/integration-tests/install-deps.sh000077500000000000000000000050111323477647300215710ustar00rootroot00000000000000#!/bin/bash set -e -x pip install http://effbot.org/media/downloads/PIL-1.1.7.tar.gz pip install -r ./integration-tests/requirements.txt pushd $HOME # download precompiled libevhtp libevhtp_bin=libevhtp-bin_1.2.0.tar.gz wget https://dl.bintray.com/lins05/generic/libevhtp-bin/$libevhtp_bin tar xf $libevhtp_bin find $HOME/opt # download precompiled libzdb # zdb_bin=libzdb-bin_2.11.1.tar.gz # wget https://dl.bintray.com/lins05/generic/libzdb-bin/$zdb_bin # tar xf $zdb_bin # sed -i -e "s|prefix=/opt/local|prefix=$HOME/opt/local|g" $HOME/opt/local/lib/pkgconfig/zdb.pc # find $HOME/opt pushd /tmp/ git clone --depth=1 https://github.com/haiwen/libzdb.git cd libzdb ./bootstrap ./configure --prefix=$HOME/opt/local make -j2 make install popd # download seahub thirdpart python libs WGET="wget --no-check-certificate" downloads=$HOME/downloads thirdpart=$HOME/thirdpart mkdir -p $downloads $thirdpart cd $thirdpart save_pythonpath=$PYTHONPATH export PYTHONPATH=. urls=( https://pypi.python.org/packages/source/p/pytz/pytz-2016.1.tar.gz https://www.djangoproject.com/m/releases/1.8/Django-1.8.10.tar.gz https://pypi.python.org/packages/source/d/django-statici18n/django-statici18n-1.1.3.tar.gz https://pypi.python.org/packages/source/d/djangorestframework/djangorestframework-3.3.2.tar.gz https://pypi.python.org/packages/source/d/django_compressor/django_compressor-1.4.tar.gz https://pypi.python.org/packages/source/j/jsonfield/jsonfield-1.0.3.tar.gz https://pypi.python.org/packages/source/d/django-post_office/django-post_office-2.0.6.tar.gz http://pypi.python.org/packages/source/g/gunicorn/gunicorn-19.4.5.tar.gz http://pypi.python.org/packages/source/f/flup/flup-1.0.2.tar.gz https://pypi.python.org/packages/source/c/chardet/chardet-2.3.0.tar.gz https://labix.org/download/python-dateutil/python-dateutil-1.5.tar.gz https://pypi.python.org/packages/source/s/six/six-1.9.0.tar.gz https://pypi.python.org/packages/source/d/django-picklefield/django-picklefield-0.3.2.tar.gz https://pypi.python.org/packages/source/d/django-constance/django-constance-1.0.1.tar.gz https://pypi.python.org/packages/source/j/jdcal/jdcal-1.2.tar.gz https://pypi.python.org/packages/source/e/et_xmlfile/et_xmlfile-1.0.1.tar.gz https://pypi.python.org/packages/source/o/openpyxl/openpyxl-2.3.0.tar.gz ) for url in ${urls[*]}; do path="${downloads}/$(basename $url)" if [[ ! -e $path ]]; then $WGET -O $path $url fi easy_install -d . $path done export PYTHONPATH=$save_pythonpath popd seafile-6.1.5/integration-tests/requirements.txt000066400000000000000000000001671323477647300221260ustar00rootroot00000000000000termcolor==1.1.0 prettytable==0.7.2 pexpect==4.0 requests==2.8.0 httpie django-constance[database] MySQL-python==1.2.5 seafile-6.1.5/integration-tests/run.py000077500000000000000000000207531323477647300200260ustar00rootroot00000000000000#!/usr/bin/env python import os from os.path import abspath, basename, exists, expanduser, join import sys import re import glob import json import logging import requests import termcolor from pexpect import spawn from utils import green, red, debug, info, warning, cd, shell, chdir, setup_logging from autosetup import (setup_server, ServerConfig, get_script, server_dir, start_server, create_test_user, MYSQL_ROOT_PASSWD) TOPDIR = abspath(join(os.getcwd(), '..')) PREFIX = expanduser('~/opt/local') SRCDIR = '/tmp/src' INSTALLDIR = '/tmp/haiwen' THIRDPARTDIR = expanduser('~/thirdpart') logger = logging.getLogger(__file__) seafile_version = '' TRAVIS_BRANCH = os.environ.get('TRAVIS_BRANCH', 'master') def make_build_env(): env = dict(os.environ) libsearpc_dir = abspath(join(TOPDIR, 'libsearpc')) ccnet_dir = abspath(join(TOPDIR, 'ccnet')) def _env_add(*a, **kw): kw['env'] = env return prepend_env_value(*a, **kw) _env_add('CPPFLAGS', '-I%s' % join(PREFIX, 'include'), seperator=' ') _env_add('LDFLAGS', '-L%s' % os.path.join(PREFIX, 'lib'), seperator=' ') _env_add('LDFLAGS', '-L%s' % os.path.join(PREFIX, 'lib64'), seperator=' ') _env_add('PATH', os.path.join(PREFIX, 'bin')) _env_add('PATH', THIRDPARTDIR) _env_add('PKG_CONFIG_PATH', os.path.join(PREFIX, 'lib', 'pkgconfig')) _env_add('PKG_CONFIG_PATH', os.path.join(PREFIX, 'lib64', 'pkgconfig')) _env_add('PKG_CONFIG_PATH', libsearpc_dir) _env_add('PKG_CONFIG_PATH', ccnet_dir) for key in ('PATH', 'PKG_CONFIG_PATH', 'CPPFLAGS', 'LDFLAGS', 'PYTHONPATH'): info('%s: %s', key, env.get(key, '')) return env def prepend_env_value(name, value, seperator=':', env=None): '''append a new value to a list''' env = env or os.environ current_value = env.get(name, '') new_value = value if current_value: new_value += seperator + current_value env[name] = new_value return env def get_project_branch(project, default_branch='master'): if project.name == 'seafile': return TRAVIS_BRANCH conf = json.loads(requests.get( 'https://raw.githubusercontent.com/haiwen/seafile-test-deploy/master/branches.json').text) return conf.get(TRAVIS_BRANCH, {}).get(project.name, default_branch) class Project(object): configure_cmd = './configure' def __init__(self, name): self.name = name self.version = '' @property def url(self): return 'https://www.github.com/haiwen/{}.git'.format(self.name) @property def projectdir(self): return join(TOPDIR, self.name) @property def branch(self): return get_project_branch(self) def clone(self): if exists(self.name): with cd(self.name): shell('git fetch origin --tags') else: shell('git clone --depth=1 --branch {} {}'.format(self.branch, self.url)) @chdir def make_dist(self): info('making tarball for %s', self.name) if exists('./autogen.sh'): shell('./autogen.sh') shell(self.configure_cmd, env=make_build_env()) shell('make dist') @chdir def copy_dist(self): self.make_dist() tarball = glob.glob('*.tar.gz')[0] info('copying %s to %s', tarball, SRCDIR) shell('cp {} {}'.format(tarball, SRCDIR)) m = re.match('{}-(.*).tar.gz'.format(self.name), basename(tarball)) if m: self.version = m.group(1) @chdir def use_branch(self, branch): shell('git checkout {}'.format(branch)) class Ccnet(Project): def __init__(self): super(Ccnet, self).__init__('ccnet') class Seafile(Project): configure_cmd = './configure --enable-client --enable-server' def __init__(self): super(Seafile, self).__init__('seafile') @chdir def copy_dist(self): super(Seafile, self).copy_dist() global seafile_version seafile_version = self.version class Seahub(Project): def __init__(self): super(Seahub, self).__init__('seahub') @chdir def make_dist(self): cmds = [ # 'git add -f media/css/*.css', # 'git commit -a -m "%s"' % msg, './tools/gen-tarball.py --version={} --branch=HEAD >/dev/null' .format(seafile_version), ] for cmd in cmds: shell(cmd, env=make_build_env()) class SeafDAV(Project): def __init__(self): super(SeafDAV, self).__init__('seafdav') @chdir def make_dist(self): shell('make') class SeafObj(Project): def __init__(self): super(SeafObj, self).__init__('seafobj') @chdir def make_dist(self): shell('make dist') def build_server(libsearpc, ccnet, seafile): cmd = [ 'python', join(TOPDIR, 'seafile/scripts/build/build-server.py'), '--yes', '--version=%s' % seafile.version, '--libsearpc_version=%s' % libsearpc.version, '--ccnet_version=%s' % ccnet.version, '--seafile_version=%s' % seafile.version, '--thirdpartdir=%s' % THIRDPARTDIR, '--srcdir=%s' % SRCDIR, '--jobs=4', ] shell(cmd, shell=False, env=make_build_env()) def fetch_and_build(): libsearpc = Project('libsearpc') ccnet = Ccnet() seafile = Seafile() seahub = Seahub() seafobj = SeafObj() seafdav = SeafDAV() for project in (libsearpc, ccnet, seafile, seahub, seafdav, seafobj): if project.name != 'seafile': project.clone() project.copy_dist() build_server(libsearpc, ccnet, seafile) def run_tests(cfg): # run_python_seafile_tests() # run_seafdav_tests(cfg) # must stop seafile server before running seaf-gc shell('{} stop'.format(get_script(cfg, 'seafile.sh'))) shell('{} stop'.format(get_script(cfg, 'seahub.sh'))) shell('{} --verbose --rm-deleted'.format(get_script(cfg, 'seaf-gc.sh'))) def run_python_seafile_tests(): python_seafile = Project('python-seafile') if not exists(python_seafile.projectdir): python_seafile.clone() shell('pip install -r {}/requirements.txt'.format( python_seafile.projectdir)) with cd(python_seafile.projectdir): # install python-seafile because seafdav tests needs it shell('python setup.py install') shell('py.test') def _seafdav_env(cfg): env = dict(os.environ) env['CCNET_CONF_DIR'] = join(INSTALLDIR, 'ccnet') env['SEAFILE_CONF_DIR'] = join(INSTALLDIR, 'seafile-data') env['SEAFILE_CENTRAL_CONF_DIR'] = join(INSTALLDIR, 'conf') for path in glob.glob(join( server_dir(cfg), 'seafile/lib*/python*/*-packages')): prepend_env_value('PYTHONPATH', path, env=env) return env def run_seafdav_tests(cfg): seafdav = SeafDAV() shell('pip install -r {}/test-requirements.txt'.format(seafdav.projectdir)) with cd(seafdav.projectdir): shell('nosetests -v -s', env=_seafdav_env(cfg)) def _mkdirs(*paths): for path in paths: if not exists(path): os.mkdir(path) def main(): _mkdirs(SRCDIR, INSTALLDIR) setup_logging() fetch_and_build() for db in ('sqlite3', 'mysql'): if db == 'mysql': shell('mysqladmin -u root password %s' % MYSQL_ROOT_PASSWD) for i in ('prompt', 'auto'): shell('rm -rf {}/*'.format(INSTALLDIR)) setup_and_test(db, i) def setup_and_test(db, initmode): cfg = ServerConfig( installdir=INSTALLDIR, tarball=join(TOPDIR, 'seafile-server_{}_x86-64.tar.gz'.format( seafile_version)), version=seafile_version, initmode=initmode) info('Setting up seafile server with %s database', db) setup_server(cfg, db) # enable webdav, we're going to seafdav tests later shell('''sed -i -e "s/enabled = false/enabled = true/g" {}''' .format(join(INSTALLDIR, 'conf/seafdav.conf'))) try: start_server(cfg) info('Testing seafile server with %s database', db) create_test_user(cfg) run_tests(cfg) except: for logfile in glob.glob('{}/logs/*.log'.format(INSTALLDIR)): shell('echo {0}; cat {0}'.format(logfile)) for logfile in glob.glob('{}/seafile-server-{}/runtime/*.log'.format( INSTALLDIR, seafile_version)): shell('echo {0}; cat {0}'.format(logfile)) raise if __name__ == '__main__': os.chdir(TOPDIR) main() seafile-6.1.5/integration-tests/utils.py000066400000000000000000000031751323477647300203560ustar00rootroot00000000000000#coding: UTF-8 import os from os.path import abspath, basename, exists, expanduser, join import sys import re import logging from contextlib import contextmanager from subprocess import Popen, PIPE, CalledProcessError import termcolor import requests from pexpect import spawn logger = logging.getLogger(__file__) def _color(s, color): return s if not os.isatty(sys.stdout.fileno()) \ else termcolor.colored(str(s), color) def green(s): return _color(s, 'green') def red(s): return _color(s, 'red') def debug(fmt, *a): logger.debug(green(fmt), *a) def info(fmt, *a): logger.info(green(fmt), *a) def warning(fmt, *a): logger.warn(red(fmt), *a) def shell(cmd, inputdata=None, **kw): info('calling "%s" in %s', cmd, kw.get('cwd', os.getcwd())) kw['shell'] = not isinstance(cmd, list) kw['stdin'] = PIPE if inputdata else None p = Popen(cmd, **kw) if inputdata: p.communicate(inputdata) p.wait() if p.returncode: raise CalledProcessError(p.returncode, cmd) @contextmanager def cd(path): olddir = os.getcwd() os.chdir(path) try: yield finally: os.chdir(olddir) def chdir(func): def wrapped(self, *w, **kw): with cd(self.projectdir): return func(self, *w, **kw) return wrapped def setup_logging(): kw = { 'format': '[%(asctime)s][%(module)s]: %(message)s', 'datefmt': '%m/%d/%Y %H:%M:%S', 'level': logging.DEBUG, 'stream': sys.stdout, } logging.basicConfig(**kw) logging.getLogger('requests.packages.urllib3.connectionpool').setLevel( logging.WARNING) seafile-6.1.5/lib/000077500000000000000000000000001323477647300137215ustar00rootroot00000000000000seafile-6.1.5/lib/Makefile.am000066400000000000000000000045631323477647300157650ustar00rootroot00000000000000pcfiles = libseafile.pc pkgconfig_DATA = $(pcfiles) pkgconfigdir = $(libdir)/pkgconfig AM_CPPFLAGS = @GLIB2_CFLAGS@ -I$(top_srcdir)/include \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/common \ @CCNET_CFLAGS@ \ @SEARPC_CFLAGS@ \ @MSVC_CFLAGS@ \ -Wall BUILT_SOURCES = gensource ## source file rules seafile_object_define = repo.vala commit.vala dirent.vala dir.vala \ task.vala branch.vala crypt.vala webaccess.vala copy-task.vala seafile_object_gen = $(seafile_object_define:.vala=.c) valac_gen = ${seafile_object_gen} seafile-object.h EXTRA_DIST = ${seafile_object_define} rpc_table.py $(pcfiles) vala.stamp utils_headers = net.h utils.h db.h utils_srcs = $(utils_headers:.h=.c) noinst_HEADERS = ${utils_headers} include.h seafiledir = $(includedir)/seafile seafile_HEADERS = seafile-object.h seafile-rpc-wrapper.c: seafile-object.h seafile-object.h: ${seafile_object_define} rm -f $@ valac --pkg posix ${seafile_object_define} -C -H seafile-object.h DISTCLEANFILES = ${searpc_gen} ## library rules lib_LTLIBRARIES = libseafile.la libseafile_la_SOURCES = ${seafile_object_gen} seafile-rpc-wrapper.c libseafile_la_LDFLAGS = -no-undefined libseafile_la_LIBADD = @GLIB2_LIBS@ @GOBJECT_LIBS@ @SEARPC_LIBS@ noinst_LTLIBRARIES = libseafile_common.la libseafile_common_la_SOURCES = ${seafile_object_gen} ${utils_srcs} libseafile_common_la_LDFLAGS = -no-undefined libseafile_common_la_LIBADD = @GLIB2_LIBS@ @GOBJECT_LIBS@ @LIB_GDI32@ \ @LIB_UUID@ @LIB_WS32@ @LIB_PSAPI@ -lsqlite3 \ @LIBEVENT_LIBS@ @SEARPC_LIBS@ @LIB_SHELL32@ \ @ZLIB_LIBS@ searpc_gen = searpc-signature.h searpc-marshal.h gensource: ${searpc_gen} ${valac_gen} rpc_table.stamp: ${top_srcdir}/lib/rpc_table.py @rm -f rpc_table.tmp @touch rpc_table.tmp @echo "[libsearpc]: generating rpc header files" @PYTHON@ `which searpc-codegen.py` ${top_srcdir}/lib/rpc_table.py @echo "[libsearpc]: done" @mv -f rpc_table.tmp $@ ${searpc_gen}: rpc_table.stamp vala.stamp: ${seafile_object_define} rm -f ${seafile_object_gen} @rm -f vala.tmp @touch vala.tmp valac -C --pkg posix $^ @mv -f vala.tmp $@ ${seafile_object_gen}: vala.stamp clean-local: rm -f ${searpc_gen} rm -f rpc_table.pyc rm -f rpc_table.stamp rm -f rpc_table.tmp rm -f vala.tmp vala.stamp ${valac_gen} install-data-local: if MACOS sed -i '' -e "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles) else ${SED} -i "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles) endif seafile-6.1.5/lib/branch.vala000066400000000000000000000007711323477647300160300ustar00rootroot00000000000000// compile this file with `valac --pkg posix repo.vala -C -H repo.h` namespace Seafile { public class Branch : Object { public string _name; public string name { get { return _name; } set { _name = value; } } public string _commit_id; public string commit_id { get { return _commit_id; } set { _commit_id = value; } } public string _repo_id; public string repo_id { get { return _repo_id; } set { _repo_id = value; } } } } // namespace seafile-6.1.5/lib/commit.vala000066400000000000000000000032021323477647300160530ustar00rootroot00000000000000// compile this file with `valac --pkg posix repo.vala -C -H repo.h` namespace Seafile { public class Commit : Object { // _id is for fast access from c code. id is for // vala to automatically generate a property. Note, // if a Vala property is start with _, it is not // translated into a GObject property. public char _id[41]; public string id { get { return (string)_id; } set { Posix.memcpy(_id, value, 40); _id[40] = '\0'; } } public string creator_name { get; set; } public string _creator; // creator public string creator { get { return _creator; } set { _creator = value; } } public string _desc; // description: what does this commit change public string desc { get { return _desc; } set { _desc = value; } } public int64 _ctime; // create time public int64 ctime { get { return _ctime; } set { _ctime = value; } } public string parent_id { get; set;} public string second_parent_id { get; set; } public string _repo_id; public string repo_id { get { return _repo_id; } set { _repo_id = value; } } // A commit point to a file or dir, not both. public string _root_id; public string root_id { get { return _root_id; } set { _root_id = value; } } // Repo data-format version of this commit public int version { get; set; } public bool new_merge { get; set; } public bool conflict { get; set; } // Used for returning file revision public string rev_file_id { get; set; } public int64 rev_file_size { get; set; } // Set if this commit renames a revision of a file public string rev_renamed_old_path { get; set; } public string device_name { get; set; } } } // namespace seafile-6.1.5/lib/copy-task.vala000066400000000000000000000006051323477647300165010ustar00rootroot00000000000000namespace Seafile { public class CopyTask : Object { public int64 done { set; get; } public int64 total { set; get; } public bool canceled { set; get; } public bool failed { set; get; } public bool successful { set; get; } } public class CopyResult : Object { public bool background { set; get; } public string task_id { set; get; } } } seafile-6.1.5/lib/crypt.vala000066400000000000000000000002101323477647300157200ustar00rootroot00000000000000namespace Seafile { public class CryptKey : Object { public string key { set; get; } public string iv { set; get; } } } seafile-6.1.5/lib/db.c000066400000000000000000000116761323477647300144650ustar00rootroot00000000000000 #include #include #include "db.h" int sqlite_open_db (const char *db_path, sqlite3 **db) { int result; const char *errmsg; result = sqlite3_open (db_path, db); if (result) { errmsg = sqlite3_errmsg (*db); g_warning ("Couldn't open database:'%s', %s\n", db_path, errmsg ? errmsg : "no error given"); sqlite3_close (*db); return -1; } return 0; } int sqlite_close_db (sqlite3 *db) { return sqlite3_close (db); } sqlite3_stmt * sqlite_query_prepare (sqlite3 *db, const char *sql) { sqlite3_stmt *stmt; int result; result = sqlite3_prepare_v2 (db, sql, -1, &stmt, NULL); if (result != SQLITE_OK) { const gchar *str = sqlite3_errmsg (db); g_warning ("Couldn't prepare query, error:%d->'%s'\n\t%s\n", result, str ? str : "no error given", sql); return NULL; } return stmt; } int sqlite_query_exec (sqlite3 *db, const char *sql) { char *errmsg = NULL; int result; result = sqlite3_exec (db, sql, NULL, NULL, &errmsg); if (result != SQLITE_OK) { if (errmsg != NULL) { g_warning ("SQL error: %d - %s\n:\t%s\n", result, errmsg, sql); sqlite3_free (errmsg); } return -1; } return 0; } int sqlite_begin_transaction (sqlite3 *db) { char *sql = "BEGIN TRANSACTION;"; return sqlite_query_exec (db, sql); } int sqlite_end_transaction (sqlite3 *db) { char *sql = "END TRANSACTION;"; return sqlite_query_exec (db, sql); } gboolean sqlite_check_for_existence (sqlite3 *db, const char *sql) { sqlite3_stmt *stmt; int result; stmt = sqlite_query_prepare (db, sql); if (!stmt) return FALSE; result = sqlite3_step (stmt); if (result == SQLITE_ERROR) { const gchar *str = sqlite3_errmsg (db); g_warning ("Couldn't execute query, error: %d->'%s'\n", result, str ? str : "no error given"); sqlite3_finalize (stmt); return FALSE; } sqlite3_finalize (stmt); if (result == SQLITE_ROW) return TRUE; return FALSE; } int sqlite_foreach_selected_row (sqlite3 *db, const char *sql, SqliteRowFunc callback, void *data) { sqlite3_stmt *stmt; int result; int n_rows = 0; stmt = sqlite_query_prepare (db, sql); if (!stmt) { return -1; } while (1) { result = sqlite3_step (stmt); if (result != SQLITE_ROW) break; n_rows++; if (!callback (stmt, data)) break; } if (result == SQLITE_ERROR) { const gchar *s = sqlite3_errmsg (db); g_warning ("Couldn't execute query, error: %d->'%s'\n", result, s ? s : "no error given"); sqlite3_finalize (stmt); return -1; } sqlite3_finalize (stmt); return n_rows; } int sqlite_get_int (sqlite3 *db, const char *sql) { int ret = -1; int result; sqlite3_stmt *stmt; if ( !(stmt = sqlite_query_prepare(db, sql)) ) return 0; result = sqlite3_step (stmt); if (result == SQLITE_ROW) { ret = sqlite3_column_int (stmt, 0); sqlite3_finalize (stmt); return ret; } if (result == SQLITE_ERROR) { const gchar *str = sqlite3_errmsg (db); g_warning ("Couldn't execute query, error: %d->'%s'\n", result, str ? str : "no error given"); sqlite3_finalize (stmt); return -1; } sqlite3_finalize(stmt); return ret; } gint64 sqlite_get_int64 (sqlite3 *db, const char *sql) { gint64 ret = -1; int result; sqlite3_stmt *stmt; if ( !(stmt = sqlite_query_prepare(db, sql)) ) return 0; result = sqlite3_step (stmt); if (result == SQLITE_ROW) { ret = sqlite3_column_int64 (stmt, 0); sqlite3_finalize (stmt); return ret; } if (result == SQLITE_ERROR) { const gchar *str = sqlite3_errmsg (db); g_warning ("Couldn't execute query, error: %d->'%s'\n", result, str ? str : "no error given"); sqlite3_finalize (stmt); return -1; } sqlite3_finalize(stmt); return ret; } char *sqlite_get_string (sqlite3 *db, const char *sql) { const char *res = NULL; int result; sqlite3_stmt *stmt; char *ret; if ( !(stmt = sqlite_query_prepare(db, sql)) ) return NULL; result = sqlite3_step (stmt); if (result == SQLITE_ROW) { res = (const char *)sqlite3_column_text (stmt, 0); ret = g_strdup(res); sqlite3_finalize (stmt); return ret; } if (result == SQLITE_ERROR) { const gchar *str = sqlite3_errmsg (db); g_warning ("Couldn't execute query, error: %d->'%s'\n", result, str ? str : "no error given"); sqlite3_finalize (stmt); return NULL; } sqlite3_finalize(stmt); return NULL; } seafile-6.1.5/lib/db.h000066400000000000000000000015651323477647300144660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef DB_UTILS_H #define DB_UTILS_H #include int sqlite_open_db (const char *db_path, sqlite3 **db); int sqlite_close_db (sqlite3 *db); sqlite3_stmt *sqlite_query_prepare (sqlite3 *db, const char *sql); int sqlite_query_exec (sqlite3 *db, const char *sql); int sqlite_begin_transaction (sqlite3 *db); int sqlite_end_transaction (sqlite3 *db); gboolean sqlite_check_for_existence (sqlite3 *db, const char *sql); typedef gboolean (*SqliteRowFunc) (sqlite3_stmt *stmt, void *data); int sqlite_foreach_selected_row (sqlite3 *db, const char *sql, SqliteRowFunc callback, void *data); int sqlite_get_int (sqlite3 *db, const char *sql); gint64 sqlite_get_int64 (sqlite3 *db, const char *sql); char *sqlite_get_string (sqlite3 *db, const char *sql); #endif seafile-6.1.5/lib/dir.vala000066400000000000000000000007301323477647300153440ustar00rootroot00000000000000namespace Seafile { public class Dir : Object { // _id is for fast access from c code. id is for // vala to automatically generate a property. Note, // if a Vala property is start with _, it is not // translated into a GObject property. public char _id[41]; public string id { get { return (string)_id; } set { Posix.memcpy(_id, value, 40); _id[40] = '\0'; } } public List entries; public int version { set; get; } } } // namespace seafile-6.1.5/lib/dirent.vala000066400000000000000000000015121323477647300160520ustar00rootroot00000000000000namespace Seafile { public class Dirent : Object { // _id is for fast access from c code. id is for // vala to automatically generate a property. Note, // if a Vala property is start with _, it is not // translated into a GObject property. public string obj_id { set; get; } public string obj_name { set; get; } public int mode { set; get; } public int version { set; get; } public int64 mtime { set; get; } public int64 size { set; get; } public string modifier { set; get;} public string permission { set; get; } public bool is_locked { set; get; } public string lock_owner { set; get; } public int64 lock_time { set; get; } public bool is_shared { set; get; } } public class FileLastModifiedInfo : Object { public string file_name { set; get; } public int64 last_modified { set; get; } } } // namespace seafile-6.1.5/lib/file.vala000066400000000000000000000006361323477647300155120ustar00rootroot00000000000000namespace Seafile { public class File : Object { // _id is for fast access from c code. id is for // vala to automatically generate a property. Note, // if a Vala property is start with _, it is not // translated into a GObject property. public char _id[41]; public string id { get { return (string)_id; } set { Posix.memcpy(_id, id, 40); _id[40] = '\0'; } } public uint64 size; } } // namespaceseafile-6.1.5/lib/include.h000066400000000000000000000012301323477647300155110ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include "utils.h" #include #ifndef ccnet_warning #define ccnet_warning(fmt, ...) g_warning( "%s: " fmt, __func__ , ##__VA_ARGS__) #endif #ifndef ccnet_error #define ccnet_error(fmt, ...) g_error( "%s: " fmt, __func__ , ##__VA_ARGS__) #endif #ifndef ccnet_message #define ccnet_message(fmt, ...) g_message(fmt, ##__VA_ARGS__) #endif #ifndef ccnet_debug #define ccnet_debug(fmt, ...) g_debug(fmt, ##__VA_ARGS__) #endif #ifndef ENABLE_DEBUG #undef g_debug #define g_debug(...) #endif seafile-6.1.5/lib/libseafile.pc.in000066400000000000000000000004541323477647300167540ustar00rootroot00000000000000prefix=(DESTDIR)@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libseafile Description: Client library for accessing seafile service. Version: @VERSION@ Libs: -L${libdir} -lseafile @SEARPC_LIBS@ Cflags: -I${includedir} @SEARPC_CFLAGS@ Requires: gobject-2.0 glib-2.0 seafile-6.1.5/lib/net.c000066400000000000000000000421001323477647300146500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifdef WIN32 #define WINVER 0x0501 #include #include #include #include #endif #include "include.h" #include #include #include #include #include #ifdef WIN32 #define UNUSED #else #include #include #include #include #include #include #include #include #include #endif #include #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else #include #endif #include "net.h" #ifdef WIN32 #ifndef inet_aton int inet_aton(const char *string, struct in_addr *addr) { addr->s_addr = inet_addr(string); if (addr->s_addr != -1 || strcmp("255.255.255.255", string) == 0) return 1; return 0; } #endif #endif //WIN32 int ccnet_netSetTOS (evutil_socket_t s, int tos) { #ifdef IP_TOS return setsockopt( s, IPPROTO_IP, IP_TOS, (char*)&tos, sizeof( tos ) ); #else return 0; #endif } static evutil_socket_t makeSocketNonBlocking (evutil_socket_t fd) { if (fd >= 0) { if (evutil_make_socket_nonblocking(fd)) { ccnet_warning ("Couldn't make socket nonblock: %s", evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR())); evutil_closesocket(fd); fd = -1; } } return fd; } static evutil_socket_t createSocket (int family, int nonblock) { evutil_socket_t fd; int ret; fd = socket (family, SOCK_STREAM, 0); if (fd < 0) { ccnet_warning("create Socket failed %d\n", fd); } else if (nonblock) { int nodelay = 1; fd = makeSocketNonBlocking( fd ); ret = setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); if (ret < 0) { ccnet_warning("setsockopt failed\n"); evutil_closesocket(fd); return -1; } } return fd; } evutil_socket_t ccnet_net_open_tcp (const struct sockaddr *sa, int nonblock) { evutil_socket_t s; int sa_len; if( (s = createSocket(sa->sa_family, nonblock)) < 0 ) return -1; #ifndef WIN32 if (sa->sa_family == AF_INET) sa_len = sizeof (struct sockaddr_in); else sa_len = sizeof (struct sockaddr_in6); #else if (sa->sa_family == AF_INET) sa_len = sizeof (struct sockaddr_in); else return -1; #endif if( (connect(s, sa, sa_len) < 0) #ifdef WIN32 && (sockerrno != WSAEWOULDBLOCK) #endif && (sockerrno != EINPROGRESS) ) { evutil_closesocket(s); s = -1; } return s; } evutil_socket_t ccnet_net_bind_tcp (int port, int nonblock) { #ifndef WIN32 int sockfd, n; struct addrinfo hints, *res, *ressave; char buf[10]; memset (&hints, 0,sizeof (struct addrinfo)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf (buf, sizeof(buf), "%d", port); if ( (n = getaddrinfo(NULL, buf, &hints, &res) ) != 0) { ccnet_warning ("getaddrinfo fails: %s\n", gai_strerror(n)); return -1; } ressave = res; do { int on = 1; sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) continue; /* error - try next one */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { ccnet_warning ("setsockopt of SO_REUSEADDR error\n"); continue; } if (nonblock) sockfd = makeSocketNonBlocking (sockfd); if (sockfd < 0) continue; /* error - try next one */ if (bind(sockfd, res->ai_addr, res->ai_addrlen) == 0) break; /* success */ close(sockfd); /* bind error - close and try next one */ } while ( (res = res->ai_next) != NULL); freeaddrinfo (ressave); if (res == NULL) { ccnet_warning ("bind fails: %s\n", strerror(errno)); return -1; } return sockfd; #else evutil_socket_t s; struct sockaddr_in sock; const int type = AF_INET; #if defined( SO_REUSEADDR ) || defined( SO_REUSEPORT ) int optval; #endif if ((s = createSocket(type, nonblock)) < 0) return -1; optval = 1; setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval)); memset(&sock, 0, sizeof(sock)); sock.sin_family = AF_INET; sock.sin_addr.s_addr = INADDR_ANY; sock.sin_port = htons(port); if ( bind(s, (struct sockaddr *)&sock, sizeof(struct sockaddr_in)) < 0) { ccnet_warning ("bind fails: %s\n", strerror(errno)); evutil_closesocket (s); return -1; } if (nonblock) s = makeSocketNonBlocking (s); return s; #endif } int ccnet_net_make_socket_blocking(evutil_socket_t fd) { #ifdef WIN32 { u_long nonblocking = 0; if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) { ccnet_warning ("fcntl(%d, F_GETFL)", (int)fd); return -1; } } #else { int flags; if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) { ccnet_warning ("fcntl(%d, F_GETFL)", fd); return -1; } if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) { ccnet_warning ("fcntl(%d, F_SETFL)", fd); return -1; } } #endif return 0; } evutil_socket_t ccnet_net_accept (evutil_socket_t b, struct sockaddr_storage *cliaddr, socklen_t *len, int nonblock) { evutil_socket_t s; /* int nodelay = 1; */ s = accept (b, (struct sockaddr *)cliaddr, len); /* setsockopt (s, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)); */ if (nonblock) makeSocketNonBlocking(s); return s; } evutil_socket_t ccnet_net_bind_v4 (const char *ipaddr, int *port) { evutil_socket_t sockfd; struct sockaddr_in addr; int on = 1; sockfd = socket (AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { ccnet_warning("create socket failed: %s\n", strerror(errno)); exit(-1); } memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_family = AF_INET; if (inet_aton(ipaddr, &addr.sin_addr) == 0) { ccnet_warning ("Bad ip address %s\n", ipaddr); return -1; } addr.sin_port = htons (*port); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { ccnet_warning ("setsockopt of SO_REUSEADDR error: %s\n", strerror(errno)); return -1; } if ( bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ccnet_warning ("Bind error: %s\n", strerror (errno)); return -1; } if (*port == 0) { struct sockaddr_storage ss; socklen_t len; len = sizeof(ss); if (getsockname(sockfd, (struct sockaddr *)&ss, &len) < 0) { ccnet_warning ("getsockname error: %s\n", strerror(errno)); return -1; } *port = sock_port ((struct sockaddr *)&ss); } return sockfd; } char * sock_ntop(const struct sockaddr *sa, socklen_t salen) { static char str[128]; /* Unix domain is largest */ switch (sa->sa_family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *) sa; if (evutil_inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) return(NULL); return(str); } #ifdef IPv6 case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; if (evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str) - 1) == NULL) return(NULL); return (str); } #endif #ifndef WIN32 #ifdef AF_UNIX case AF_UNIX: { struct sockaddr_un *unp = (struct sockaddr_un *) sa; /* OK to have no pathname bound to the socket: happens on every connect() unless client calls bind() first. */ if (unp->sun_path[0] == 0) strcpy(str, "(no pathname bound)"); else snprintf(str, sizeof(str), "%s", unp->sun_path); return(str); } #endif #endif default: snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d", sa->sa_family, salen); return(str); } return (NULL); } int sock_pton (const char *addr_str, uint16_t port, struct sockaddr_storage *sa) { struct sockaddr_in *saddr = (struct sockaddr_in *) sa; #ifndef WIN32 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *) sa; #endif if (evutil_inet_pton (AF_INET, addr_str, &saddr->sin_addr) == 1 ) { saddr->sin_family = AF_INET; saddr->sin_port = htons (port); return 0; } #ifndef WIN32 else if (evutil_inet_pton (AF_INET6, addr_str, &saddr6->sin6_addr) == 1) { saddr6->sin6_family = AF_INET6; saddr6->sin6_port = htons (port); return 0; } #endif return -1; } /* return 1 if addr_str is a valid ipv4 or ipv6 address */ int is_valid_ipaddr (const char *addr_str) { struct sockaddr_storage addr; if (!addr_str) return 0; if (sock_pton(addr_str, 0, &addr) < 0) return 0; return 1; } uint16_t sock_port (const struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *) sa; return ntohs(sin->sin_port); } #ifdef IPv6 case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; return ntohs(sin6->sin6_port); } #endif default: return 0; } return 0; } evutil_socket_t udp_client (const char *host, const char *serv, struct sockaddr **saptr, socklen_t *lenp) { evutil_socket_t sockfd; int n; struct addrinfo hints, *res, *ressave; memset (&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; if ((n = getaddrinfo(host, serv, &hints, &res)) != 0) { ccnet_warning ("udp_client error for %s, %s: %s", host, serv, gai_strerror(n)); return -1; } ressave = res; do { sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd >= 0) break; /* success */ } while ( (res = res->ai_next) != NULL); if (res == NULL) { /* errno set from final socket() */ ccnet_warning ("udp_client error for %s, %s", host, serv); freeaddrinfo (ressave); return -1; } *saptr = malloc(res->ai_addrlen); memcpy(*saptr, res->ai_addr, res->ai_addrlen); *lenp = res->ai_addrlen; freeaddrinfo(ressave); return (sockfd); } int family_to_level(int family) { switch (family) { case AF_INET: return IPPROTO_IP; #ifdef IPV6 case AF_INET6: return IPPROTO_IPV6; #endif default: return -1; } } #ifdef WIN32 static int mcast_join(evutil_socket_t sockfd, const struct sockaddr *grp, socklen_t grplen, const char *ifname, u_int ifindex) { int optval = 3; int sockm; if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&optval, sizeof(int)) == SOCKET_ERROR) { ccnet_warning("Fail to set socket multicast TTL, LastError=%d\n", WSAGetLastError()); return -1; } optval = 0; if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(int)) == SOCKET_ERROR) { ccnet_warning("Fail to set socket multicast LOOP, LastError=%d\n", WSAGetLastError()); return -1; } sockm = WSAJoinLeaf (sockfd, grp, grplen, NULL, NULL, NULL, NULL, JL_BOTH); if (sockm == INVALID_SOCKET) { ccnet_warning("Fail to join multicast group, LastError=%d\n", WSAGetLastError()); return -1; } return sockm; } evutil_socket_t create_multicast_sock (struct sockaddr *sasend, socklen_t salen) { int ret; const int on = 1; evutil_socket_t recvfd; struct sockaddr *sarecv; recvfd = WSASocket (AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF |WSA_FLAG_OVERLAPPED); if (recvfd < 0) { ccnet_warning ("Create multicast listen socket fails: %d\n", WSAGetLastError()); return -1; } ret = setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (ret != 0) { ccnet_warning("Failed to setsockopt SO_REUSEADDR, WSAGetLastError=%d\n", WSAGetLastError()); return -1; } sarecv = malloc(salen); memcpy(sarecv, sasend, salen); struct sockaddr_in *saddr = (struct sockaddr_in *)sarecv; saddr->sin_addr.s_addr = INADDR_ANY; if (bind(recvfd, sarecv, salen) < 0) { ccnet_warning("Bind multicast bind socket failed LastError=%d\n", WSAGetLastError()); free (sarecv); return -1;; } free (sarecv); if (mcast_join(recvfd, sasend, salen, NULL, 0) < 0) { ccnet_warning ("mcast_join error: %s\n", strerror(errno)); return -1; } return recvfd; } #else static int mcast_join(evutil_socket_t sockfd, const struct sockaddr *grp, socklen_t grplen, const char *ifname, u_int ifindex) { #if (defined MCAST_JOIN_GROUP) && (! defined __APPLE__) struct group_req req; if (ifindex > 0) { req.gr_interface = ifindex; } else if (ifname != NULL) { if ( (req.gr_interface = if_nametoindex(ifname)) == 0) { errno = ENXIO; /* i/f name not found */ return(-1); } } else req.gr_interface = 0; if (grplen > sizeof(req.gr_group)) { errno = EINVAL; return -1; } memcpy(&req.gr_group, grp, grplen); return (setsockopt(sockfd, family_to_level(grp->sa_family), MCAST_JOIN_GROUP, &req, sizeof(req))); #else /* end mcast_join1 */ /* include mcast_join2 */ switch (grp->sa_family) { case AF_INET: { struct ip_mreq mreq; struct ifreq ifreq; memcpy(&mreq.imr_multiaddr.s_addr, &((const struct sockaddr_in *) grp)->sin_addr, sizeof(struct in_addr)); if (ifindex > 0) { if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) { errno = ENXIO; /* i/f index not found */ return(-1); } goto doioctl; } else if (ifname != NULL) { strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); doioctl: if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) return(-1); memcpy(&mreq.imr_interface, &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, sizeof(struct in_addr)); } else mreq.imr_interface.s_addr = htonl(INADDR_ANY); return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))); } /* end mcast_join2 */ /* include mcast_join3 */ #ifdef IPV6 #ifndef IPV6_JOIN_GROUP /* APIv0 compatibility */ #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP #endif case AF_INET6: { struct ipv6_mreq mreq6; memcpy(&mreq6.ipv6mr_multiaddr, &((const struct sockaddr_in6 *) grp)->sin6_addr, sizeof(struct in6_addr)); if (ifindex > 0) { mreq6.ipv6mr_interface = ifindex; } else if (ifname != NULL) { if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) { errno = ENXIO; /* i/f name not found */ return(-1); } } else mreq6.ipv6mr_interface = 0; return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6))); } #endif default: errno = EAFNOSUPPORT; return(-1); } #endif return -1; } evutil_socket_t create_multicast_sock (struct sockaddr *sasend, socklen_t salen) { int ret; const int on = 1; evutil_socket_t recvfd; struct sockaddr *sarecv; if ( (recvfd = socket (sasend->sa_family, SOCK_DGRAM, 0)) < 0) { ccnet_warning ("Create multicast listen socket fails: %s\n", strerror(errno)); return -1; } ret = setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); if (ret < 0) ccnet_warning("Failed to setsockopt SO_REUSEADDR\n"); sarecv = malloc(salen); memcpy(sarecv, sasend, salen); if (bind(recvfd, sarecv, salen) < 0) { ccnet_warning ("Bind multicast listen socket fails: %s\n", strerror(errno)); free (sarecv); return -1; } free (sarecv); if (mcast_join(recvfd, sasend, salen, NULL, 0) < 0) { ccnet_warning ("mcast_join error: %s\n", strerror(errno)); return -1; } return recvfd; } #endif int sockfd_to_family(evutil_socket_t sockfd) { struct sockaddr_storage ss; socklen_t len; len = sizeof(ss); if (getsockname(sockfd, (struct sockaddr *) &ss, &len) < 0) return(-1); return(ss.ss_family); } int mcast_set_loop(evutil_socket_t sockfd, int onoff) { #ifndef WIN32 switch (sockfd_to_family(sockfd)) { case AF_INET: { u_char flag; flag = onoff; return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &flag, sizeof(flag))); } #ifdef IPV6 case AF_INET6: { u_int flag; flag = onoff; return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &flag, sizeof(flag))); } #endif default: errno = EAFNOSUPPORT; return(-1); } #else return -1; #endif /* WIN32 */ } seafile-6.1.5/lib/net.h000066400000000000000000000044721323477647300146670ustar00rootroot00000000000000 #ifndef CCNET_NET_H #define CCNET_NET_H #ifdef WIN32 #include #include #include typedef int socklen_t; #define UNUSED #else #include #include #include #include #include #include #include #include #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else #include #endif #ifdef WIN32 /* #define ECONNREFUSED WSAECONNREFUSED */ /* #define ECONNRESET WSAECONNRESET */ /* #define EHOSTUNREACH WSAEHOSTUNREACH */ /* #define EINPROGRESS WSAEINPROGRESS */ /* #define ENOTCONN WSAENOTCONN */ /* #define EWOULDBLOCK WSAEWOULDBLOCK */ #define sockerrno WSAGetLastError( ) #else #include #define sockerrno errno #endif #ifdef WIN32 extern int inet_aton(const char *string, struct in_addr *addr); extern const char *inet_ntop(int af, const void *src, char *dst, size_t size); extern int inet_pton(int af, const char *src, void *dst); #endif evutil_socket_t ccnet_net_open_tcp (const struct sockaddr *sa, int nonblock); evutil_socket_t ccnet_net_bind_tcp (int port, int nonblock); evutil_socket_t ccnet_net_accept (evutil_socket_t b, struct sockaddr_storage *cliaddr, socklen_t *len, int nonblock); int ccnet_net_make_socket_blocking (evutil_socket_t fd); /* bind to an IPv4 address, if (*port == 0) the port number will be returned */ evutil_socket_t ccnet_net_bind_v4 (const char *ipaddr, int *port); int ccnet_netSetTOS ( evutil_socket_t s, int tos ); char *sock_ntop(const struct sockaddr *sa, socklen_t salen); uint16_t sock_port (const struct sockaddr *sa); /* return 1 if addr_str is a valid ipv4 or ipv6 address */ int is_valid_ipaddr (const char *addr_str); /* return 0 if success, -1 if error */ int sock_pton (const char *addr_str, uint16_t port, struct sockaddr_storage *sa); evutil_socket_t udp_client (const char *host, const char *serv, struct sockaddr **saptr, socklen_t *lenp); int mcast_set_loop(evutil_socket_t sockfd, int onoff); evutil_socket_t create_multicast_sock (struct sockaddr *sasend, socklen_t salen); #endif seafile-6.1.5/lib/repo.vala000066400000000000000000000137061323477647300155420ustar00rootroot00000000000000namespace Seafile { public class Repo : Object { // Section 1: Basic information // Members in this section should be set for every Repo object // _id is for fast access from c code. id is for // vala to automatically generate a property. Note, // if a Vala property is start with _, it is not // translated into a GObject property. public char _id[37]; public string id { get { return (string)_id; } set { Posix.memcpy(_id, value, 36); _id[36] = '\0'; } } public string _name; public string name { get { return _name; } set { _name = value; } } public string _desc; // description public string desc { get { return _desc; } set { _desc = value; } } // data format version public int version { get; set; } public int last_modify { get; set; } public int64 size { get; set; } public int64 file_count { get; set; } public string head_cmmt_id { get; set; } public string root { get; set; } // To be compatible with obsoleted SharedRepo object public string repo_id { get; set; } public string repo_name { get; set; } public string repo_desc { get; set; } public int last_modified { get; set; } // Section 2: Encryption related // Members in this section should be set for every Repo object public bool encrypted { get; set; } public string magic { get; set; } public int enc_version { get; set; } public string random_key { get; set; } // Section 3: Client only information // Should be set for all client repo objects public string _worktree; public string worktree { get { return _worktree; } set { _worktree = value; } } public string _relay_id; public string relay_id { get { return _relay_id; } set { _relay_id = value; } } public int last_sync_time { get; set; } public bool auto_sync { get; set; } public bool worktree_invalid { get; set; } // Section 4: Server only information // Should be set for all server repo objects // virutal repo related public bool is_virtual { get; set; } public string origin_repo_id { get; set; } public string origin_repo_name { get; set; } public string origin_path { get; set; } public bool is_original_owner { get; set; } public string virtual_perm { get; set; } // Used to access fs objects public string store_id { get; set; } public bool is_corrupted { get; set; } public bool repaired { get; set; } // Section 5: Share information // Only set in list_share_repos, get_group_repos and get_inner_pub_repos, etc public string share_type { get; set; } // personal, group or public public string permission { get; set; } public string user { get; set; } // share from or share to public int group_id { get; set; } // used when shared to group // For list_owned_repo public bool is_shared { get; set; } } public class TrashRepo : Object { public string repo_id { get; set; } public string repo_name { get; set; } public string head_id { get; set; } public string owner_id { get; set; } public int64 size { get; set; } public int64 del_time { get; set; } } public class SyncInfo : Object { public string repo_id { get; set; } public string head_commit { get; set; } public bool deleted_on_relay { get; set; } public bool bad_local_branch { get; set; } public bool need_fetch { get; set; } public bool need_upload { get; set; } public bool need_merge { get; set; } // public int last_sync_time { get; set; } } public class SyncTask : Object { public bool is_sync_lan { get; set; } public bool force_upload { get; set; } public string dest_id { get; set; } public string repo_id { get; set; } public string state { get; set; } public string error { get; set; } public string err_detail { get; set; } public string tx_id { get; set; } } public class SessionInfo : Object { public string datadir { get; set; } } public class CheckoutTask : Object { public string repo_id { get; set; } public string worktree { get; set; } public int total_files { get; set; } public int finished_files { get; set; } } public class DiffEntry : Object { public string status { get; set; } public string name { get; set; } public string new_name { get; set; } } public class DeletedEntry : Object { public string commit_id { get; set; } public string obj_id { get; set; } public string obj_name { get; set; } public string basedir { get; set; } public int mode { get; set; } public int delete_time { get; set; } public int64 file_size { get; set; } public string scan_stat { get; set; } } public class RepoTokenInfo: Object { public string repo_id { get; set; } public string repo_name { get; set; } public string repo_owner { get; set; } public string email { get; set; } public string token { get; set; } public string peer_id { get; set; } public string peer_ip { get; set; } public string peer_name { get; set; } public int64 sync_time { get; set; } public string client_ver { get; set; } } public class SharedUser : Object { public string repo_id { get; set; } public string user { get; set; } public string perm { get; set; } } public class SharedGroup : Object { public string repo_id { get; set; } public int group_id { get; set; } public string perm { get; set; } } public class EncryptionInfo: Object { public string repo_id { get; set; } public string passwd { get; set; } public int enc_version { get; set; } public string magic { get; set; } public string random_key { get; set; } } public class FileSyncError: Object { public string repo_id { get; set; } public string repo_name { get; set; } public string path { get; set; } public int err_id { get; set; } public int64 timestamp { get; set; } } } // namespace seafile-6.1.5/lib/rpc_table.py000066400000000000000000000112431323477647300162270ustar00rootroot00000000000000""" Define RPC functions needed to generate """ # [ , [] ] func_table = [ [ "int", [] ], [ "int", ["int"] ], [ "int", ["int", "int"] ], [ "int", ["int", "string"] ], [ "int", ["int", "string", "int"] ], [ "int", ["int", "string", "string"] ], [ "int", ["int", "string", "int", "int"] ], [ "int", ["int", "int", "string", "string"] ], [ "int", ["string"] ], [ "int", ["string", "int"] ], [ "int", ["string", "int", "int"] ], [ "int", ["string", "int", "string"] ], [ "int", ["string", "int", "string", "string"] ], [ "int", ["string", "int", "int", "string", "string"] ], [ "int", ["string", "string"] ], [ "int", ["string", "string", "string"] ], [ "int", ["string", "string", "int", "int"] ], [ "int", ["string", "string", "string", "int"] ], [ "int", ["string", "string", "string", "int", "string"] ], [ "int", ["string", "string", "string", "string"] ], [ "int", ["string", "string", "string", "string", "string"] ], [ "int", ["string", "string", "string", "string", "string", "string"] ], [ "int", ["string", "string", "string", "int", "string", "string"] ], [ "int", ["string", "string", "string", "string", "string", "string", "string"] ], [ "int", ["string", "int64"]], [ "int", ["int", "int64"]], [ "int", ["int", "string", "int64"]], [ "int64", [] ], [ "int64", ["string"] ], [ "int64", ["int"]], [ "int64", ["int", "string"]], [ "int64", ["string", "int", "string"] ], [ "string", [] ], [ "string", ["int"] ], [ "string", ["int", "int"] ], [ "string", ["int", "string"] ], [ "string", ["int", "int", "string"] ], [ "string", ["string"] ], [ "string", ["string", "int"] ], [ "string", ["string", "int", "int"] ], [ "string", ["string", "string"] ], [ "string", ["string", "string", "int"] ], [ "string", ["string", "string", "int", "int"] ], [ "string", ["string", "string", "string"] ], [ "string", ["string", "string", "string", "string"] ], [ "string", ["string", "string", "string", "string", "int"] ], [ "string", ["string", "string", "string", "string", "string"] ], [ "string", ["string", "string", "string", "string", "string", "int"] ], [ "string", ["string", "string", "string", "string", "string", "string", "int"] ], [ "string", ["string", "string", "string", "string", "string", "string", "int", "int"] ], [ "string", ["string", "string", "string", "string", "string", "string"] ], [ "string", ["string", "string", "string", "string", "string", "string", "int64"] ], [ "string", ["string", "string", "string", "string", "string", "string", "int64", "int"] ], [ "string", ["string", "string", "string", "string", "string", "string", "string"] ], [ "string", ["string", "string", "string", "string", "string", "string", "string", "int64"] ], [ "string", ["string", "string", "string", "string", "string", "string", "string", "string", "string"] ], [ "string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"] ], [ "string", ["string", "int", "string", "int", "int"] ], [ "string", ["string", "int", "string", "string", "string"] ], [ "objlist", [] ], [ "objlist", ["int"] ], [ "objlist", ["int", "int"] ], [ "objlist", ["int", "string"] ], [ "objlist", ["int", "int", "int"] ], [ "objlist", ["string"] ], [ "objlist", ["string", "int"] ], [ "objlist", ["string", "int", "int"] ], [ "objlist", ["string", "int", "string"] ], [ "objlist", ["string", "string"] ], [ "objlist", ["string", "string", "string"] ], [ "objlist", ["string", "string", "int"] ], [ "objlist", ["string", "string", "string", "int"] ], [ "objlist", ["string", "string", "int", "int"] ], [ "objlist", ["string", "string", "int", "int", "int"] ], [ "objlist", ["int", "string", "string", "int", "int"] ], [ "objlist", ["string", "int", "string", "string", "string"] ], [ "objlist", ["string", "int", "string", "int", "int"] ], [ "objlist", ["string", "int", "string", "string", "int"] ], [ "objlist", ["string", "string", "string", "string", "int", "int"] ], [ "object", [] ], [ "object", ["int"] ], [ "object", ["string"] ], [ "object", ["string", "string"] ], [ "object", ["string", "string", "string"] ], [ "object", ["string", "int", "string"] ], [ "object", ["int", "string", "string"] ], [ "object", ["string", "string", "string", "string", "string", "string", "string", "int", "int"] ], [ "object", ["string", "string", "string", "string", "string", "string", "int", "string", "int", "int"] ], ] seafile-6.1.5/lib/seafile-rpc-wrapper.c000066400000000000000000000332401323477647300177370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include #include #include #include #include #include #include #include #include "seafile-object.h" char * seafile_get_config (SearpcClient *client, const char *key) { if (!key) return NULL; return searpc_client_call__string ( client, "seafile_get_config", NULL, 1, "string", key); } int seafile_get_config_async (SearpcClient *client, const char *key, AsyncCallback callback, void *user_data) { if (!key) return -1; return searpc_client_async_call__string ( client, "seafile_get_config", callback, user_data, 1, "string", key); } int seafile_set_config (SearpcClient *client, const char *key, const char *value) { if (!key || !value) return -1; return searpc_client_call__int ( client, "seafile_set_config", NULL, 2, "string", key, "string", value); } int seafile_set_config_async (SearpcClient *client, const char *key, const char *value, AsyncCallback callback, void *user_data) { if (!key || !value) return -1; return searpc_client_async_call__int ( client, "seafile_set_config", callback, user_data, 2, "string", key, "string", value); } char * seafile_create_repo (SearpcClient *client, const gchar *name, const gchar *description, const gchar *worktree, const gchar *passwd, const gchar *relay_id, int keep_local_history, GError **error) { g_return_val_if_fail (client && name && description && worktree, NULL); return searpc_client_call__string ( client, "seafile_create_repo", error, 6, "string", name, "string", description, "string", worktree, "string", passwd, "string", relay_id, "int", keep_local_history); } int seafile_create_repo_async (SearpcClient *client, const gchar *name, const gchar *description, const gchar *worktree, const gchar *passwd, const gchar *relay_id, int keep_local_history, AsyncCallback callback, void *user_data) { g_return_val_if_fail (client && name && description && worktree, -1); return searpc_client_async_call__string ( client, "seafile_create_repo", callback, user_data, 6, "string", name, "string", description, "string", worktree, "string", passwd, "string", relay_id, "int", keep_local_history); } int seafile_destroy_repo (SearpcClient *client, const char *repo_id, GError **error) { g_return_val_if_fail (client && repo_id, -1); return searpc_client_call__int ( client, "seafile_destroy_repo", error, 1, "string", repo_id); } int seafile_set_repo_token (SearpcClient *client, const char *repo_id, const char *token, GError **error) { g_return_val_if_fail (client && repo_id && token, -1); return searpc_client_call__int ( client, "seafile_set_repo_token", error, 2, "string", repo_id, "string", token); } char * seafile_get_repo_token (SearpcClient *client, const char *repo_id, GError **error) { g_return_val_if_fail (client && repo_id, NULL); return searpc_client_call__string ( client, "seafile_get_repo_token", error, 1, "string", repo_id); } GList * seafile_get_repo_list (SearpcClient *client, int offset, int limit, GError **error) { return searpc_client_call__objlist ( client, "seafile_get_repo_list", SEAFILE_TYPE_REPO, error, 2, "int", offset, "int", limit); } GObject * seafile_get_repo (SearpcClient *client, const char *repo_id, GError **error) { g_return_val_if_fail (client && repo_id, NULL); return searpc_client_call__object ( client, "seafile_get_repo", SEAFILE_TYPE_REPO, error, 1, "string", repo_id); } int seafile_set_repo_property (SearpcClient *client, const char *repo_id, const char *key, const char *value, GError **error) { g_return_val_if_fail (client && repo_id && key, -1); return searpc_client_call__int ( client, "seafile_set_repo_property", error, 3, "string", repo_id, "string", key, "string", value); } char * seafile_get_repo_property (SearpcClient *client, const char *repo_id, const char *key, GError **error) { g_return_val_if_fail (client && repo_id, NULL); return searpc_client_call__string ( client, "seafile_get_repo_property", error, 2, "string", repo_id, "string", key); } int seafile_calc_dir_size (SearpcClient *client, const char *path, GError **error) { return searpc_client_call__int (client, "seafile_calc_dir_size", error, 1, "string", path); } int seafile_add_chunk_server (SearpcClient *client, const char *server_id, GError **error) { if (!server_id) return -1; return searpc_client_call__int ( client, "seafile_add_chunk_server", error, 1, "string", server_id); } int seafile_del_chunk_server (SearpcClient *client, const char *server_id, GError **error) { if (!server_id) return -1; return searpc_client_call__int ( client, "seafile_del_chunk_server", error, 1, "string", server_id); } char * seafile_list_chunk_servers (SearpcClient *client, GError **error) { return searpc_client_call__string ( client, "seafile_list_chunk_servers", error, 0); } char * seafile_repo_query_access_property (SearpcClient *client, const char *repo_id, GError **error) { return searpc_client_call__string ( client, "seafile_repo_query_access_property", error, 1, "string", repo_id); } GObject * seafile_web_query_access_token (SearpcClient *client, const char *token, GError **error) { return searpc_client_call__object ( client, "seafile_web_query_access_token", SEAFILE_TYPE_WEB_ACCESS, error, 1, "string", token); } GObject * seafile_get_decrypt_key (SearpcClient *client, const char *repo_id, const char *user, GError **error) { return searpc_client_call__object ( client, "seafile_get_decrypt_key", SEAFILE_TYPE_CRYPT_KEY, error, 2, "string", repo_id, "string", user); } char * seafile_put_file (SearpcClient *client, const char *repo_id, const char *file_path, const char *parent_dir, const char *file_name, const char *user, const char *head_id, GError **error) { return searpc_client_call__string (client, "seafile_put_file", error, 6, "string", repo_id, "string", file_path, "string", parent_dir, "string", file_name, "string", user, "string", head_id); } char * seafile_put_file_blocks (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, const char *head_id, gint64 file_size, GError **error) { return searpc_client_call__string (client, "seafile_put_file_blocks", error, 8, "string", repo_id, "string", parent_dir, "string", file_name, "string", blockids_json, "string", paths_json, "string", user, "string", head_id, "int64", &file_size); } int seafile_post_file (SearpcClient *client, const char *repo_id, const char *file_path, const char *parent_dir, const char *file_name, const char *user, GError **error) { return searpc_client_call__int (client, "seafile_post_file", error, 5, "string", repo_id, "string", file_path, "string", parent_dir, "string", file_name, "string", user); } char * seafile_post_file_blocks (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *file_name, const char *blockids_json, const char *paths_json, const char *user, gint64 file_size, int replace_existed, GError **error) { return searpc_client_call__string (client, "seafile_post_file_blocks", error, 8, "string", repo_id, "string", parent_dir, "string", file_name, "string", blockids_json, "string", paths_json, "string", user, "int64", &file_size, "int", replace_existed); } char * seafile_post_multi_files (SearpcClient *client, const char *repo_id, const char *parent_dir, const char *filenames_json, const char *paths_json, const char *user, int replace_existed, GError **error) { return searpc_client_call__string (client, "seafile_post_multi_files", error, 6, "string", repo_id, "string", parent_dir, "string", filenames_json, "string", paths_json, "string", user, "int", replace_existed); } int seafile_set_user_quota (SearpcClient *client, const char *user, gint64 quota, GError **error) { return searpc_client_call__int (client, "set_user_quota", error, 2, "string", user, "int64", "a); } int seafile_set_org_quota (SearpcClient *client, int org_id, gint64 quota, GError **error) { return searpc_client_call__int (client, "set_org_quota", error, 2, "int", org_id, "int64", "a); } int seafile_set_org_user_quota (SearpcClient *client, int org_id, const char *user, gint64 quota, GError **error) { return searpc_client_call__int (client, "set_org_user_quota", error, 3, "int", org_id, "string", user, "int64", "a); } int seafile_check_quota (SearpcClient *client, const char *repo_id, GError **error) { return searpc_client_call__int (client, "check_quota", error, 1, "string", repo_id); } int seafile_disable_auto_sync_async (SearpcClient *client, AsyncCallback callback, void *user_data) { return searpc_client_async_call__int (client, "seafile_disable_auto_sync", callback, user_data, 0); } int seafile_enable_auto_sync_async (SearpcClient *client, AsyncCallback callback, void *user_data) { return searpc_client_async_call__int (client, "seafile_enable_auto_sync", callback, user_data, 0); } int seafile_is_auto_sync_enabled_async (SearpcClient *client, AsyncCallback callback, void *user_data) { return searpc_client_async_call__int (client, "seafile_is_auto_sync_enabled", callback, user_data, 0); } seafile-6.1.5/lib/task.vala000066400000000000000000000025731323477647300155370ustar00rootroot00000000000000namespace Seafile { public class Task : Object { public char _tx_id[37]; public string tx_id { get { return (string)_tx_id; } set { Posix.memcpy(_tx_id, value, 36); _tx_id[36] = '\0'; } } public string ttype { get; set; } public string repo_id { get; set; } public string dest_id { get; set; } public string from_branch { get; set; } public string to_branch { get; set; } public string state { get; set; } public string rt_state { get; set; } public string error_str { get; set; } public int64 block_total { get; set; } public int64 block_done { get; set; } // the number of blocks sent or received public int fs_objects_total { get; set; } public int fs_objects_done { get; set; } public int rate { get; set; } public int64 _rsize; // the size remain public int64 rsize{ get { return _rsize; } set { _rsize = value; } } public int64 _dsize; // the size has done public int64 dsize { get { return _dsize; } set { _dsize = value; } } } public class CloneTask : Object { public string state { get; set; } public string error_str { get; set; } public string err_detail { get; set; } public string repo_id { get; set; } public string peer_id { get; set; } public string repo_name { get; set; } public string worktree { get; set; } public string tx_id { get; set; } } } // namespace seafile-6.1.5/lib/utils.c000066400000000000000000001522121323477647300152300ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include #include "common.h" #ifdef WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #endif #include "utils.h" #ifdef WIN32 #include #include #include #include #include #include #else #include #endif #ifndef WIN32 #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern int inet_pton(int af, const char *src, void *dst); struct timeval timeval_from_msec (uint64_t milliseconds) { struct timeval ret; const uint64_t microseconds = milliseconds * 1000; ret.tv_sec = microseconds / 1000000; ret.tv_usec = microseconds % 1000000; return ret; } void rawdata_to_hex (const unsigned char *rawdata, char *hex_str, int n_bytes) { static const char hex[] = "0123456789abcdef"; int i; for (i = 0; i < n_bytes; i++) { unsigned int val = *rawdata++; *hex_str++ = hex[val >> 4]; *hex_str++ = hex[val & 0xf]; } *hex_str = '\0'; } static unsigned hexval(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return c - 'a' + 10; if (c >= 'A' && c <= 'F') return c - 'A' + 10; return ~0; } int hex_to_rawdata (const char *hex_str, unsigned char *rawdata, int n_bytes) { int i; for (i = 0; i < n_bytes; i++) { unsigned int val = (hexval(hex_str[0]) << 4) | hexval(hex_str[1]); if (val & ~0xff) return -1; *rawdata++ = val; hex_str += 2; } return 0; } size_t ccnet_strlcpy (char *dest, const char *src, size_t size) { size_t ret = strlen(src); if (size) { size_t len = (ret >= size) ? size - 1 : ret; memcpy(dest, src, len); dest[len] = '\0'; } return ret; } int checkdir (const char *dir) { SeafStat st; #ifdef WIN32 /* remove trailing '\\' */ char *path = g_strdup(dir); char *p = (char *)path + strlen(path) - 1; while (*p == '\\' || *p == '/') *p-- = '\0'; if ((seaf_stat(dir, &st) < 0) || !S_ISDIR(st.st_mode)) { g_free (path); return -1; } g_free (path); return 0; #else if ((seaf_stat(dir, &st) < 0) || !S_ISDIR(st.st_mode)) return -1; return 0; #endif } int checkdir_with_mkdir (const char *dir) { #ifdef WIN32 int ret; char *path = g_strdup(dir); char *p = (char *)path + strlen(path) - 1; while (*p == '\\' || *p == '/') *p-- = '\0'; ret = g_mkdir_with_parents(path, 0755); g_free (path); return ret; #else return g_mkdir_with_parents(dir, 0755); #endif } int objstore_mkdir (const char *base) { int ret; int i, j, len; static const char hex[] = "0123456789abcdef"; char subdir[SEAF_PATH_MAX]; if ( (ret = checkdir_with_mkdir(base)) < 0) return ret; len = strlen(base); memcpy(subdir, base, len); subdir[len] = G_DIR_SEPARATOR; subdir[len+3] = '\0'; for (i = 0; i < 16; i++) { subdir[len+1] = hex[i]; for (j = 0; j < 16; j++) { subdir[len+2] = hex[j]; if ( (ret = checkdir_with_mkdir(subdir)) < 0) return ret; } } return 0; } void objstore_get_path (char *path, const char *base, const char *obj_id) { int len; len = strlen(base); memcpy(path, base, len); path[len] = G_DIR_SEPARATOR; path[len+1] = obj_id[0]; path[len+2] = obj_id[1]; path[len+3] = G_DIR_SEPARATOR; strcpy(path+len+4, obj_id+2); } #ifdef WIN32 /* UNIX epoch expressed in Windows time, the unit is 100 nanoseconds. * See http://msdn.microsoft.com/en-us/library/ms724228 */ #define UNIX_EPOCH 116444736000000000ULL __time64_t file_time_to_unix_time (FILETIME *ftime) { guint64 win_time, unix_time; win_time = (guint64)ftime->dwLowDateTime + (((guint64)ftime->dwHighDateTime)<<32); unix_time = (win_time - UNIX_EPOCH)/10000000; return (__time64_t)unix_time; } static int get_utc_file_time_fd (int fd, __time64_t *mtime, __time64_t *ctime) { HANDLE handle; FILETIME write_time, create_time; handle = (HANDLE)_get_osfhandle (fd); if (handle == INVALID_HANDLE_VALUE) { g_warning ("Failed to get handle from fd: %lu.\n", GetLastError()); return -1; } if (!GetFileTime (handle, &create_time, NULL, &write_time)) { g_warning ("Failed to get file time: %lu.\n", GetLastError()); return -1; } *mtime = file_time_to_unix_time (&write_time); *ctime = file_time_to_unix_time (&create_time); return 0; } #define EPOCH_DIFF 11644473600ULL inline static void unix_time_to_file_time (guint64 unix_time, FILETIME *ftime) { guint64 win_time; win_time = (unix_time + EPOCH_DIFF) * 10000000; ftime->dwLowDateTime = win_time & 0xFFFFFFFF; ftime->dwHighDateTime = (win_time >> 32) & 0xFFFFFFFF; } static int set_utc_file_time (const char *path, const wchar_t *wpath, guint64 mtime) { HANDLE handle; FILETIME write_time; handle = CreateFileW (wpath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (handle == INVALID_HANDLE_VALUE) { g_warning ("Failed to open %s: %lu.\n", path, GetLastError()); return -1; } unix_time_to_file_time (mtime, &write_time); if (!SetFileTime (handle, NULL, NULL, &write_time)) { g_warning ("Failed to set file time for %s: %lu.\n", path, GetLastError()); CloseHandle (handle); return -1; } CloseHandle (handle); return 0; } wchar_t * win32_long_path (const char *path) { char *long_path, *p; wchar_t *long_path_w; if (strncmp(path, "//", 2) == 0) long_path = g_strconcat ("\\\\?\\UNC\\", path + 2, NULL); else long_path = g_strconcat ("\\\\?\\", path, NULL); for (p = long_path; *p != 0; ++p) if (*p == '/') *p = '\\'; long_path_w = g_utf8_to_utf16 (long_path, -1, NULL, NULL, NULL); g_free (long_path); return long_path_w; } /* Convert a (possible) 8.3 format path to long path */ wchar_t * win32_83_path_to_long_path (const char *worktree, const wchar_t *path, int path_len) { wchar_t *worktree_w = g_utf8_to_utf16 (worktree, -1, NULL, NULL, NULL); int wt_len; wchar_t *p; wchar_t *fullpath_w = NULL; wchar_t *fullpath_long = NULL; wchar_t *ret = NULL; char *fullpath; for (p = worktree_w; *p != L'\0'; ++p) if (*p == L'/') *p = L'\\'; wt_len = wcslen(worktree_w); fullpath_w = g_new0 (wchar_t, wt_len + path_len + 6); wcscpy (fullpath_w, L"\\\\?\\"); wcscat (fullpath_w, worktree_w); wcscat (fullpath_w, L"\\"); wcsncat (fullpath_w, path, path_len); fullpath_long = g_new0 (wchar_t, SEAF_PATH_MAX); DWORD n = GetLongPathNameW (fullpath_w, fullpath_long, SEAF_PATH_MAX); if (n == 0) { /* Failed. */ fullpath = g_utf16_to_utf8 (fullpath_w, -1, NULL, NULL, NULL); g_free (fullpath); goto out; } else if (n > SEAF_PATH_MAX) { /* In this case n is the necessary length for the buf. */ g_free (fullpath_long); fullpath_long = g_new0 (wchar_t, n); if (GetLongPathNameW (fullpath_w, fullpath_long, n) != (n - 1)) { fullpath = g_utf16_to_utf8 (fullpath_w, -1, NULL, NULL, NULL); g_free (fullpath); goto out; } } /* Remove "\\?\worktree\" from the beginning. */ ret = wcsdup (fullpath_long + wt_len + 5); out: g_free (worktree_w); g_free (fullpath_w); g_free (fullpath_long); return ret; } static int windows_error_to_errno (DWORD error) { switch (error) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: return ENOENT; case ERROR_ALREADY_EXISTS: return EEXIST; case ERROR_ACCESS_DENIED: case ERROR_SHARING_VIOLATION: return EACCES; case ERROR_DIR_NOT_EMPTY: return ENOTEMPTY; default: return 0; } } #endif int seaf_stat (const char *path, SeafStat *st) { #ifdef WIN32 wchar_t *wpath = win32_long_path (path); WIN32_FILE_ATTRIBUTE_DATA attrs; int ret = 0; if (!GetFileAttributesExW (wpath, GetFileExInfoStandard, &attrs)) { ret = -1; errno = windows_error_to_errno (GetLastError()); goto out; } memset (st, 0, sizeof(SeafStat)); if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) st->st_mode = (S_IFDIR | S_IRWXU); else st->st_mode = (S_IFREG | S_IRUSR | S_IWUSR); st->st_atime = file_time_to_unix_time (&attrs.ftLastAccessTime); st->st_ctime = file_time_to_unix_time (&attrs.ftCreationTime); st->st_mtime = file_time_to_unix_time (&attrs.ftLastWriteTime); st->st_size = ((((__int64)attrs.nFileSizeHigh)<<32) + attrs.nFileSizeLow); out: g_free (wpath); return ret; #else return stat (path, st); #endif } int seaf_fstat (int fd, SeafStat *st) { #ifdef WIN32 if (_fstat64 (fd, st) < 0) return -1; if (get_utc_file_time_fd (fd, &st->st_mtime, &st->st_ctime) < 0) return -1; return 0; #else return fstat (fd, st); #endif } #ifdef WIN32 void seaf_stat_from_find_data (WIN32_FIND_DATAW *fdata, SeafStat *st) { memset (st, 0, sizeof(SeafStat)); if (fdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) st->st_mode = (S_IFDIR | S_IRWXU); else st->st_mode = (S_IFREG | S_IRUSR | S_IWUSR); st->st_atime = file_time_to_unix_time (&fdata->ftLastAccessTime); st->st_ctime = file_time_to_unix_time (&fdata->ftCreationTime); st->st_mtime = file_time_to_unix_time (&fdata->ftLastWriteTime); st->st_size = ((((__int64)fdata->nFileSizeHigh)<<32) + fdata->nFileSizeLow); } #endif int seaf_set_file_time (const char *path, guint64 mtime) { #ifndef WIN32 struct stat st; struct utimbuf times; if (stat (path, &st) < 0) { g_warning ("Failed to stat %s: %s.\n", path, strerror(errno)); return -1; } times.actime = st.st_atime; times.modtime = (time_t)mtime; return utime (path, ×); #else wchar_t *wpath = win32_long_path (path); int ret = 0; if (set_utc_file_time (path, wpath, mtime) < 0) ret = -1; g_free (wpath); return ret; #endif } int seaf_util_unlink (const char *path) { #ifdef WIN32 wchar_t *wpath = win32_long_path (path); int ret = 0; if (!DeleteFileW (wpath)) { ret = -1; errno = windows_error_to_errno (GetLastError()); } g_free (wpath); return ret; #else return unlink (path); #endif } int seaf_util_rmdir (const char *path) { #ifdef WIN32 wchar_t *wpath = win32_long_path (path); int ret = 0; if (!RemoveDirectoryW (wpath)) { ret = -1; errno = windows_error_to_errno (GetLastError()); } g_free (wpath); return ret; #else return rmdir (path); #endif } int seaf_util_mkdir (const char *path, mode_t mode) { #ifdef WIN32 wchar_t *wpath = win32_long_path (path); int ret = 0; if (!CreateDirectoryW (wpath, NULL)) { ret = -1; errno = windows_error_to_errno (GetLastError()); } g_free (wpath); return ret; #else return mkdir (path, mode); #endif } int seaf_util_open (const char *path, int flags) { #ifdef WIN32 wchar_t *wpath; DWORD access = 0; HANDLE handle; int fd; access |= GENERIC_READ; if (flags & (O_WRONLY | O_RDWR)) access |= GENERIC_WRITE; wpath = win32_long_path (path); handle = CreateFileW (wpath, access, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (handle == INVALID_HANDLE_VALUE) { errno = windows_error_to_errno (GetLastError()); g_free (wpath); return -1; } fd = _open_osfhandle ((intptr_t)handle, 0); g_free (wpath); return fd; #else return open (path, flags); #endif } int seaf_util_create (const char *path, int flags, mode_t mode) { #ifdef WIN32 wchar_t *wpath; DWORD access = 0; HANDLE handle; int fd; access |= GENERIC_READ; if (flags & (O_WRONLY | O_RDWR)) access |= GENERIC_WRITE; wpath = win32_long_path (path); handle = CreateFileW (wpath, access, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); if (handle == INVALID_HANDLE_VALUE) { errno = windows_error_to_errno (GetLastError()); g_free (wpath); return -1; } fd = _open_osfhandle ((intptr_t)handle, 0); g_free (wpath); return fd; #else return open (path, flags, mode); #endif } int seaf_util_rename (const char *oldpath, const char *newpath) { #ifdef WIN32 wchar_t *oldpathw = win32_long_path (oldpath); wchar_t *newpathw = win32_long_path (newpath); int ret = 0; if (!MoveFileExW (oldpathw, newpathw, MOVEFILE_REPLACE_EXISTING)) { ret = -1; errno = windows_error_to_errno (GetLastError()); } g_free (oldpathw); g_free (newpathw); return ret; #else return rename (oldpath, newpath); #endif } gboolean seaf_util_exists (const char *path) { #ifdef WIN32 wchar_t *wpath = win32_long_path (path); DWORD attrs; gboolean ret; attrs = GetFileAttributesW (wpath); ret = (attrs != INVALID_FILE_ATTRIBUTES); g_free (wpath); return ret; #else return (access (path, F_OK) == 0); #endif } gint64 seaf_util_lseek (int fd, gint64 offset, int whence) { #ifdef WIN32 return _lseeki64 (fd, offset, whence); #else return lseek (fd, offset, whence); #endif } #ifdef WIN32 int traverse_directory_win32 (wchar_t *path_w, DirentCallback callback, void *user_data) { WIN32_FIND_DATAW fdata; HANDLE handle; wchar_t *pattern; char *path; int path_len_w; DWORD error; gboolean stop; int ret = 0; path = g_utf16_to_utf8 (path_w, -1, NULL, NULL, NULL); path_len_w = wcslen(path_w); pattern = g_new0 (wchar_t, (path_len_w + 3)); wcscpy (pattern, path_w); wcscat (pattern, L"\\*"); handle = FindFirstFileW (pattern, &fdata); if (handle == INVALID_HANDLE_VALUE) { g_warning ("FindFirstFile failed %s: %lu.\n", path, GetLastError()); ret = -1; goto out; } do { if (wcscmp (fdata.cFileName, L".") == 0 || wcscmp (fdata.cFileName, L"..") == 0) continue; ++ret; stop = FALSE; if (callback (path_w, &fdata, user_data, &stop) < 0) { ret = -1; FindClose (handle); goto out; } if (stop) { FindClose (handle); goto out; } } while (FindNextFileW (handle, &fdata) != 0); error = GetLastError(); if (error != ERROR_NO_MORE_FILES) { g_warning ("FindNextFile failed %s: %lu.\n", path, error); ret = -1; } FindClose (handle); out: g_free (path); g_free (pattern); return ret; } #endif #ifdef WIN32 static inline gboolean has_trailing_space_or_period (const char *path) { int len = strlen(path); if (path[len - 1] == ' ' || path[len - 1] == '.') { return TRUE; } return FALSE; } #endif gboolean should_ignore_on_checkout (const char *file_path, IgnoreReason *ignore_reason) { gboolean ret = FALSE; #ifdef WIN32 static char illegals[] = {'\\', ':', '*', '?', '"', '<', '>', '|', '\b', '\t'}; char **components = g_strsplit (file_path, "/", -1); int n_comps = g_strv_length (components); int j = 0; char *file_name; int i; char c; for (; j < n_comps; ++j) { file_name = components[j]; if (has_trailing_space_or_period (file_name)) { /* Ignore files/dir whose path has trailing spaces. It would cause * problem on windows. */ /* g_debug ("ignore '%s' which contains trailing space in path\n", path); */ ret = TRUE; if (ignore_reason) *ignore_reason = IGNORE_REASON_END_SPACE_PERIOD; goto out; } for (i = 0; i < G_N_ELEMENTS(illegals); i++) { if (strchr (file_name, illegals[i])) { ret = TRUE; if (ignore_reason) *ignore_reason = IGNORE_REASON_INVALID_CHARACTER; goto out; } } for (c = 1; c <= 31; c++) { if (strchr (file_name, c)) { ret = TRUE; if (ignore_reason) *ignore_reason = IGNORE_REASON_INVALID_CHARACTER; goto out; } } } out: g_strfreev (components); #endif return ret; } ssize_t /* Read "n" bytes from a descriptor. */ readn(int fd, void *vptr, size_t n) { size_t nleft; ssize_t nread; char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { if ( (nread = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) nread = 0; /* and call read() again */ else return(-1); } else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return(n - nleft); /* return >= 0 */ } ssize_t /* Write "n" bytes to a descriptor. */ writen(int fd, const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { if ( (nwritten = write(fd, ptr, nleft)) <= 0) { if (nwritten < 0 && errno == EINTR) nwritten = 0; /* and call write() again */ else return(-1); /* error */ } nleft -= nwritten; ptr += nwritten; } return(n); } ssize_t /* Read "n" bytes from a descriptor. */ recvn(evutil_socket_t fd, void *vptr, size_t n) { size_t nleft; ssize_t nread; char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { #ifndef WIN32 if ( (nread = read(fd, ptr, nleft)) < 0) #else if ( (nread = recv(fd, ptr, nleft, 0)) < 0) #endif { if (errno == EINTR) nread = 0; /* and call read() again */ else return(-1); } else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return(n - nleft); /* return >= 0 */ } ssize_t /* Write "n" bytes to a descriptor. */ sendn(evutil_socket_t fd, const void *vptr, size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = vptr; nleft = n; while (nleft > 0) { #ifndef WIN32 if ( (nwritten = write(fd, ptr, nleft)) <= 0) #else if ( (nwritten = send(fd, ptr, nleft, 0)) <= 0) #endif { if (nwritten < 0 && errno == EINTR) nwritten = 0; /* and call write() again */ else return(-1); /* error */ } nleft -= nwritten; ptr += nwritten; } return(n); } int copy_fd (int ifd, int ofd) { while (1) { char buffer[8192]; ssize_t len = readn (ifd, buffer, sizeof(buffer)); if (!len) break; if (len < 0) { close (ifd); return -1; } if (writen (ofd, buffer, len) < 0) { close (ofd); return -1; } } close(ifd); return 0; } int copy_file (const char *dst, const char *src, int mode) { int fdi, fdo, status; if ((fdi = g_open (src, O_RDONLY | O_BINARY, 0)) < 0) return fdi; fdo = g_open (dst, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, mode); if (fdo < 0 && errno == EEXIST) { close (fdi); return 0; } else if (fdo < 0){ close (fdi); return -1; } status = copy_fd (fdi, fdo); if (close (fdo) != 0) return -1; return status; } char* ccnet_expand_path (const char *src) { #ifdef WIN32 char new_path[SEAF_PATH_MAX + 1]; char *p = new_path; const char *q = src; memset(new_path, 0, sizeof(new_path)); if (*src == '~') { const char *home = g_get_home_dir(); memcpy(new_path, home, strlen(home)); p += strlen(new_path); q++; } memcpy(p, q, strlen(q)); /* delete the charactor '\' or '/' at the end of the path * because the function stat faied to deal with directory names * with '\' or '/' in the end */ p = new_path + strlen(new_path) - 1; while(*p == '\\' || *p == '/') *p-- = '\0'; return strdup (new_path); #else const char *next_in, *ntoken; char new_path[SEAF_PATH_MAX + 1]; char *next_out; int len; /* special cases */ if (!src || *src == '\0') return NULL; if (strlen(src) > SEAF_PATH_MAX) return NULL; next_in = src; next_out = new_path; *next_out = '\0'; if (*src == '~') { /* handle src start with '~' or '~' like '~plt' */ struct passwd *pw = NULL; for ( ; *next_in != '/' && *next_in != '\0'; next_in++) ; len = next_in - src; if (len == 1) { pw = getpwuid (geteuid()); } else { /* copy '~' to new_path */ memcpy (new_path, src, len); new_path[len] = '\0'; pw = getpwnam (new_path + 1); } if (pw == NULL) return NULL; len = strlen (pw->pw_dir); memcpy (new_path, pw->pw_dir, len); next_out = new_path + len; *next_out = '\0'; if (*next_in == '\0') return strdup (new_path); } else if (*src != '/') { getcwd (new_path, SEAF_PATH_MAX); for ( ; *next_out; next_out++) ; /* to '\0' */ } while (*next_in != '\0') { /* move ntoken to the next not '/' char */ for (ntoken = next_in; *ntoken == '/'; ntoken++) ; for (next_in = ntoken; *next_in != '/' && *next_in != '\0'; next_in++) ; len = next_in - ntoken; if (len == 0) { /* the path ends with '/', keep it */ *next_out++ = '/'; *next_out = '\0'; break; } if (len == 2 && ntoken[0] == '.' && ntoken[1] == '.') { /* '..' */ for (; next_out > new_path && *next_out != '/'; next_out--) ; *next_out = '\0'; } else if (ntoken[0] != '.' || len != 1) { /* not '.' */ *next_out++ = '/'; memcpy (next_out, ntoken, len); next_out += len; *next_out = '\0'; } } /* the final special case */ if (new_path[0] == '\0') { new_path[0] = '/'; new_path[1] = '\0'; } return strdup (new_path); #endif } int calculate_sha1 (unsigned char *sha1, const char *msg, int len) { GChecksum *c; gsize cs_len = 20; if (len < 0) len = strlen(msg); c = g_checksum_new (G_CHECKSUM_SHA1); g_checksum_update(c, (const unsigned char *)msg, len); g_checksum_get_digest (c, sha1, &cs_len); g_checksum_free (c); return 0; } uint32_t ccnet_sha1_hash (const void *v) { /* 31 bit hash function */ const unsigned char *p = v; uint32_t h = 0; int i; for (i = 0; i < 20; i++) h = (h << 5) - h + p[i]; return h; } int ccnet_sha1_equal (const void *v1, const void *v2) { const unsigned char *p1 = v1; const unsigned char *p2 = v2; int i; for (i = 0; i < 20; i++) if (p1[i] != p2[i]) return 0; return 1; } #ifndef WIN32 char* gen_uuid () { char *uuid_str = g_malloc (37); uuid_t uuid; uuid_generate (uuid); uuid_unparse_lower (uuid, uuid_str); return uuid_str; } void gen_uuid_inplace (char *buf) { uuid_t uuid; uuid_generate (uuid); uuid_unparse_lower (uuid, buf); } gboolean is_uuid_valid (const char *uuid_str) { uuid_t uuid; if (!uuid_str) return FALSE; if (uuid_parse (uuid_str, uuid) < 0) return FALSE; return TRUE; } #else char* gen_uuid () { char *uuid_str = g_malloc (37); unsigned char *str = NULL; UUID uuid; UuidCreate(&uuid); UuidToString(&uuid, &str); memcpy(uuid_str, str, 37); RpcStringFree(&str); return uuid_str; } void gen_uuid_inplace (char *buf) { unsigned char *str = NULL; UUID uuid; UuidCreate(&uuid); UuidToString(&uuid, &str); memcpy(buf, str, 37); RpcStringFree(&str); } gboolean is_uuid_valid (const char *uuid_str) { if (!uuid_str) return FALSE; UUID uuid; if (UuidFromString((unsigned char *)uuid_str, &uuid) != RPC_S_OK) return FALSE; return TRUE; } #endif gboolean is_object_id_valid (const char *obj_id) { if (!obj_id) return FALSE; int len = strlen(obj_id); int i; char c; if (len != 40) return FALSE; for (i = 0; i < len; ++i) { c = obj_id[i]; if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) continue; return FALSE; } return TRUE; } char** strsplit_by_space (char *string, int *length) { char *remainder, *s; int size = 8, num = 0, done = 0; char **array; if (string == NULL || string[0] == '\0') { if (length != NULL) { *length = 0; } return NULL; } array = malloc (sizeof(char *) * size); if (array == NULL) { return NULL; } remainder = string; while (!done) { for (s = remainder; *s != ' ' && *s != '\0'; ++s) ; if (*s == '\0') done = 1; else *s = '\0'; array[num++] = remainder; if (!done && num == size) { size <<= 1; char** tmp = realloc (array, sizeof(char *) * size); if (tmp == NULL) { free(array); return NULL; } array = tmp; } remainder = s + 1; } if (length != NULL) { *length = num; } return array; } char** strsplit_by_char (char *string, int *length, char c) { char *remainder, *s; int size = 8, num = 0, done = 0; char **array; if (string == NULL || string[0] == '\0') { *length = 0; return NULL; } array = malloc (sizeof(char *) * size); if (array == NULL) { return NULL; } remainder = string; while (!done) { for (s = remainder; *s != c && *s != '\0'; ++s) ; if (*s == '\0') done = 1; else *s = '\0'; array[num++] = remainder; if (!done && num == size) { size <<= 1; char** tmp = realloc (array, sizeof(char *) * size); if (tmp == NULL) { free(array); return NULL; } array = tmp; } remainder = s + 1; } if (length != NULL) { *length = num; } return array; } char* strjoin_n (const char *seperator, int argc, char **argv) { GString *buf; int i; char *str; if (argc == 0) return NULL; buf = g_string_new (argv[0]); for (i = 1; i < argc; ++i) { g_string_append (buf, seperator); g_string_append (buf, argv[i]); } str = buf->str; g_string_free (buf, FALSE); return str; } gboolean is_ipaddr_valid (const char *ip) { unsigned char buf[sizeof(struct in6_addr)]; if (evutil_inet_pton(AF_INET, ip, buf) == 1) return TRUE; if (evutil_inet_pton(AF_INET6, ip, buf) == 1) return TRUE; return FALSE; } void parse_key_value_pairs (char *string, KeyValueFunc func, void *data) { char *line = string, *next, *space; char *key, *value; while (*line) { /* handle empty line */ if (*line == '\n') { ++line; continue; } for (next = line; *next != '\n' && *next; ++next) ; *next = '\0'; for (space = line; space < next && *space != ' '; ++space) ; if (*space != ' ') { g_warning ("Bad key value format: %s\n", line); return; } *space = '\0'; key = line; value = space + 1; func (data, key, value); line = next + 1; } } void parse_key_value_pairs2 (char *string, KeyValueFunc2 func, void *data) { char *line = string, *next, *space; char *key, *value; while (*line) { /* handle empty line */ if (*line == '\n') { ++line; continue; } for (next = line; *next != '\n' && *next; ++next) ; *next = '\0'; for (space = line; space < next && *space != ' '; ++space) ; if (*space != ' ') { g_warning ("Bad key value format: %s\n", line); return; } *space = '\0'; key = line; value = space + 1; if (func(data, key, value) == FALSE) break; line = next + 1; } } /** * handle the empty string problem. */ gchar* ccnet_key_file_get_string (GKeyFile *keyf, const char *category, const char *key) { gchar *v; if (!g_key_file_has_key (keyf, category, key, NULL)) return NULL; v = g_key_file_get_string (keyf, category, key, NULL); if (v != NULL && v[0] == '\0') { g_free(v); return NULL; } return v; } /** * string_list_is_exists: * @str_list: * @string: a C string or %NULL * * Check whether @string is in @str_list. * * returns: %TRUE if @string is in str_list, %FALSE otherwise */ gboolean string_list_is_exists (GList *str_list, const char *string) { GList *ptr; for (ptr = str_list; ptr; ptr = ptr->next) { if (g_strcmp0(string, ptr->data) == 0) return TRUE; } return FALSE; } /** * string_list_append: * @str_list: * @string: a C string (can't be %NULL * * Append @string to @str_list if it is in the list. * * returns: the new start of the list */ GList* string_list_append (GList *str_list, const char *string) { g_return_val_if_fail (string != NULL, str_list); if (string_list_is_exists(str_list, string)) return str_list; str_list = g_list_append (str_list, g_strdup(string)); return str_list; } GList * string_list_append_sorted (GList *str_list, const char *string) { g_return_val_if_fail (string != NULL, str_list); if (string_list_is_exists(str_list, string)) return str_list; str_list = g_list_insert_sorted_with_data (str_list, g_strdup(string), (GCompareDataFunc)g_strcmp0, NULL); return str_list; } GList * string_list_remove (GList *str_list, const char *string) { g_return_val_if_fail (string != NULL, str_list); GList *ptr; for (ptr = str_list; ptr; ptr = ptr->next) { if (strcmp((char *)ptr->data, string) == 0) { g_free (ptr->data); return g_list_delete_link (str_list, ptr); } } return str_list; } void string_list_free (GList *str_list) { GList *ptr = str_list; while (ptr) { g_free (ptr->data); ptr = ptr->next; } g_list_free (str_list); } void string_list_join (GList *str_list, GString *str, const char *seperator) { GList *ptr; if (!str_list) return; ptr = str_list; g_string_append (str, ptr->data); for (ptr = ptr->next; ptr; ptr = ptr->next) { g_string_append (str, seperator); g_string_append (str, (char *)ptr->data); } } GList * string_list_parse (const char *list_in_str, const char *seperator) { if (!list_in_str) return NULL; GList *list = NULL; char **array = g_strsplit (list_in_str, seperator, 0); char **ptr; for (ptr = array; *ptr; ptr++) { list = g_list_prepend (list, g_strdup(*ptr)); } list = g_list_reverse (list); g_strfreev (array); return list; } GList * string_list_parse_sorted (const char *list_in_str, const char *seperator) { GList *list = string_list_parse (list_in_str, seperator); return g_list_sort (list, (GCompareFunc)g_strcmp0); } gboolean string_list_sorted_is_equal (GList *list1, GList *list2) { GList *ptr1 = list1, *ptr2 = list2; while (ptr1 && ptr2) { if (g_strcmp0(ptr1->data, ptr2->data) != 0) break; ptr1 = ptr1->next; ptr2 = ptr2->next; } if (!ptr1 && !ptr2) return TRUE; return FALSE; } char ** ncopy_string_array (char **orig, int n) { char **ret = g_malloc (sizeof(char *) * n); int i = 0; for (; i < n; i++) ret[i] = g_strdup(orig[i]); return ret; } void nfree_string_array (char **array, int n) { int i = 0; for (; i < n; i++) g_free (array[i]); g_free (array); } gint64 get_current_time() { GTimeVal tv; gint64 t; g_get_current_time (&tv); t = tv.tv_sec * (gint64)1000000 + tv.tv_usec; return t; } #ifdef WIN32 static SOCKET pg_serv_sock = INVALID_SOCKET; static struct sockaddr_in pg_serv_addr; /* pgpipe() should only be called in the main loop, * since it accesses the static global socket. */ int pgpipe (ccnet_pipe_t handles[2]) { int len = sizeof( pg_serv_addr ); handles[0] = handles[1] = INVALID_SOCKET; if (pg_serv_sock == INVALID_SOCKET) { if ((pg_serv_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { g_warning("pgpipe failed to create socket: %d\n", WSAGetLastError()); return -1; } memset(&pg_serv_addr, 0, sizeof(pg_serv_addr)); pg_serv_addr.sin_family = AF_INET; pg_serv_addr.sin_port = htons(0); pg_serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(pg_serv_sock, (SOCKADDR *)&pg_serv_addr, len) == SOCKET_ERROR) { g_warning("pgpipe failed to bind: %d\n", WSAGetLastError()); closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } if (listen(pg_serv_sock, SOMAXCONN) == SOCKET_ERROR) { g_warning("pgpipe failed to listen: %d\n", WSAGetLastError()); closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } struct sockaddr_in tmp_addr; int tmp_len = sizeof(tmp_addr); if (getsockname(pg_serv_sock, (SOCKADDR *)&tmp_addr, &tmp_len) == SOCKET_ERROR) { g_warning("pgpipe failed to getsockname: %d\n", WSAGetLastError()); closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } pg_serv_addr.sin_port = tmp_addr.sin_port; } if ((handles[1] = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { g_warning("pgpipe failed to create socket 2: %d\n", WSAGetLastError()); closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } if (connect(handles[1], (SOCKADDR *)&pg_serv_addr, len) == SOCKET_ERROR) { g_warning("pgpipe failed to connect socket: %d\n", WSAGetLastError()); closesocket(handles[1]); handles[1] = INVALID_SOCKET; closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } struct sockaddr_in client_addr; int client_len = sizeof(client_addr); if ((handles[0] = accept(pg_serv_sock, (SOCKADDR *)&client_addr, &client_len)) == INVALID_SOCKET) { g_warning("pgpipe failed to accept socket: %d\n", WSAGetLastError()); closesocket(handles[1]); handles[1] = INVALID_SOCKET; closesocket(pg_serv_sock); pg_serv_sock = INVALID_SOCKET; return -1; } return 0; } #endif /* convert locale specific input to utf8 encoded string */ char *ccnet_locale_to_utf8 (const gchar *src) { if (!src) return NULL; gsize bytes_read = 0; gsize bytes_written = 0; GError *error = NULL; gchar *dst = NULL; dst = g_locale_to_utf8 (src, /* locale specific string */ strlen(src), /* len of src */ &bytes_read, /* length processed */ &bytes_written, /* output length */ &error); if (error) { return NULL; } return dst; } /* convert utf8 input to locale specific string */ char *ccnet_locale_from_utf8 (const gchar *src) { if (!src) return NULL; gsize bytes_read = 0; gsize bytes_written = 0; GError *error = NULL; gchar *dst = NULL; dst = g_locale_from_utf8 (src, /* locale specific string */ strlen(src), /* len of src */ &bytes_read, /* length processed */ &bytes_written, /* output length */ &error); if (error) { return NULL; } return dst; } #ifdef WIN32 static HANDLE get_process_handle (const char *process_name_in) { char name[256]; if (strstr(process_name_in, ".exe")) { snprintf (name, sizeof(name), "%s", process_name_in); } else { snprintf (name, sizeof(name), "%s.exe", process_name_in); } DWORD aProcesses[1024], cbNeeded, cProcesses; if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return NULL; /* Calculate how many process identifiers were returned. */ cProcesses = cbNeeded / sizeof(DWORD); HANDLE hProcess; HMODULE hMod; char process_name[SEAF_PATH_MAX]; unsigned int i; for (i = 0; i < cProcesses; i++) { if(aProcesses[i] == 0) continue; hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, aProcesses[i]); if (!hProcess) continue; if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { GetModuleBaseName(hProcess, hMod, process_name, sizeof(process_name)/sizeof(char)); } if (strcasecmp(process_name, name) == 0) return hProcess; else { CloseHandle(hProcess); } } /* Not found */ return NULL; } int count_process (const char *process_name_in) { char name[SEAF_PATH_MAX]; char process_name[SEAF_PATH_MAX]; DWORD aProcesses[1024], cbNeeded, cProcesses; HANDLE hProcess; HMODULE hMods[1024]; int count = 0; int i, j; if (strstr(process_name_in, ".exe")) { snprintf (name, sizeof(name), "%s", process_name_in); } else { snprintf (name, sizeof(name), "%s.exe", process_name_in); } if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) { return 0; } /* Calculate how many process identifiers were returned. */ cProcesses = cbNeeded / sizeof(DWORD); for (i = 0; i < cProcesses; i++) { if(aProcesses[i] == 0) continue; hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]); if (!hProcess) { continue; } if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { for (j = 0; j < cbNeeded / sizeof(HMODULE); j++) { if (GetModuleBaseName(hProcess, hMods[j], process_name, sizeof(process_name))) { if (strcasecmp(process_name, name) == 0) count++; } } } CloseHandle(hProcess); } return count; } gboolean process_is_running (const char *process_name) { HANDLE proc_handle = get_process_handle(process_name); if (proc_handle) { CloseHandle(proc_handle); return TRUE; } else { return FALSE; } } int win32_kill_process (const char *process_name) { HANDLE proc_handle = get_process_handle(process_name); if (proc_handle) { TerminateProcess(proc_handle, 0); CloseHandle(proc_handle); return 0; } else { return -1; } } int win32_spawn_process (char *cmdline_in, char *working_directory_in) { if (!cmdline_in) return -1; wchar_t *cmdline_w = NULL; wchar_t *working_directory_w = NULL; cmdline_w = wchar_from_utf8 (cmdline_in); if (!cmdline_in) { g_warning ("failed to convert cmdline_in"); return -1; } if (working_directory_in) { working_directory_w = wchar_from_utf8 (working_directory_in); if (!working_directory_w) { g_warning ("failed to convert working_directory_in"); return -1; } } STARTUPINFOW si; PROCESS_INFORMATION pi; unsigned flags; BOOL success; /* we want to execute seafile without crreating a console window */ flags = CREATE_NO_WINDOW; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_FORCEOFFFEEDBACK; si.hStdInput = (HANDLE) _get_osfhandle(0); si.hStdOutput = (HANDLE) _get_osfhandle(1); si.hStdError = (HANDLE) _get_osfhandle(2); memset(&pi, 0, sizeof(pi)); success = CreateProcessW (NULL, cmdline_w, NULL, NULL, TRUE, flags, NULL, working_directory_w, &si, &pi); free (cmdline_w); if (working_directory_w) free (working_directory_w); if (!success) { g_warning ("failed to fork_process: GLE=%lu\n", GetLastError()); return -1; } /* close the handle of thread so that the process object can be freed by * system */ CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; } char * wchar_to_utf8 (const wchar_t *wch) { if (wch == NULL) { return NULL; } char *utf8 = NULL; int bufsize, len; bufsize = WideCharToMultiByte (CP_UTF8, /* multibyte code page */ 0, /* flags */ wch, /* src */ -1, /* src len, -1 for all includes \0 */ utf8, /* dst */ 0, /* dst buf len */ NULL, /* default char */ NULL); /* BOOL flag indicates default char is used */ if (bufsize <= 0) { g_warning ("failed to convert a string from wchar to utf8 0"); return NULL; } utf8 = g_malloc(bufsize); len = WideCharToMultiByte (CP_UTF8, /* multibyte code page */ 0, /* flags */ wch, /* src */ -1, /* src len, -1 for all includes \0 */ utf8, /* dst */ bufsize, /* dst buf len */ NULL, /* default char */ NULL); /* BOOL flag indicates default char is used */ if (len != bufsize) { g_free (utf8); g_warning ("failed to convert a string from wchar to utf8"); return NULL; } return utf8; } wchar_t * wchar_from_utf8 (const char *utf8) { if (utf8 == NULL) { return NULL; } wchar_t *wch = NULL; int bufsize, len; bufsize = MultiByteToWideChar (CP_UTF8, /* multibyte code page */ 0, /* flags */ utf8, /* src */ -1, /* src len, -1 for all includes \0 */ wch, /* dst */ 0); /* dst buf len */ if (bufsize <= 0) { g_warning ("failed to convert a string from wchar to utf8 0"); return NULL; } wch = g_malloc (bufsize * sizeof(wchar_t)); len = MultiByteToWideChar (CP_UTF8, /* multibyte code page */ 0, /* flags */ utf8, /* src */ -1, /* src len, -1 for all includes \0 */ wch, /* dst */ bufsize); /* dst buf len */ if (len != bufsize) { g_free (wch); g_warning ("failed to convert a string from utf8 to wchar"); return NULL; } return wch; } #endif /* ifdef WIN32 */ #ifdef __linux__ /* read the link of /proc/123/exe and compare with `process_name' */ static int find_process_in_dirent(struct dirent *dir, const char *process_name) { char path[512]; /* fisrst construct a path like /proc/123/exe */ if (sprintf (path, "/proc/%s/exe", dir->d_name) < 0) { return -1; } char buf[SEAF_PATH_MAX]; /* get the full path of exe */ ssize_t l = readlink(path, buf, SEAF_PATH_MAX); if (l < 0) return -1; buf[l] = '\0'; /* get the base name of exe */ char *base = g_path_get_basename(buf); int ret = strcmp(base, process_name); g_free(base); if (ret == 0) return atoi(dir->d_name); else return -1; } /* read the /proc fs to determine whether some process is running */ gboolean process_is_running (const char *process_name) { DIR *proc_dir = opendir("/proc"); if (!proc_dir) { fprintf (stderr, "failed to open /proc/ dir\n"); return FALSE; } struct dirent *subdir = NULL; while ((subdir = readdir(proc_dir))) { char first = subdir->d_name[0]; /* /proc/[1-9][0-9]* */ if (first > '9' || first < '1') continue; int pid = find_process_in_dirent(subdir, process_name); if (pid > 0) { closedir(proc_dir); return TRUE; } } closedir(proc_dir); return FALSE; } int count_process(const char *process_name) { int count = 0; DIR *proc_dir = opendir("/proc"); if (!proc_dir) { g_warning ("failed to open /proc/ :%s\n", strerror(errno)); return FALSE; } struct dirent *subdir = NULL; while ((subdir = readdir(proc_dir))) { char first = subdir->d_name[0]; /* /proc/[1-9][0-9]* */ if (first > '9' || first < '1') continue; if (find_process_in_dirent(subdir, process_name) > 0) { count++; } } closedir (proc_dir); return count; } #endif #ifdef __APPLE__ gboolean process_is_running (const char *process_name) { //TODO return FALSE; } #endif char* ccnet_object_type_from_id (const char *object_id) { char *ptr; if ( !(ptr = strchr(object_id, '/')) ) return NULL; return g_strndup(object_id, ptr - object_id); } #ifdef WIN32 /** * In Win32 we need to use _stat64 for files larger than 2GB. _stat64 needs * the `path' argument in gbk encoding. */ #define STAT_STRUCT struct __stat64 #define STAT_FUNC win_stat64_utf8 static inline int win_stat64_utf8 (char *path_utf8, STAT_STRUCT *sb) { wchar_t *path_w = wchar_from_utf8 (path_utf8); int result = _wstat64 (path_w, sb); free (path_w); return result; } #else #define STAT_STRUCT struct stat #define STAT_FUNC stat #endif static gint64 calc_recursively (const char *path, GError **calc_error) { gint64 sum = 0; GError *error = NULL; GDir *folder = g_dir_open(path, 0, &error); if (!folder) { g_set_error (calc_error, CCNET_DOMAIN, 0, "g_open() dir %s failed:%s\n", path, error->message); return -1; } const char *name = NULL; while ((name = g_dir_read_name(folder)) != NULL) { STAT_STRUCT sb; char *full_path= g_build_filename (path, name, NULL); if (STAT_FUNC(full_path, &sb) < 0) { g_set_error (calc_error, CCNET_DOMAIN, 0, "failed to stat on %s: %s\n", full_path, strerror(errno)); g_free(full_path); g_dir_close(folder); return -1; } if (S_ISDIR(sb.st_mode)) { gint64 size = calc_recursively(full_path, calc_error); if (size < 0) { g_free (full_path); g_dir_close (folder); return -1; } sum += size; g_free(full_path); } else if (S_ISREG(sb.st_mode)) { sum += sb.st_size; g_free(full_path); } } g_dir_close (folder); return sum; } gint64 ccnet_calc_directory_size (const char *path, GError **error) { return calc_recursively (path, error); } #ifdef WIN32 /* * strtok_r code directly from glibc.git /string/strtok_r.c since windows * doesn't have it. */ char * strtok_r(char *s, const char *delim, char **save_ptr) { char *token; if(s == NULL) s = *save_ptr; /* Scan leading delimiters. */ s += strspn(s, delim); if(*s == '\0') { *save_ptr = s; return NULL; } /* Find the end of the token. */ token = s; s = strpbrk(token, delim); if(s == NULL) { /* This token finishes the string. */ *save_ptr = strchr(token, '\0'); } else { /* Terminate the token and make *SAVE_PTR point past it. */ *s = '\0'; *save_ptr = s + 1; } return token; } #endif /* JSON related utils. For compatibility with json-glib. */ const char * json_object_get_string_member (json_t *object, const char *key) { json_t *string = json_object_get (object, key); if (!string) return NULL; return json_string_value (string); } gboolean json_object_has_member (json_t *object, const char *key) { return (json_object_get (object, key) != NULL); } gint64 json_object_get_int_member (json_t *object, const char *key) { json_t *integer = json_object_get (object, key); return json_integer_value (integer); } void json_object_set_string_member (json_t *object, const char *key, const char *value) { json_object_set_new (object, key, json_string (value)); } void json_object_set_int_member (json_t *object, const char *key, gint64 value) { json_object_set_new (object, key, json_integer (value)); } void clean_utf8_data (char *data, int len) { const char *s, *e; char *p; gboolean is_valid; s = data; p = data; while ((s - data) != len) { is_valid = g_utf8_validate (s, len - (s - data), &e); if (is_valid) break; if (s != e) p += (e - s); *p = '?'; ++p; s = e + 1; } } char * normalize_utf8_path (const char *path) { if (!g_utf8_validate (path, -1, NULL)) return NULL; return g_utf8_normalize (path, -1, G_NORMALIZE_NFC); } /* zlib related wrapper functions. */ #define ZLIB_BUF_SIZE 16384 int seaf_compress (guint8 *input, int inlen, guint8 **output, int *outlen) { int ret; unsigned have; z_stream strm; guint8 out[ZLIB_BUF_SIZE]; GByteArray *barray; if (inlen == 0) return -1; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION); if (ret != Z_OK) { g_warning ("deflateInit failed.\n"); return -1; } strm.avail_in = inlen; strm.next_in = input; barray = g_byte_array_new (); do { strm.avail_out = ZLIB_BUF_SIZE; strm.next_out = out; ret = deflate(&strm, Z_FINISH); /* no bad return value */ have = ZLIB_BUF_SIZE - strm.avail_out; g_byte_array_append (barray, out, have); } while (ret != Z_STREAM_END); *outlen = barray->len; *output = g_byte_array_free (barray, FALSE); /* clean up and return */ (void)deflateEnd(&strm); return 0; } int seaf_decompress (guint8 *input, int inlen, guint8 **output, int *outlen) { int ret; unsigned have; z_stream strm; unsigned char out[ZLIB_BUF_SIZE]; GByteArray *barray; if (inlen == 0) { g_warning ("Empty input for zlib, invalid.\n"); return -1; } /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; ret = inflateInit(&strm); if (ret != Z_OK) { g_warning ("inflateInit failed.\n"); return -1; } strm.avail_in = inlen; strm.next_in = input; barray = g_byte_array_new (); do { strm.avail_out = ZLIB_BUF_SIZE; strm.next_out = out; ret = inflate(&strm, Z_NO_FLUSH); if (ret < 0) { g_warning ("Failed to inflate.\n"); goto out; } have = ZLIB_BUF_SIZE - strm.avail_out; g_byte_array_append (barray, out, have); } while (ret != Z_STREAM_END); out: /* clean up and return */ (void)inflateEnd(&strm); if (ret == Z_STREAM_END) { *outlen = barray->len; *output = g_byte_array_free (barray, FALSE); return 0; } else { g_byte_array_free (barray, TRUE); return -1; } } char* format_dir_path (const char *path) { int path_len = strlen (path); char *rpath; if (path[0] != '/') { rpath = g_strconcat ("/", path, NULL); path_len++; } else { rpath = g_strdup (path); } while (path_len > 1 && rpath[path_len-1] == '/') { rpath[path_len-1] = '\0'; path_len--; } return rpath; } gboolean is_empty_string (const char *str) { return !str || strcmp (str, "") == 0; } gboolean is_permission_valid (const char *perm) { if (is_empty_string (perm)) { return FALSE; } return strcmp (perm, "r") == 0 || strcmp (perm, "rw") == 0; } seafile-6.1.5/lib/utils.h000066400000000000000000000233011323477647300152310ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifndef CCNET_UTILS_H #define CCNET_UTILS_H #ifdef WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x500 #endif #include #endif #include #include #include #include #include #include #include #include #include #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #else #include #endif #ifdef __linux__ #include #endif #ifdef __OpenBSD__ #include #endif #ifdef WIN32 #include #include #ifndef WEXITSTATUS #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) #endif /* Borrowed from libevent */ #define ccnet_pipe_t intptr_t int pgpipe (ccnet_pipe_t handles[2]); /* Should only be called in main loop. */ #define ccnet_pipe(a) pgpipe((a)) #define piperead(a,b,c) recv((a),(b),(c),0) #define pipewrite(a,b,c) send((a),(b),(c),0) #define pipeclose(a) closesocket((a)) #define SeafStat struct __stat64 #else #define ccnet_pipe_t int #define ccnet_pipe(a) pipe((a)) #define piperead(a,b,c) read((a),(b),(c)) #define pipewrite(a,b,c) write((a),(b),(c)) #define pipeclose(a) close((a)) #define SeafStat struct stat #endif #define pipereadn(a,b,c) recvn((a),(b),(c)) #define pipewriten(a,b,c) sendn((a),(b),(c)) int seaf_stat (const char *path, SeafStat *st); int seaf_fstat (int fd, SeafStat *st); #ifdef WIN32 void seaf_stat_from_find_data (WIN32_FIND_DATAW *fdata, SeafStat *st); #endif int seaf_set_file_time (const char *path, guint64 mtime); #ifdef WIN32 wchar_t * win32_long_path (const char *path); /* Convert a (possible) 8.3 format path to long path */ wchar_t * win32_83_path_to_long_path (const char *worktree, const wchar_t *path, int path_len); __time64_t file_time_to_unix_time (FILETIME *ftime); #endif int seaf_util_unlink (const char *path); int seaf_util_rmdir (const char *path); int seaf_util_mkdir (const char *path, mode_t mode); int seaf_util_open (const char *path, int flags); int seaf_util_create (const char *path, int flags, mode_t mode); int seaf_util_rename (const char *oldpath, const char *newpath); gboolean seaf_util_exists (const char *path); gint64 seaf_util_lseek (int fd, gint64 offset, int whence); #ifdef WIN32 typedef int (*DirentCallback) (wchar_t *parent, WIN32_FIND_DATAW *fdata, void *user_data, gboolean *stop); int traverse_directory_win32 (wchar_t *path_w, DirentCallback callback, void *user_data); #endif #ifndef O_BINARY #define O_BINARY 0 #endif typedef enum IgnoreReason { IGNORE_REASON_END_SPACE_PERIOD = 0, IGNORE_REASON_INVALID_CHARACTER = 1, } IgnoreReason; gboolean should_ignore_on_checkout (const char *file_path, IgnoreReason *ignore_reason); /* for debug */ #ifndef ccnet_warning #define ccnet_warning(fmt, ...) g_warning("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #ifndef ccnet_error #define ccnet_error(fmt, ...) g_error("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #ifndef ccnet_message #define ccnet_message(fmt, ...) g_message("%s(%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__) #endif #define CCNET_DOMAIN g_quark_from_string("ccnet") struct timeval timeval_from_msec (uint64_t milliseconds); size_t ccnet_strlcpy (char *dst, const char *src, size_t size); void rawdata_to_hex (const unsigned char *rawdata, char *hex_str, int n_bytes); int hex_to_rawdata (const char *hex_str, unsigned char *rawdata, int n_bytes); #define sha1_to_hex(sha1, hex) rawdata_to_hex((sha1), (hex), 20) #define hex_to_sha1(hex, sha1) hex_to_rawdata((hex), (sha1), 20) /* If msg is NULL-terminated, set len to -1 */ int calculate_sha1 (unsigned char *sha1, const char *msg, int len); int ccnet_sha1_equal (const void *v1, const void *v2); unsigned int ccnet_sha1_hash (const void *v); char* gen_uuid (); void gen_uuid_inplace (char *buf); gboolean is_uuid_valid (const char *uuid_str); gboolean is_object_id_valid (const char *obj_id); /* dir operations */ int checkdir (const char *dir); int checkdir_with_mkdir (const char *path); char* ccnet_expand_path (const char *src); /** * Make directory with 256 sub-directories from '00' to 'ff'. * `base` and subdir will be created if they are not existing. */ int objstore_mkdir (const char *base); void objstore_get_path (char *path, const char *base, const char *obj_id); char** strsplit_by_space (char *string, int *length); /* Read "n" bytes from a descriptor. */ ssize_t readn(int fd, void *vptr, size_t n); ssize_t writen(int fd, const void *vptr, size_t n); /* Read "n" bytes from a socket. */ ssize_t recvn(evutil_socket_t fd, void *vptr, size_t n); ssize_t sendn(evutil_socket_t fd, const void *vptr, size_t n); int copy_fd (int ifd, int ofd); int copy_file (const char *dst, const char *src, int mode); /* string utilities */ char** strsplit_by_char (char *string, int *length, char c); char * strjoin_n (const char *seperator, int argc, char **argv); int is_ipaddr_valid (const char *ip); typedef void (*KeyValueFunc) (void *data, const char *key, char *value); void parse_key_value_pairs (char *string, KeyValueFunc func, void *data); typedef gboolean (*KeyValueFunc2) (void *data, const char *key, const char *value); void parse_key_value_pairs2 (char *string, KeyValueFunc2 func, void *data); gchar* ccnet_key_file_get_string (GKeyFile *keyf, const char *category, const char *key); GList *string_list_append (GList *str_list, const char *string); GList *string_list_append_sorted (GList *str_list, const char *string); GList *string_list_remove (GList *str_list, const char *string); void string_list_free (GList *str_list); gboolean string_list_is_exists (GList *str_list, const char *string); void string_list_join (GList *str_list, GString *strbuf, const char *seperator); GList *string_list_parse (const char *list_in_str, const char *seperator); GList *string_list_parse_sorted (const char *list_in_str, const char *seperator); gboolean string_list_sorted_is_equal (GList *list1, GList *list2); char** ncopy_string_array (char **orig, int n); void nfree_string_array (char **array, int n); /* 64bit time */ gint64 get_current_time(); /* * Utility functions for converting data to/from network byte order. */ #if !defined(__NetBSD__) static inline uint64_t bswap64 (uint64_t val) { uint64_t ret; uint8_t *ptr = (uint8_t *)&ret; ptr[0]=((val)>>56)&0xFF; ptr[1]=((val)>>48)&0xFF; ptr[2]=((val)>>40)&0xFF; ptr[3]=((val)>>32)&0xFF; ptr[4]=((val)>>24)&0xFF; ptr[5]=((val)>>16)&0xFF; ptr[6]=((val)>>8)&0xFF; ptr[7]=(val)&0xFF; return ret; } #endif static inline uint64_t hton64(uint64_t val) { #if __BYTE_ORDER == __LITTLE_ENDIAN || defined WIN32 || defined __APPLE__ return bswap64 (val); #else return val; #endif } static inline uint64_t ntoh64(uint64_t val) { #if __BYTE_ORDER == __LITTLE_ENDIAN || defined WIN32 || defined __APPLE__ return bswap64 (val); #else return val; #endif } static inline void put64bit(uint8_t **ptr,uint64_t val) { uint64_t val_n = hton64 (val); *((uint64_t *)(*ptr)) = val_n; (*ptr)+=8; } static inline void put32bit(uint8_t **ptr,uint32_t val) { uint32_t val_n = htonl (val); *((uint32_t *)(*ptr)) = val_n; (*ptr)+=4; } static inline void put16bit(uint8_t **ptr,uint16_t val) { uint16_t val_n = htons (val); *((uint16_t *)(*ptr)) = val_n; (*ptr)+=2; } static inline uint64_t get64bit(const uint8_t **ptr) { uint64_t val_h = ntoh64 (*((uint64_t *)(*ptr))); (*ptr)+=8; return val_h; } static inline uint32_t get32bit(const uint8_t **ptr) { uint32_t val_h = ntohl (*((uint32_t *)(*ptr))); (*ptr)+=4; return val_h; } static inline uint16_t get16bit(const uint8_t **ptr) { uint16_t val_h = ntohs (*((uint16_t *)(*ptr))); (*ptr)+=2; return val_h; } /* Convert between local encoding and utf8. Returns the converted * string if success, otherwise return NULL */ char *ccnet_locale_from_utf8 (const gchar *src); char *ccnet_locale_to_utf8 (const gchar *src); /* Detect whether a process with the given name is running right now. */ gboolean process_is_running(const char *name); /* count how much instance of a program is running */ int count_process (const char *process_name_in); #ifdef WIN32 int win32_kill_process (const char *process_name_in); int win32_spawn_process (char *cmd, char *wd); char *wchar_to_utf8 (const wchar_t *src); wchar_t *wchar_from_utf8 (const char *src); #endif char* ccnet_object_type_from_id (const char *object_id); gint64 ccnet_calc_directory_size (const char *path, GError **error); #ifdef WIN32 char * strtok_r(char *s, const char *delim, char **save_ptr); #endif #include const char * json_object_get_string_member (json_t *object, const char *key); gboolean json_object_has_member (json_t *object, const char *key); gint64 json_object_get_int_member (json_t *object, const char *key); void json_object_set_string_member (json_t *object, const char *key, const char *value); void json_object_set_int_member (json_t *object, const char *key, gint64 value); /* Replace invalid UTF-8 bytes with '?' */ void clean_utf8_data (char *data, int len); char * normalize_utf8_path (const char *path); /* zlib related functions. */ int seaf_compress (guint8 *input, int inlen, guint8 **output, int *outlen); int seaf_decompress (guint8 *input, int inlen, guint8 **output, int *outlen); char* format_dir_path (const char *path); gboolean is_empty_string (const char *str); gboolean is_permission_valid (const char *perm); #endif seafile-6.1.5/lib/webaccess.vala000066400000000000000000000003431323477647300165250ustar00rootroot00000000000000namespace Seafile { public class WebAccess : Object { public string repo_id { set; get; } public string obj_id { set; get; } public string op { set; get; } public string username { set; get; } } } seafile-6.1.5/m4/000077500000000000000000000000001323477647300134735ustar00rootroot00000000000000seafile-6.1.5/m4/ax_lib_sqlite3.m4000066400000000000000000000116111323477647300166370ustar00rootroot00000000000000# =========================================================================== # http://www.nongnu.org/autoconf-archive/ax_lib_sqlite3.html # =========================================================================== # # SYNOPSIS # # AX_LIB_SQLITE3([MINIMUM-VERSION]) # # DESCRIPTION # # Test for the SQLite 3 library of a particular version (or newer) # # This macro takes only one optional argument, required version of SQLite # 3 library. If required version is not passed, 3.0.0 is used in the test # of existance of SQLite 3. # # If no intallation prefix to the installed SQLite library is given the # macro searches under /usr, /usr/local, and /opt. # # This macro calls: # # AC_SUBST(SQLITE3_CFLAGS) # AC_SUBST(SQLITE3_LDFLAGS) # AC_SUBST(SQLITE3_VERSION) # # And sets: # # HAVE_SQLITE3 # # LICENSE # # Copyright (c) 2008 Mateusz Loskot # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. AC_DEFUN([AX_LIB_SQLITE3], [ AC_ARG_WITH([sqlite3], AC_HELP_STRING( [--with-sqlite3=@<:@ARG@:>@], [use SQLite 3 library @<:@default=yes@:>@, optionally specify the prefix for sqlite3 library] ), [ if test "$withval" = "no"; then WANT_SQLITE3="no" elif test "$withval" = "yes"; then WANT_SQLITE3="yes" ac_sqlite3_path="" else WANT_SQLITE3="yes" ac_sqlite3_path="$withval" fi ], [WANT_SQLITE3="yes"] ) SQLITE3_CFLAGS="" SQLITE3_LDFLAGS="" SQLITE3_VERSION="" if test "x$WANT_SQLITE3" = "xyes"; then ac_sqlite3_header="sqlite3.h" sqlite3_version_req=ifelse([$1], [], [3.0.0], [$1]) sqlite3_version_req_shorten=`expr $sqlite3_version_req : '\([[0-9]]*\.[[0-9]]*\)'` sqlite3_version_req_major=`expr $sqlite3_version_req : '\([[0-9]]*\)'` sqlite3_version_req_minor=`expr $sqlite3_version_req : '[[0-9]]*\.\([[0-9]]*\)'` sqlite3_version_req_micro=`expr $sqlite3_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` if test "x$sqlite3_version_req_micro" = "x" ; then sqlite3_version_req_micro="0" fi sqlite3_version_req_number=`expr $sqlite3_version_req_major \* 1000000 \ \+ $sqlite3_version_req_minor \* 1000 \ \+ $sqlite3_version_req_micro` AC_MSG_CHECKING([for SQLite3 library >= $sqlite3_version_req]) if test "$ac_sqlite3_path" != ""; then ac_sqlite3_ldflags="-L$ac_sqlite3_path/lib" ac_sqlite3_cppflags="-I$ac_sqlite3_path/include" else for ac_sqlite3_path_tmp in /usr /usr/local /opt ; do if test -f "$ac_sqlite3_path_tmp/include/$ac_sqlite3_header" \ && test -r "$ac_sqlite3_path_tmp/include/$ac_sqlite3_header"; then ac_sqlite3_path=$ac_sqlite3_path_tmp ac_sqlite3_cppflags="-I$ac_sqlite3_path_tmp/include" ac_sqlite3_ldflags="-L$ac_sqlite3_path_tmp/lib" break; fi done fi ac_sqlite3_ldflags="$ac_sqlite3_ldflags -lsqlite3" saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ac_sqlite3_cppflags" AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM([[@%:@include ]], [[ #if (SQLITE_VERSION_NUMBER >= $sqlite3_version_req_number) // Everything is okay #else # error SQLite version is too old #endif ]] ) ], [ AC_MSG_RESULT([yes]) success="yes" ], [ AC_MSG_RESULT([not found]) succees="no" ] ) CPPFLAGS="$saved_CPPFLAGS" if test "$success" = "yes"; then SQLITE3_CFLAGS="$ac_sqlite3_cppflags" SQLITE3_LDFLAGS="$ac_sqlite3_ldflags" ac_sqlite3_header_path="$ac_sqlite3_path/include/$ac_sqlite3_header" dnl Retrieve SQLite release version if test "x$ac_sqlite3_header_path" != "x"; then ac_sqlite3_version=`cat $ac_sqlite3_header_path \ | grep '#define.*SQLITE_VERSION.*\"' | sed -e 's/.* "//' \ | sed -e 's/"//'` if test $ac_sqlite3_version != ""; then SQLITE3_VERSION=$ac_sqlite3_version else AC_MSG_WARN([Can not find SQLITE_VERSION macro in sqlite3.h header to retrieve SQLite version!]) fi fi AC_SUBST(SQLITE3_CFLAGS) AC_SUBST(SQLITE3_LDFLAGS) AC_SUBST(SQLITE3_VERSION) AC_DEFINE([HAVE_SQLITE3], [], [Have the SQLITE3 library]) fi fi ]) seafile-6.1.5/m4/glib-gettext.m4000066400000000000000000000303751323477647300163440ustar00rootroot00000000000000# Copyright (C) 1995-2002 Free Software Foundation, Inc. # Copyright (C) 2001-2003,2004 Red Hat, Inc. # # This file is free software, distributed under the terms of the GNU # General Public License. As a special exception to the GNU General # Public License, this file may be distributed as part of a program # that contains a configuration script generated by Autoconf, under # the same distribution terms as the rest of that program. # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU Public License # but which still want to provide support for the GNU gettext functionality. # # Macro to add for using GNU gettext. # Ulrich Drepper , 1995, 1996 # # Modified to never use included libintl. # Owen Taylor , 12/15/1998 # # Major rework to remove unused code # Owen Taylor , 12/11/2002 # # Added better handling of ALL_LINGUAS from GNU gettext version # written by Bruno Haible, Owen Taylor 5/30/3002 # # Modified to require ngettext # Matthias Clasen 08/06/2004 # # We need this here as well, since someone might use autoconf-2.5x # to configure GLib then an older version to configure a package # using AM_GLIB_GNU_GETTEXT AC_PREREQ(2.53) dnl dnl We go to great lengths to make sure that aclocal won't dnl try to pull in the installed version of these macros dnl when running aclocal in the glib directory. dnl m4_copy([AC_DEFUN],[glib_DEFUN]) m4_copy([AC_REQUIRE],[glib_REQUIRE]) dnl dnl At the end, if we're not within glib, we'll define the public dnl definitions in terms of our private definitions. dnl # GLIB_LC_MESSAGES #-------------------- glib_DEFUN([GLIB_LC_MESSAGES], [AC_CHECK_HEADERS([locale.h]) if test $ac_cv_header_locale_h = yes; then AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, [AC_TRY_LINK([#include ], [return LC_MESSAGES], am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) if test $am_cv_val_LC_MESSAGES = yes; then AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your file defines LC_MESSAGES.]) fi fi]) # GLIB_PATH_PROG_WITH_TEST #---------------------------- dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], [# Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in /*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in ifelse([$5], , $PATH, [$5]); do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word" break fi fi done IFS="$ac_save_ifs" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) # GLIB_WITH_NLS #----------------- glib_DEFUN([GLIB_WITH_NLS], dnl NLS is obligatory [USE_NLS=yes AC_SUBST(USE_NLS) gt_cv_have_gettext=no CATOBJEXT=NONE XGETTEXT=: INTLLIBS= AC_CHECK_HEADER(libintl.h, [gt_cv_func_dgettext_libintl="no" libintl_extra_libs="" # # First check in libc # AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, [AC_TRY_LINK([ #include ], [return !ngettext ("","", 1)], gt_cv_func_ngettext_libc=yes, gt_cv_func_ngettext_libc=no) ]) if test "$gt_cv_func_ngettext_libc" = "yes" ; then AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, [AC_TRY_LINK([ #include ], [return !dgettext ("","")], gt_cv_func_dgettext_libc=yes, gt_cv_func_dgettext_libc=no) ]) fi if test "$gt_cv_func_ngettext_libc" = "yes" ; then AC_CHECK_FUNCS(bind_textdomain_codeset) fi # # If we don't have everything we want, check in libintl # if test "$gt_cv_func_dgettext_libc" != "yes" \ || test "$gt_cv_func_ngettext_libc" != "yes" \ || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then AC_CHECK_LIB(intl, bindtextdomain, [AC_CHECK_LIB(intl, ngettext, [AC_CHECK_LIB(intl, dgettext, gt_cv_func_dgettext_libintl=yes)])]) if test "$gt_cv_func_dgettext_libintl" != "yes" ; then AC_MSG_CHECKING([if -liconv is needed to use gettext]) AC_MSG_RESULT([]) AC_CHECK_LIB(intl, ngettext, [AC_CHECK_LIB(intl, dcgettext, [gt_cv_func_dgettext_libintl=yes libintl_extra_libs=-liconv], :,-liconv)], :,-liconv) fi # # If we found libintl, then check in it for bind_textdomain_codeset(); # we'll prefer libc if neither have bind_textdomain_codeset(), # and both have dgettext and ngettext # if test "$gt_cv_func_dgettext_libintl" = "yes" ; then glib_save_LIBS="$LIBS" LIBS="$LIBS -lintl $libintl_extra_libs" unset ac_cv_func_bind_textdomain_codeset AC_CHECK_FUNCS(bind_textdomain_codeset) LIBS="$glib_save_LIBS" if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then gt_cv_func_dgettext_libc=no else if test "$gt_cv_func_dgettext_libc" = "yes" \ && test "$gt_cv_func_ngettext_libc" = "yes"; then gt_cv_func_dgettext_libintl=no fi fi fi fi if test "$gt_cv_func_dgettext_libc" = "yes" \ || test "$gt_cv_func_dgettext_libintl" = "yes"; then gt_cv_have_gettext=yes fi if test "$gt_cv_func_dgettext_libintl" = "yes"; then INTLLIBS="-lintl $libintl_extra_libs" fi if test "$gt_cv_have_gettext" = "yes"; then AC_DEFINE(HAVE_GETTEXT,1, [Define if the GNU gettext() function is already present or preinstalled.]) GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl if test "$MSGFMT" != "no"; then glib_save_LIBS="$LIBS" LIBS="$LIBS $INTLLIBS" AC_CHECK_FUNCS(dcgettext) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr], [CATOBJEXT=.gmo DATADIRNAME=share], [case $host in *-*-solaris*) dnl On Solaris, if bind_textdomain_codeset is in libc, dnl GNU format message catalog is always supported, dnl since both are added to the libc all together. dnl Hence, we'd like to go with DATADIRNAME=share and dnl and CATOBJEXT=.gmo in this case. AC_CHECK_FUNC(bind_textdomain_codeset, [CATOBJEXT=.gmo DATADIRNAME=share], [CATOBJEXT=.mo DATADIRNAME=lib]) ;; *) CATOBJEXT=.mo DATADIRNAME=lib ;; esac]) LIBS="$glib_save_LIBS" INSTOBJEXT=.mo else gt_cv_have_gettext=no fi fi ]) if test "$gt_cv_have_gettext" = "yes" ; then AC_DEFINE(ENABLE_NLS, 1, [always defined to indicate that i18n is enabled]) fi dnl Test whether we really found GNU xgettext. if test "$XGETTEXT" != ":"; then dnl If it is not GNU xgettext we define it as : so that the dnl Makefiles still can work. if $XGETTEXT --omit-header /dev/null 2> /dev/null; then : ; else AC_MSG_RESULT( [found xgettext program is not GNU xgettext; ignore it]) XGETTEXT=":" fi fi # We need to process the po/ directory. POSUB=po AC_OUTPUT_COMMANDS( [case "$CONFIG_FILES" in *po/Makefile.in*) sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile esac]) dnl These rules are solely for the distribution goal. While doing this dnl we only have to keep exactly one list of the available catalogs dnl in configure.in. for lang in $ALL_LINGUAS; do GMOFILES="$GMOFILES $lang.gmo" POFILES="$POFILES $lang.po" done dnl Make all variables we use known to autoconf. AC_SUBST(CATALOGS) AC_SUBST(CATOBJEXT) AC_SUBST(DATADIRNAME) AC_SUBST(GMOFILES) AC_SUBST(INSTOBJEXT) AC_SUBST(INTLLIBS) AC_SUBST(PO_IN_DATADIR_TRUE) AC_SUBST(PO_IN_DATADIR_FALSE) AC_SUBST(POFILES) AC_SUBST(POSUB) ]) # AM_GLIB_GNU_GETTEXT # ------------------- # Do checks necessary for use of gettext. If a suitable implementation # of gettext is found in either in libintl or in the C library, # it will set INTLLIBS to the libraries needed for use of gettext # and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable # gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() # on various variables needed by the Makefile.in.in installed by # glib-gettextize. dnl glib_DEFUN([GLIB_GNU_GETTEXT], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_HEADER_STDC])dnl GLIB_LC_MESSAGES GLIB_WITH_NLS if test "$gt_cv_have_gettext" = "yes"; then if test "x$ALL_LINGUAS" = "x"; then LINGUAS= else AC_MSG_CHECKING(for catalogs to be installed) NEW_LINGUAS= for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then NEW_LINGUAS="$NEW_LINGUAS $presentlang" fi done LINGUAS=$NEW_LINGUAS AC_MSG_RESULT($LINGUAS) fi dnl Construct list of names of catalog files to be constructed. if test -n "$LINGUAS"; then for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done fi fi dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly dnl find the mkinstalldirs script in another subdir but ($top_srcdir). dnl Try to locate is. MKINSTALLDIRS= if test -n "$ac_aux_dir"; then MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi AC_SUBST(MKINSTALLDIRS) dnl Generate list of files to be processed by xgettext which will dnl be included in po/Makefile. test -d po || mkdir po if test "x$srcdir" != "x."; then if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then posrcprefix="$srcdir/" else posrcprefix="../$srcdir/" fi else posrcprefix="../" fi rm -f po/POTFILES sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ < $srcdir/po/POTFILES.in > po/POTFILES ]) # AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) # ------------------------------- # Define VARIABLE to the location where catalog files will # be installed by po/Makefile. glib_DEFUN([GLIB_DEFINE_LOCALEDIR], [glib_REQUIRE([GLIB_GNU_GETTEXT])dnl glib_save_prefix="$prefix" glib_save_exec_prefix="$exec_prefix" test "x$prefix" = xNONE && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix=$prefix if test "x$CATOBJEXT" = "x.mo" ; then localedir=`eval echo "${libdir}/locale"` else localedir=`eval echo "${datadir}/locale"` fi prefix="$glib_save_prefix" exec_prefix="$glib_save_exec_prefix" AC_DEFINE_UNQUOTED($1, "$localedir", [Define the location where the catalogs will be installed]) ]) dnl dnl Now the definitions that aclocal will find dnl ifdef(glib_configure_in,[],[ AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) ])dnl seafile-6.1.5/m4/python.m4000066400000000000000000000036141323477647300152620ustar00rootroot00000000000000## this one is commonly used with AM_PATH_PYTHONDIR ... dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) dnl Check if a module containing a given symbol is visible to python. AC_DEFUN([AM_CHECK_PYMOD], [AC_REQUIRE([AM_PATH_PYTHON]) py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1) AC_CACHE_VAL(py_cv_mod_$py_mod_var, [ ifelse([$2],[], [prog=" import sys try: import $1 except ImportError: sys.exit(1) except: sys.exit(0) sys.exit(0)"], [prog=" import $1 $1.$2"]) if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC then eval "py_cv_mod_$py_mod_var=yes" else eval "py_cv_mod_$py_mod_var=no" fi ]) py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"` if test "x$py_val" != xno; then AC_MSG_RESULT(yes) ifelse([$3], [],, [$3 ])dnl else AC_MSG_RESULT(no) ifelse([$4], [],, [$4 ])dnl fi ]) dnl a macro to check for ability to create python extensions dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) dnl function also defines PYTHON_INCLUDES AC_DEFUN([AM_CHECK_PYTHON_HEADERS], [AC_REQUIRE([AM_PATH_PYTHON]) AC_MSG_CHECKING(for headers required to compile python extensions) dnl deduce PYTHON_INCLUDES py_prefix=`$PYTHON -c "import sys; print sys.prefix"` py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` if test -x "$PYTHON-config"; then PYTHON_INCLUDES=`$PYTHON-config --includes 2>/dev/null` else PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" if test "$py_prefix" != "$py_exec_prefix"; then PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" fi fi AC_SUBST(PYTHON_INCLUDES) dnl check if the headers exist: save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" AC_TRY_CPP([#include ],dnl [AC_MSG_RESULT(found) $1],dnl [AC_MSG_RESULT(not found) $2]) CPPFLAGS="$save_CPPFLAGS" ]) seafile-6.1.5/msi/000077500000000000000000000000001323477647300137435ustar00rootroot00000000000000seafile-6.1.5/msi/Includes.wxi000066400000000000000000000243501323477647300162460ustar00rootroot00000000000000 seafile-6.1.5/msi/Makefile000066400000000000000000000017141323477647300154060ustar00rootroot00000000000000CULTURE = zh-cn LANG_FILE = zh_CN.wxl TARGET = seafile.msi ifeq (${MAKECMDGOALS}, en) CULTURE = en-us LANG_FILE = en_US.wxl TARGET = seafile-en.msi endif ifeq (${MAKECMDGOALS}, de) CULTURE = de-de LANG_FILE = de_DE.wxl TARGET = seafile-de.msi endif all : $(TARGET) en: all de: all CC=candle.exe LD=light.exe CFLAGS = -nologo -ext WixUIExtension -ext WixUtilExtension LDFLAGS = -nologo -spdb -ext \ WixUIExtension -ext WixUtilExtension \ -loc ${LANG_FILE} -cultures:${CULTURE} \ -sice:ICE80 sources = WixUI_InstallDir_NoLicense.wxs MyInstallDirDlg.wxs \ seafile.wxs fragment.wxs shell.wxs OBJECTS = ${sources:%.wxs=%.wixobj} fragment.wxs: Paraffin.exe -dir bin -g -alias bin -custom bin fragment.wxs %.wixobj : %.wxs $(CC) $(CFLAGS) $< -o $@ seafile.wixobj : seafile.wxs Includes.wxi $(CC) $(CFLAGS) $< -o $@ $(TARGET) : $(OBJECTS) $(LANG_FILE) $(LD) $(LDFLAGS) $(OBJECTS) -o $@ clean : rm -f $(OBJECTS) *.msi fragment.* .PHONY: all en de clean seafile-6.1.5/msi/MyInstallDirDlg.wxs000066400000000000000000000047261323477647300175210ustar00rootroot00000000000000 1 seafile-6.1.5/msi/WixUI_InstallDir_NoLicense.wxs000066400000000000000000000113011323477647300215730ustar00rootroot00000000000000 1 "1"]]> 1 NOT Installed Installed AND PATCH 1 LicenseAccepted = "1" 1 1 NOT WIXUI_DONTVALIDATEPATH "1"]]> WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1" 1 1 NOT Installed Installed AND NOT PATCH Installed AND PATCH 1 1 1 1 seafile-6.1.5/msi/custom/000077500000000000000000000000001323477647300152555ustar00rootroot00000000000000seafile-6.1.5/msi/custom/Makefile000066400000000000000000000011321323477647300167120ustar00rootroot00000000000000CC64 = x86_64-w64-mingw32-gcc.exe DLLWRAP64 = x86_64-w64-mingw32-dllwrap.exe CC32 = gcc.exe DLLWRAP32 = dllwrap.exe all: seafile_custom32.dll seafile_custom64.dll CFLAGS = -Wall -O2 DLLWRAPFLAGS = -Wl,--enable-stdcall-fixup custom32.o: custom.c $(CC32) $(CFLAGS) custom.c -c -o $@ custom64.o: custom.c $(CC64) $(CFLAGS) custom.c -c -o $@ seafile_custom32.dll: custom32.o $(DLLWRAP32) $(DLLWRAPFLAGS) --def custom.def $< -o $@ seafile_custom64.dll: custom64.o $(DLLWRAP64) $(DLLWRAPFLAGS) --def custom.def $< -o $@ clean: rm -f *.o *.dll install: uninstall: distclean: .PHONY: all clean seafile-6.1.5/msi/custom/custom.c000066400000000000000000000045101323477647300167330ustar00rootroot00000000000000#include #include #include #include #ifndef KEY_WOW64_64KEY #define KEY_WOW64_64KEY 0x0100 #endif #ifndef KEY_WOW64_32KEY #define KEY_WOW64_32KEY 0x0200 #endif #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define AT __FILE__ ":" TOSTRING(__LINE__) void msgbox(const char *msg) { MessageBox(NULL, msg, "Seafile Custom", MB_OK); } BOOL readRegValue(HKEY root, const char *subkey, const char *name, char **value) { HKEY hKey; char *buf = NULL; BOOL ret = FALSE; LONG result = RegOpenKeyEx(root, subkey, 0L, // KEY_READ | KEY_WOW64_64KEY, KEY_READ, &hKey); if (result != ERROR_SUCCESS) { goto out; } DWORD len, type; result = RegQueryValueEx(hKey, name, NULL, // reserved &type, // type NULL, // data &len); // size if (result != ERROR_SUCCESS || type != REG_SZ) { goto out; } buf = malloc (len + 1); buf[len] = 0; result = RegQueryValueEx(hKey, name, NULL, // reserved NULL, // type (LPBYTE) buf, // data &len); // size if (result != ERROR_SUCCESS) { goto out; } *value = buf; ret = TRUE; out: RegCloseKey(hKey); return ret; } /* Remove auto start entry for seafile when uninstall. Error is ignored. */ UINT __stdcall RemoveExtDll(HANDLE hModule) { const char *dll_path_key = "SOFTWARE\\Classes\\CLSID\\{D14BEDD3-4E05-4F2F-B0DE-C0381E6AE606}\\InProcServer32"; char *path = NULL; if (!readRegValue(HKEY_LOCAL_MACHINE, dll_path_key, "", &path)) { return ERROR_SUCCESS; } if (!path) { return ERROR_SUCCESS; } int n = strlen(path); char *path2 = malloc (n + 3); memcpy (path2, path, strlen(path)); path2[n] = '.'; path2[n + 1] = '1'; path2[n + 2] = 0; MoveFileEx(path, path2, MOVEFILE_REPLACE_EXISTING); free(path); free(path2); return ERROR_SUCCESS; } seafile-6.1.5/msi/custom/custom.def000066400000000000000000000000541323477647300172460ustar00rootroot00000000000000LIBRARY seafile_custom EXPORTS RemoveExtDll seafile-6.1.5/msi/de_de.wxl000066400000000000000000000013061323477647300155370ustar00rootroot00000000000000 Seafile Seafile Installation Seafile Installation HaiWenHuZhi ltd. Eine neuere Version von Seafile wurde auf Ihrem System gefunden. Die Installation wird jetzt beendet Seafile deinstallieren Seafile starten Seafile beim Systemstart ausführen seafile-6.1.5/msi/en_US.wxl000066400000000000000000000012471323477647300155140ustar00rootroot00000000000000 Seafile Seafile Installer Seafile Installer HaiWenHuZhi ltd. A more up-to-date version of Seafile is detected on your machine. The installer will now quit Uninstall Seafile Start Seafile Start Seafile on startup seafile-6.1.5/msi/seafdir.ico000066400000000000000000000226761323477647300160710ustar00rootroot0000000000000000 ¨%(0` $  (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( (((&(((@(((K(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((M(((L(((A((('((( (((&&&())0*-.z*,.*,.”*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.•*,.”*,.*-.{()*3&&&f™¾ow³àðs²áþs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²àÿs²áÿw³àðiÃw‰Ìü©‰ËûéÄ÷ü~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~Ãõÿ~ÃõÿÄöü‰ËûêŠÌü³ŽÏÿ¶’Ñþæ†ÊüùƒÉûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÈûÿƒÉûÿ†Êüù’ÐþæŽÏÿ¾‡Íÿ¼‹ÎÿæÉüö}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}Æüÿ}ÆüÿÉü÷‹Îþæ‡ÍÿÅyÇÿÂzÇÿærÃýônÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿnÀüÿrÂýõzÇÿæyÇÿÊJÔÿkÁÿÈi¿ÿæc¼ýó^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿ^¹üÿb¼ýôi¿ÿækÁÿÐkÆÿb¾ÿ [ºÿÏW¸ÿæRµýòN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿN²üÿRµýóW¸ÿæ[ºÿÖc½ÿ ZºÿK³ÿÖF±ÿæB¯ýñ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿ?¬üÿB®ýòF±ÿæK³ÿÚ[ºÿT·ÿ%=­þÛ8«þæ6©üð4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ4¨ûÿ6©üñ8«þæ<­þÞT·ÿ'Q¶þ.8«ýß5©ýæ3¨üð1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ1¦ûÿ3¨üñ5©ýæ7ªýáQµþ0K³þ25©üâ2§üæ1¦ûï/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ/¥úÿ1¦ûð2§üæ4¨üãJ³þ4E±ý62§ûä/¥ûæ.¥úî-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ-¤ùÿ.¥úï/¥ûæ2¦ûåE°ý9?­ý:.¥úæ,¤úæ+£úî+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£ùÿ+£úî,¤úæ.¥úæ?­ý=9ªûH+£ùç)¢ùæ)¢ùí)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢øÿ)¢ùî)¢ùæ+£ùç8ªüL3§ù](¡øç& øæ& øì' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' ÷ÿ' øí& øæ'¡øæ2¦ùa,£÷o$Ÿ÷æ$Ÿ÷æ$Ÿ÷ë%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ%Ÿ÷ÿ$Ÿ÷ì$Ÿ÷æ$Ÿ÷æ,£÷r(Ÿõ}!öæ!öæ!öë#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ#žöÿ"öì!öæ!öæ(Ÿõ#œó„›õæ›õæœõë!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿ!õÿœõì›õæ›õæ#œô†™òŠ™ôæ™ôæšôë›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿ›õÿšôì™ôæ™ôæ™òŒ–ð—óæ—óæ˜óëšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿšôÿ˜óì—óæ—óæ–ð’“òæ–òæ–òë™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ™óÿ—òì–òæ–òæ“îž‘í±”ñæ”ñæ•ñë—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ—òÿ•ñì”ñæ”ñæ‘í³ ìÂ’ðæ’ðæ“ðë–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ–ñÿ”ðì’ðæ’ðæ ìÄ ìÑ ‘ïæ ‘ïæ’ïë•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ•ñÿ’ïì ‘ïæ ‘ïæ ìÒŒëÙ îæ îæ îë“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ“ðÿ îì îæ îæŒëÚ‹êßíæíæ Žíë’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ’ïÿ Žîìíæíæ‹êߊêåŒìæŒìæíëîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿîÿíìŒìæŒìæŠêå?¤íæ\´òî[³òî[³òò\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ\´óÿ[³òò[³òî\´òî?¥íç@£ëGU­ívV®íwKŸä—\£æÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿa¦éÿ]£çþKžã›V®íwU®ív@£ëI1…Õ;o²ñÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿy¹öÿr´òþ1…ÕB@ß9k¿úÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿrÄÿÿmÀûþDžà@Bß9oÀúÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿvÆÿÿqÂûþI¡á?Džß9rÂúÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿyÇÿÿsÃûýe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òùe¸òù`³ïØ=šÝFŸß9uÃúÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}Éÿÿ}ÉÿÿuÃûúQ©èvEžÞ7yÄúýÊÿÿÊÿÿÊÿÿÊÿÿÊÿÿÊÿÿÊÿÿÊÿÿÊÿÿyÄûûS«éu<šÝ@›Üb³ìºn»ò÷n»òùn»òùn»òùn»òùn»òùn»òùn»òùlºòéV¬ëk=›ÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ€€€€€€àààààÿÿÿàÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿseafile-6.1.5/msi/seafile-background.bmp000066400000000000000000022617521323477647300202070ustar00rootroot00000000000000BMêc Š|í8 `c   ÿÿÿÿBGRsÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþþÿþþþÿþþþÿþþÿÿþþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþþÿþþþÿþþþÿþþþÿþþþÿþþþÿþþÿÿþþÿÿþþÿÿþþÿÿþþþÿþþþÿþþÿÿþþÿÿþþÿÿþþþÿþþþÿþþÿÿþþÿÿþþþÿþþþÿþþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿüýþÿûýþÿúýþÿùüþÿùüþÿùüÿÿùüÿÿúýþÿûýÿÿýþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿüýþÿúýþÿùüþÿùüþÿùüþÿùüþÿùüþÿùüþÿùüÿÿùüÿÿùüÿÿùüÿÿùüþÿùüþÿùüÿÿùüÿÿùüÿÿùüþÿùüþÿùüÿÿùüÿÿùüþÿùüþÿúýÿÿúýþÿüýþÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿüýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿýþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüÿÿîøÿÿçõþÿâóþÿáóþÿâóÿÿãôÿÿèõþÿðùÿÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿòùþÿéöþÿãôþÿáóþÿáóþÿâóþÿáóþÿáóþÿâóÿÿâóÿÿâóÿÿâóÿÿáóþÿáóþÿâóÿÿâóÿÿâóÿÿáóþÿáóþÿâóÿÿâóÿÿâóÿÿâóÿÿåôÿÿê÷ÿÿòúÿÿüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿüýþÿÿÿÿÿÿÿÿÿäôÿÿ´áÿÿÌþÿW¼þÿ?²ýÿ6®ýÿ8°ÿÿD´ÿÿ_¾þÿ‹Ðÿÿ¿åÿÿêöþÿÿÿÿÿÿÿÿÿûýþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿÿÿÿÿ÷ûþÿÏëþÿ”ÔþÿaÀþÿBµþÿ5¯þÿ7¯þÿ9¯þÿ7¯ýÿ8¯þÿ9°ÿÿ9±ÿÿ9±ÿÿ9±ÿÿ8¯þÿ8¯þÿ8¯ÿÿ9°ÿÿ9°ÿÿ8°þÿ8¯þÿ9°ÿÿ9°ÿÿ7¯þÿ:°þÿH¶ÿÿiÃþÿ—ÕþÿÉéÿÿôúþÿÿÿÿÿýþÿÿþþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿÿÿÿÿñùÿÿºäÿÿsÇýÿB´ýÿ&¨ýÿ žþÿ ýÿœýÿ žþÿ žþÿ ýÿ.«þÿM¸þÿ~ËþÿÂæþÿöûþÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿæõþÿ¤Ûÿÿ_Àÿÿ2®þÿ¢þÿ Ÿþÿ žþÿ þÿ œýÿ ýÿ žþÿ Ÿÿÿ Ÿÿÿ Ÿÿÿ Ÿÿÿ žÿÿ žÿÿ þÿ þÿ þÿ žþÿ ýÿ þÿ þÿ ýÿ žþÿ Ÿÿÿ¤þÿ0­ýÿW»ýÿ’ÓþÿÔíþÿþþþÿÿÿÿÿþþÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿòùþÿ¯àÿÿQ»ÿÿ Ÿýÿ ýÿ ýÿ žþÿ Ÿýÿ žüÿŸþÿ Ÿýÿ žýÿ žþÿ žþÿ¢þÿ[½þÿ·âþÿõûþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿéöþÿ–Õþÿ:±ÿÿ Ÿÿÿ žþÿ žþÿ ŸþÿŸþÿŸþÿ žýÿŸþÿ þÿ þÿ ÿÿ¡ÿÿ¡ÿÿ ÿÿ ÿÿŸþÿ ýÿ žþÿ þÿ ýÿžýÿ ýÿŸýÿ þÿ  ÿÿ žþÿ žýÿ ýÿ(©þÿwÈþÿÊêþÿúýþÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿöûþÿªÝþÿJ·þÿ Ÿþÿ  ÿÿ Ÿÿÿ žÿÿ žýÿ žýÿ Ÿþÿ žýÿ žýÿ Ÿýÿ Ÿþÿ Ÿþÿ Ÿþÿ  ÿÿM¸þÿ­Þþÿöûþÿÿÿÿÿúýþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿíøþÿ£Úþÿ2®þÿ žþÿ ýÿ Ÿýÿ Ÿýÿ Ÿþÿ  ÿÿ Ÿÿÿ Ÿþÿ Ÿýÿ žþÿ žþÿ  þÿ  ÿÿ  ÿÿ Ÿþÿ žþÿ žþÿ žþÿ Ÿþÿ  ÿÿ ¡ÿÿ Ÿÿÿ žÿÿ  ÿÿ Ÿþÿ žþÿ  ÿÿ  ÿÿ Ÿÿÿ Ÿþÿ¤þÿ\¾þÿÌêþÿÿÿÿÿýþþÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿüýþÿÿÿÿÿÔîþÿU¼ýÿ Ÿþÿ Ÿþÿ ¡ÿÿ£ÿÿ Ÿþÿ Ÿýÿ  þÿ  þÿ Ÿþÿ  ýÿ þÿ þÿ¡ýÿ  þÿ  ÿÿ ŸþÿK¸ýÿ®ßþÿöûþÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿÿÿÿÿÀæþÿS»ýÿ  þÿ Ÿýÿ üÿ ýÿ Ÿýÿ þÿ¡þÿ  þÿ  þÿ  þÿ Ÿýÿ Ÿýÿ¡ýÿ  þÿ  þÿ Ÿýÿ  þÿ  ÿÿ  þÿ  þÿ¡ÿÿ£ÿÿ¡ÿÿ  ÿÿ¡ÿÿ  þÿ Ÿýÿ  þÿ¡ÿÿ¡þÿ Ÿþÿ žþÿ¤þÿwÉýÿÔîþÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿïùÿÿœØÿÿ§þÿ ¡þÿ¢þÿ ¡þÿ  þÿ  þÿ¡þÿ¢þÿ¢þÿ¡þÿ¡þÿ¡þÿ þÿ ýÿ ýÿ£ÿÿ¡þÿ  ýÿM¹ýÿ²àþÿûýÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿÿÿÿÿõûÿÿŠÑýÿ¦üÿ¡þÿ¡þÿ  ýÿ  ýÿ  þÿ þÿ¡þÿ¡þÿ¡þÿ¡þÿ  þÿ ¡ýÿ  ýÿ  þÿ  þÿ  ýÿ¢þÿ¢ÿÿ ¡þÿ  ýÿ¡þÿ£ÿÿ¢þÿ¡þÿ¢ÿÿ ¡þÿ  ýÿ þÿ þÿ  ýÿ ýÿ Ÿýÿ Ÿþÿ'ªýÿ’ÔþÿöûÿÿÿÿÿÿýþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýÿÿÿÿÿÿÿÿÿÿËêÿÿcÂÿÿ¥ÿÿ£ÿÿ¢þÿ  üÿ ¡ýÿ¢þÿ¢þÿ£ÿÿ¤ÿÿ£þÿ¢þÿ¢þÿ¢ÿÿ¡ÿÿ¡þÿ¢þÿ£þÿ¢þÿ¢þÿNºþÿ±àÿÿûýÿÿÿÿÿÿùüþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿüýÿÿËëþÿ_Àýÿ  üÿ£ÿÿ¤ÿÿ¡ÿÿ¢þÿ¢þÿ¢ÿÿ£ÿÿ!©þÿ=³ýÿBµýÿ1¯þÿ§ÿÿ¢þÿ¢þÿ£ÿÿ¢þÿ¢þÿ£ÿÿ¢ÿÿ¡þÿ¡ýÿ¢þÿ£þÿ£þÿ¢ýÿ¢ýÿ¢ýÿ£ÿÿ¢ÿÿ¡ýÿ¡ýÿ¢ýÿ¡ýÿ¢þÿ\¿þÿÌëÿÿüýÿÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýÿÿÿÿÿÿÿÿÿÿ³âÿÿ@¶ÿÿ¥ÿÿ£þÿ¢üÿ üÿ¢ýÿ£þÿ£ýÿ£þÿ¤ÿÿ¤þÿ¤þÿ¤ÿÿ£ÿÿ¢þÿ¢ýÿ£þÿ¥þÿ£þÿ£þÿ£þÿP»ÿÿ´âþÿúýþÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿöûþÿ­ßþÿG·üÿ¡ýÿ£þÿ¥ÿÿ¤ÿÿ£þÿ£þÿ!©ÿÿY¿ÿÿ‰Ñþÿ£Ûýÿ§ÝýÿœÙÿÿwËÿÿ@µþÿ¥þÿ¤ÿÿ£ÿÿ¢þÿ¢ýÿ¢þÿ¢þÿ¢ýÿ¢þÿ£þÿ£ýÿ¢ýÿ¢ýÿ£þÿ£þÿ£þÿ¢þÿ¢þÿ¢ýÿ¢ýÿ¢þÿ8²ÿÿ›Øÿÿóúÿÿÿÿÿÿüýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýÿÿÿÿÿÿÿÿÿÿ¬ßÿÿ7³ÿÿ¥þÿ£ýÿ¢üÿ¢ýÿ¤þÿ¥þÿ¥ýÿ¤ýÿ£þÿ¤þÿ¥þÿ¥ÿÿ£þÿ¢ýÿ£ýÿ¤þÿ¤þÿ£þÿ¦ýÿ¤ýÿ¤þÿS½þÿ¶ãþÿýþþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿôûþÿ¡Úþÿ>µýÿ¢ýÿ£ýÿ¥ýÿ¥þÿ£þÿ$ªþÿfÄþÿÃçþÿðùþÿõûþÿøüþÿöûÿÿßòþÿ¢ÛþÿKºþÿ¤þÿ¥ÿÿ£þÿ¢ýÿ¢ýÿ¢ýÿ¤ýÿ¤þÿ¤ýÿ£ýÿ£þÿ£þÿ£þÿ£ýÿ£ýÿ£þÿ¢þÿ¢þÿ¢ýÿ¢þÿ§þÿnÇþÿë÷þÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿ²áþÿAµýÿ§þÿ¥þÿ¤þÿ¥ÿÿ¦ÿÿ¦ÿÿ¦þÿ¥þÿ¤þÿ¤ýÿ£ýÿ£ýÿ¤ýÿ¤ýÿ¥þÿ¤þÿ¤ýÿ¥ýÿ¥þÿ¥ýÿ¥ýÿ¨ÿÿS¾ÿÿ°áþÿüýþÿÿÿÿÿùüþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿóúþÿ Ûþÿ@¶þÿ¥þÿ¥þÿ¦þÿ¥þÿ¦þÿdÄþÿÉêþÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõûÿÿ¦ÝþÿD¸þÿ©ÿÿ¦ÿÿ¤þÿ£ýÿ£ýÿ¤þÿ¦þÿ¥ýÿ¤ýÿ¤þÿ¥þÿ¥þÿ¥ÿÿ¤þÿ¥ýÿ¥ýÿ¥þÿ¤þÿ¤ýÿ£ýÿN»ýÿåõþÿÿÿÿÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿÄèþÿ\Áýÿ¨ýÿ¦þÿ§ÿÿ§ÿÿ¦þÿ¦þÿ§þÿ§þÿ¦þÿ¦þÿ¤ýÿ£üÿ¤ýÿ¥þÿ¦þÿ¦þÿ¦ýÿ¦þÿ¦þÿ¦þÿ¦ýÿ§ÿÿ¨ÿÿT¾þÿ·äþÿúýÿÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿÿÿÿÿõûþÿªÞþÿH¹þÿ¦þÿ¦þÿ¦þÿ¦þÿ.°þÿÚþÿÿÿÿÿÿÿÿÿýþÿÿýþþÿýþþÿûýþÿÿÿÿÿÿÿÿÿåõþÿ‰Òþÿ&®ÿÿ¨ÿÿ¨ÿÿ¦þÿ¤þÿ¤þÿ¦þÿ§þÿ¥þÿ¥ýÿ¦þÿ¨ÿÿ§þÿ§þÿ¦þÿ¦ýÿ¦ýÿ¦ýÿ¦ýÿ¥ýÿ?µýÿãôþÿÿÿÿÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿâôÿÿ‹Ôþÿ#«ýÿ§þÿ©ÿÿ§þÿ¦ýÿ¦ýÿ§þÿ§þÿ§þÿ©ÿÿ§þÿ¦üÿ¦þÿ¦þÿ¦ýÿ§ýÿ§ýÿ§þÿ¦þÿ¦þÿ¦þÿ§þÿ§ÿÿªÿÿWÀþÿ·äþÿüýþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿúýþÿÃèþÿ]Áþÿ¦þÿ§þÿ§þÿ¨þÿN¼þÿ»åþÿÿÿÿÿÿÿÿÿùüþÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿûýþÿýþÿÿ¾æÿÿ9µþÿ¨þÿ©þÿ©ÿÿ§þÿ¦ýÿ§þÿ§þÿ§þÿ¦ýÿ§þÿ¨ÿÿ¨ýÿ©þÿ¨ÿÿ¦ýÿ¦üÿ¦üÿ¨þÿ§þÿ<µýÿâôþÿÿÿÿÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿýþþÿÿÿÿÿÅéþÿC¸ýÿ©þÿ«ÿÿ¨þÿ¨ýÿ¨ýÿ§ýÿ¦ýÿ§ýÿªÿÿªÿÿ©þÿ©ýÿ¨üÿ§üÿ§ýÿ§ýÿ§üÿ¨ýÿ¨þÿ§þÿ§ýÿ¨þÿªÿÿªþÿV¿ýÿ³âþÿøüþÿÿÿÿÿúýþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿèöþÿ…Ðþÿ%­þÿ©ÿÿ©þÿ«þÿ[ÃÿÿÂèÿÿÿÿÿÿÿÿÿÿûýÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿûýþÿÿÿÿÿÓîþÿH»ýÿ©ýÿªþÿ©þÿ©þÿ¨ýÿ§ýÿ§ýÿ§ýÿ©þÿ¨þÿ§ýÿ©þÿªÿÿªÿÿ¨ýÿ§ýÿ¨þÿ©þÿ¦ýÿC·üÿãôþÿÿÿÿÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿîøþÿ’Öþÿ:¶þÿªþÿ¨þÿ©ýÿ©ýÿ¨ýÿ¨üÿ©ýÿªÿÿªþÿ©ýÿ¨üÿ¨üÿ¨ýÿ¨ýÿ¨üÿ¨üÿ©ýÿªþÿ©þÿ¨ýÿ©ýÿªþÿªÿÿªþÿU¿þÿ·äþÿ÷üþÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿÿÿÿÿÿÿÿÿ´ãþÿL¼þÿªÿÿªþÿ!¬þÿP¾þÿ¾çþÿÿÿÿÿÿÿÿÿøüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿÔîþÿK¼ýÿªþÿªþÿ©þÿ©ýÿ©ýÿ§üÿ§ýÿ©ýÿ©ýÿ¨ýÿ§ýÿ©þÿªÿÿ«þÿªþÿ©þÿ©þÿ«ÿÿ¨þÿV¾ýÿçõþÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿþþþÿáóþÿŠÓþÿ5³þÿªýÿªþÿªþÿ«ýÿ«ýÿªýÿªÿÿªþÿ©üÿ§üÿ¨ýÿªþÿªýÿªýÿ©ýÿªþÿ«þÿ«þÿªýÿ©ýÿªýÿ¬ÿÿªÿÿªþÿZÂýÿ¸äþÿøüÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿâôþÿÖþÿ3´þÿ«þÿªþÿ+°ýÿšÚþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿüþÿÿÿÿÿÿÊëþÿDºþÿªýÿ«ýÿ©ýÿ©ýÿ©ýÿ§üÿ©ýÿ«þÿªüÿ¨üÿ©ýÿªþÿ«þÿ«þÿ«þÿªýÿªýÿ«ÿÿ(°ÿÿxÌþÿíøþÿÿÿÿÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿâôþÿ¢ÝþÿYÂþÿ/³þÿ$®þÿ­ÿÿ¬þÿ¬þÿ¬ýÿ«þÿªþÿªýÿ«þÿ¬ÿÿ¬ÿÿ¬þÿ¬þÿ¬þÿ¬þÿ¬ýÿªýÿªþÿ¬ÿÿ«þÿªýÿªýÿ¬þÿ[Ãþÿ·åþÿúýþÿÿÿÿÿùýþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿþþÿÿÿÿÿÿßóþÿÑÿÿ5¶ÿÿ¬þÿ¬ýÿ^ÄýÿÃéþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿþþþÿÿÿÿÿþþÿÿøüþÿ´ãþÿ:·þÿ«ýÿ«üÿªüÿªýÿªýÿªýÿ«ýÿ¬þÿ¬þÿ«ýÿ«ýÿ¬þÿ«þÿ«þÿ«ýÿ«üÿªüÿ¬þÿH¼þÿ¦Þþÿõûþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿîùÿÿ¿èÿÿ–ØþÿjÈÿÿ9·ÿÿ!¯ÿÿ­þÿ¬ýÿ¬ýÿ­þÿ­ýÿ­þÿ­ÿÿ­ÿÿ­ÿÿ­ýÿ­ýÿ­ýÿ¬üÿ«üÿ¬þÿ®ÿÿ­ýÿ­ýÿ¬þÿ®þÿ ¯þÿ\Äþÿ»æÿÿúýÿÿÿÿÿÿÿÿÿÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿüþÿÿÿÿÿÿÿÿÿÿØñÿÿ“ØÿÿN¿þÿ*±ýÿ*±þÿ]Äþÿ²ãþÿåõþÿõûÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿæöþÿ•Ùþÿ.³þÿ¬ýÿ«üÿ«üÿ¬ýÿ­þÿ­þÿ­ýÿ¬ýÿ­þÿ­þÿ¬ýÿ¬ýÿ­þÿ¬þÿ¬ýÿ!¬üÿ¬ýÿ­þÿlÉÿÿØðþÿýþþÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿüþþÿÿÿÿÿÿÿÿÿøüÿÿ¼çÿÿZÄÿÿ&±þÿ®þÿ­ýÿ®ýÿ¯ýÿ ¯ýÿ ®ýÿ®þÿ®ÿÿ®þÿ®ýÿ®ýÿ®þÿ­ýÿ¬üÿ®þÿ °ÿÿ¯þÿ®ýÿ ¯þÿ%±ÿÿ °ÿÿ¯þÿ`Æþÿ½çÿÿþþþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýÿÿÿÿÿÿÿÿÿÿê÷þÿ²ãþÿ€ÐþÿM¾þÿD»þÿxÎþÿ½çþÿëøÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿËìþÿiÈýÿ%°þÿ®þÿ¬ýÿ¬ýÿ­ýÿ®þÿ®þÿ®ýÿ­ýÿ®þÿ®þÿ­ýÿ­ýÿ®þÿ®þÿ­ýÿ®ýÿ ¯þÿ@¹ÿÿ¢ÝÿÿøüÿÿÿÿÿÿýþÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓïþÿ`Æýÿ$±ýÿ °ýÿ"°þÿ!°þÿ!°þÿ"±þÿ!¯ýÿ ®ýÿ ®ýÿ ¯ýÿ!¯ýÿ"°þÿ!°ÿÿ ¯ÿÿ®þÿ!°þÿ"²ÿÿ ¯þÿ ¯ýÿ!°þÿ"±ÿÿ"±ÿÿ!°ÿÿ#¯ýÿ_Åýÿ»æÿÿÿÿÿÿÿÿÿÿùýþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷üÿÿäõÿÿ¿çþÿ¡Üþÿ¤ÞþÿÆêþÿíøÿÿþþÿÿûýþÿÿÿÿÿÿÿÿÿ¢Ýüÿ6¶ûÿ ¯ýÿ ¯ýÿ®ýÿ®üÿ®ýÿ$°ýÿ+²ýÿ%°þÿ °þÿ ¯ýÿ ¯ýÿ!°þÿ ¯þÿ ®ýÿ"®ýÿ$°þÿ °þÿ1µþÿ×þÿâôÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿüþþÿóúþÿµåþÿI¿ýÿ °üÿ!°üÿ!°ýÿ"°þÿ"±þÿ$±ÿÿ#°þÿ!¯ýÿ"±ýÿ#±þÿ#±þÿ#±ÿÿ#²ÿÿ"±ÿÿ!°ÿÿ#²ÿÿ$²þÿ!°þÿ ¯ýÿ!°üÿ"±þÿ&³ÿÿ#±ÿÿ"°ýÿ%±ýÿbÇþÿ¿èÿÿýþÿÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿíøþÿâôþÿé÷ÿÿöûÿÿùüþÿÿÿÿÿÿÿÿÿÒïþÿkÉüÿ ¯üÿ!¯ýÿ#°ýÿ!°ýÿ!°üÿ!¯üÿ+³ýÿPÀýÿF½þÿ&²ýÿ!°ýÿ$²ýÿ&²þÿ"°þÿ!¯ýÿ!°þÿ"±ÿÿ:¹þÿ‚ÒýÿÛòþÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿàôþÿ×ýÿ/µýÿ!±üÿ#±ûÿ!°üÿ"±ýÿ#±þÿ$±þÿ$±ýÿ$²ýÿ$³þÿ$³ÿÿ$²ÿÿ#²þÿ$²ýÿ$²þÿ#²ÿÿ$³ÿÿ$³þÿ#²ýÿ"±üÿ"±üÿ#±ýÿ$²þÿ$²ýÿ&²üÿ"±üÿ'²ýÿeÈýÿÀèþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿüþþÿüþþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæöþÿ„Óýÿ7¸üÿ!°üÿ"°ýÿ$±þÿ$³þÿ%²ýÿ#°ýÿ-´ýÿfÉþÿyÐþÿUÃýÿ(´ýÿ$³þÿ#²þÿ#±ýÿ#±ýÿ,µþÿG¾ÿÿ×ÿÿÛòþÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÙòþÿ€Òýÿ-´üÿ"±üÿ&³ýÿ%²ýÿ%²ýÿ$³ýÿ$³üÿ%³ýÿ&³ýÿ&³ýÿ%²ýÿ$²ýÿ$´ýÿ%³üÿ%³üÿ%´þÿ%´ÿÿ&´þÿ%³ýÿ$³ýÿ%´þÿ%³ýÿ%³ýÿ$³üÿ#²ûÿ$³ýÿ%³þÿ)³ûÿcÈüÿºçÿÿþþÿÿÿÿÿÿùýþÿûýþÿýþþÿþþþÿþþþÿþþþÿþþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿëøÿÿšÛÿÿ?»ýÿ#²üÿ#²üÿ$±ýÿ&³þÿ'µÿÿ'³þÿ$²ýÿ'³üÿPÂýÿ¡Þþÿ©áÿÿC¾ÿÿ&´þÿ%´þÿ/¶þÿNÁþÿ|ÒþÿµåþÿæöþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÕðþÿ|Òýÿ/µüÿ%³ýÿ)µþÿ(µþÿ(µþÿ&µýÿ%´üÿ&´üÿ&³üÿ&³üÿ%²üÿ%³ýÿ&´ýÿ'´üÿ&´üÿ%´ýÿ&´ýÿ'´ýÿ'µýÿ&µýÿ%´ýÿ&´ýÿ&´üÿ&´üÿ&³üÿ*¶þÿ(¶þÿ&´ýÿ+¶ýÿ_Èþÿ­ãþÿêøþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿýþþÿýþþÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚòþÿ’ÙþÿJÀþÿ'´þÿ&´ýÿ'³üÿ&³ýÿ'´ýÿ'µþÿ'´þÿ&´þÿ&´ýÿ7¹ýÿ¥ßþÿåöÿÿŸÞÿÿpÎþÿxÐþÿØþÿ±ãþÿÔðþÿöüþÿÿÿÿÿÿÿÿÿþþÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÖñþÿ~Òýÿ0¸üÿ'µýÿ+µþÿ)¶þÿ)¶þÿ(¶þÿ)¶þÿ(µüÿ&´ûÿ&³ûÿ'´üÿ(´ýÿ'´üÿ(µüÿ(µýÿ'µüÿ'´üÿ'´üÿ(¶ýÿ'µýÿ&´üÿ'´üÿ(µýÿ(µýÿ(µýÿ)¶þÿ*·ÿÿ,¸ÿÿ'µýÿ'µýÿOÃýÿ˜ÜþÿÖñþÿïùþÿùüþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿôûþÿíøþÿÈìþÿ€Óýÿ?½üÿ(¶ýÿ)¶þÿ,¶þÿ)µýÿ'µýÿ'µýÿ'µýÿ'µþÿ*¶þÿ(¶þÿ(µþÿ‡Õþÿé÷ÿÿóûÿÿäõþÿãõþÿòúÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÛòþÿ‡Öýÿ3ºýÿ)¶ýÿ,·ýÿ*·üÿ)¶üÿ*¶ýÿ,¸ÿÿ+¸þÿ)¶ûÿ)µûÿ*¶ýÿ)µýÿ(µüÿ(µüÿ)¶ýÿ*·þÿ*·ýÿ(µüÿ(¶ýÿ*¶ýÿ*¶ýÿ*¶ýÿ)¶ýÿ)·ýÿ(¶üÿ+·þÿ,¸ÿÿ*·þÿ'¶üÿ(¶üÿ+¸þÿ<½þÿ`Èýÿ–ÛýÿÁéýÿÝóþÿóúþÿùüþÿøüþÿ÷üþÿíùþÿ×ñþÿ¶æþÿ†ÕýÿTÄüÿ4¹ýÿ)¶ýÿ*·ýÿ+·þÿ,¸ÿÿ+¸ÿÿ*·ýÿ*·þÿ*¸ÿÿ*¸ýÿ+¸üÿ(¶ýÿ)·þÿgÌþÿËíþÿýþþÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþþÿþþþÿþþþÿþþþÿþþþÿþþþÿþþþÿþþÿÿþþþÿüþþÿÿÿÿÿÿÿÿÿäöþÿ™Üþÿ?¾þÿ+¸ýÿ,¸ýÿ,¸ýÿ,¸üÿ,¸ýÿ.ºÿÿ-ºÿÿ+¸üÿ+·üÿ,¸ýÿ+¸ýÿ*·üÿ*·üÿ+¸ýÿ,¹þÿ,¹ýÿ+·ýÿ+¶þÿ,¸þÿ-¹þÿ+¸ýÿ*¸ýÿ*¸ýÿ+¸ýÿ,¸þÿ,¸þÿ+¸ýÿ+·üÿ+·üÿ+¸ýÿ,¸ÿÿ+¸ÿÿHÁþÿdÊýÿzÒýÿÙýÿ—Üýÿ˜Ýýÿ—ÜþÿŠØýÿtÐýÿ^Èýÿ>¾ýÿ+¸ýÿ,·ýÿ+·ýÿ-·ýÿ+·ýÿ,·ýÿ,¸þÿ,¹ýÿ-¹þÿ-¹ÿÿ,¹þÿ-¸üÿ*·üÿ+¸ýÿ[Èþÿ¶æýÿöüþÿÿÿÿÿýþÿÿþþþÿüþþÿüþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿôûþÿµæþÿPÄþÿ-¹ýÿ/¹ýÿ.ºþÿ.ºþÿ-¹ýÿ.ºÿÿ-ºþÿ,¹ýÿ,¹ýÿ-ºþÿ-ºþÿ-ºþÿ-ºýÿ.»ýÿ-ºýÿ-ºýÿ.¹ýÿ-¸þÿ.¹þÿ.ºþÿ-ºýÿ,¹ýÿ-¹ýÿ.ºþÿ.ºþÿ,¹þÿ,¹üÿ-¹üÿ-¸üÿ-¸üÿ0ºþÿ/»ÿÿ.»ÿÿ.ºþÿ-¹ýÿ0¹ýÿ5¼ýÿ8½üÿ6½ýÿ.ºýÿ-¹ýÿ.ºþÿ/»þÿ0ºþÿ0ºüÿ-¹üÿ,¸ýÿ,¹üÿ,¸üÿ,¸üÿ.ºþÿ/ºþÿ.¹þÿ-¹þÿ/¹ýÿ-¸üÿ-¹ýÿ[Èýÿ³åýÿõûþÿÿÿÿÿûýþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿüþþÿýþþÿúýþÿÿÿÿÿ×ñþÿkÎüÿ2»üÿ/ºüÿ/¼ýÿ/¼ýÿ.»ýÿ.ºýÿ.¹ýÿ/ºüÿ.»ýÿ/»ýÿ0»þÿ0¼ÿÿ0½ÿÿ/»þÿ.»üÿ.»üÿ/»ýÿ/»üÿ.ºýÿ.ºýÿ/»ýÿ/»ýÿ/»þÿ0¼þÿ/¼þÿ.ºýÿ.¹üÿ.ºüÿ/»üÿ/ºüÿ.ºüÿ/»ýÿ/¼þÿ0»þÿ/ºþÿ/»ýÿ/ºýÿ0»ýÿ0½þÿ0¼þÿ/»þÿ0¼ÿÿ/¼þÿ/»ýÿ/»ýÿ/»ýÿ.»ýÿ/¼ýÿ.»ýÿ.ºýÿ/»ýÿ/»þÿ/ºþÿ.ºüÿ1»üÿ0ºýÿ/¹üÿYÇüÿ°åþÿôûþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîùþÿ–ÜýÿGÃüÿ0¼ýÿ1½ýÿ4¾ýÿ0¼ýÿ0¼ýÿ0»ýÿ1¼ýÿ1½ýÿ1½þÿ2¼þÿ2½þÿ1½þÿ1½ýÿ1½ýÿ0¼üÿ/¼üÿ0¼ýÿ0¼ýÿ0»üÿ/»üÿ0»ýÿ1¼þÿ1½þÿ1½ýÿ0»üÿ/»üÿ0»ýÿ1¼ýÿ1¼ýÿ0»üÿ0¼üÿ3½ýÿ4¾þÿ4½þÿ1¼ýÿ0»ýÿ1¼þÿ1½þÿ3½ýÿ4¿þÿ3¾þÿ2½þÿ0¼ýÿ0¼ýÿ1¼ýÿ1½þÿ1½þÿ0¼ýÿ/»üÿ0»üÿ0¼ýÿ0½þÿ0½üÿ2½ýÿ1¼ýÿ0»üÿ[Éüÿ°åþÿôûþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿìùþÿÜôþÿÛóþÿÜôþÿÜôþÿÜôþÿÜôþÿÜôþÿÜôþÿÜôþÿÝôÿÿÝôþÿÚóþÿÚóþÿáõþÿùýÿÿýþþÿÏïþÿrÑýÿ2¾ýÿ3¾þÿ3¾ýÿ2½üÿ4¿þÿ3¾þÿ2½ýÿ2¾þÿ3¾þÿ3½ýÿ2½ýÿ2¾ýÿ3¾ýÿ4¾þÿ2½ýÿ0¼üÿ2½þÿ2½ýÿ1¼ûÿ0»ûÿ1¼üÿ3¾ýÿ2¾ýÿ2½üÿ1¼üÿ1½ýÿ2½ýÿ2½ýÿ3¿þÿ2½þÿ1¼ýÿ2¾ýÿ3¿þÿ2¾þÿ1¼üÿ2½ýÿ2¾þÿ1½ýÿ2½ýÿ2¾ýÿ2¿ýÿ2¾þÿ2½þÿ3½ýÿ3¾ýÿ3¾þÿ3½þÿ2½ýÿ2¼üÿ1¼üÿ2½ýÿ3¾þÿ3¾ýÿ4¾ýÿ1¾ýÿ2¾ýÿ_Ìýÿ´çþÿõûþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿûþÿÿØóÿÿàþÿuÓýÿuÔýÿyÔýÿxÔýÿyÕþÿxÕþÿwÓýÿwÓýÿxÔýÿyÕþÿyÔýÿvÔýÿuÓýÿƒÙþÿ¾ëþÿûýþÿüþþÿ°æýÿWÉüÿ5¿ýÿ4¿üÿ7Àüÿ7Àþÿ5Àýÿ2¿üÿ2¾üÿ2½üÿ3½ûÿ4¾ýÿ4¿ýÿ4¿ýÿ4¾þÿ3¾þÿ2¾ýÿ7Àýÿ3¾üÿ2½ûÿ@ÁüÿCÃüÿ;Áüÿ3¾üÿ3¾üÿ5¿ýÿ4Àýÿ3¾üÿ4¾üÿ5Áþÿ4¿ýÿ3½üÿ4¿üÿ4¿ýÿ4¿ýÿ3¾ýÿ5Àýÿ5Áþÿ4¿þÿ3¾ýÿ4¾ýÿ4Àýÿ4¿þÿ4¿þÿ5Àþÿ5Àþÿ4¿þÿ4¿ýÿ4¿þÿ5Àþÿ3¾ýÿ3¿ýÿ4¿ýÿ5¾ýÿ7¿üÿ4¾üÿ4¿þÿeÎþÿ¾êþÿøüþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýþÿÿÿÿÿðúþÿ’ÜüÿOÈüÿ>Âýÿ<Âüÿ?Ãüÿ<Áüÿ>Âýÿ=Ãþÿ<Âýÿ<Àüÿ;Áüÿ=Âýÿ=Áüÿ>Áüÿ9ÀüÿAÄýÿ}×ýÿ×òþÿÿÿÿÿñúþÿ¥âýÿYËýÿ6Àüÿ6Àüÿ5¿üÿ9Àüÿ6¿üÿ5¿üÿ5¾ûÿ5¿ûÿ5¿üÿ6Àýÿ6Àýÿ7¿ýÿ9Àýÿ5Àýÿ5Àüÿ5Àüÿ^ÌüÿÚýÿxÔýÿDÄüÿ4¿üÿ5Àýÿ6Áýÿ6Áýÿ5Àüÿ6¿üÿ6Àþÿ5Àýÿ5¿üÿ5Àüÿ5Àüÿ5Àüÿ6Àýÿ6Áýÿ7Áýÿ6Àþÿ6¿þÿ6Àþÿ6Áýÿ5Àüÿ4¿ýÿ6Àþÿ7Âþÿ6Âþÿ6Àýÿ5¿ýÿ6Àþÿ7Âþÿ6Àþÿ5¿ýÿ5¿üÿ8¿ûÿ4¾ûÿ5ÀýÿsÓýÿÐðþÿûýþÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿæ÷þÿXÊûÿ7Áüÿ8Âýÿ7Âüÿ6Áüÿ6Àüÿ7Áýÿ7Ãþÿ6Âþÿ6Àüÿ5¿üÿ6Àüÿ6Áüÿ7Àûÿ7Àûÿ7ÁüÿLÈüÿ•Þýÿèøþÿÿÿÿÿíùþÿ¤ãþÿ_Íýÿ;Âüÿ5¿ûÿ6Àûÿ7Áüÿ7Àüÿ7Áüÿ8Âüÿ7Áüÿ7Áüÿ7Áüÿ7Áüÿ7Áýÿ7Âýÿ9ÁûÿbÎüÿ¯æþÿåöþÿªåþÿLÈýÿ6Áýÿ7Âýÿ8Ãýÿ8Âýÿ8Âýÿ7Áüÿ6Àüÿ7Àýÿ7Âýÿ7Âýÿ6Áûÿ6Àûÿ7Áýÿ7Áýÿ7Áüÿ8Áüÿ8Áýÿ7Áýÿ7Âüÿ6Áüÿ6Àüÿ7Àýÿ8Âþÿ8Ãþÿ8Áüÿ6¿üÿ7Áýÿ9Ãÿÿ8Âþÿ6Àýÿ6Áüÿ8Àüÿ6Àûÿ6Áüÿ‡Úýÿäöþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýþÿÿÿÿÿç÷þÿ]Íýÿ9Ãýÿ9Äþÿ9Äýÿ8Ãýÿ9Ãþÿ9Ãýÿ:Åþÿ9Äþÿ8Âýÿ8Áüÿ8Ãýÿ8Ãþÿ8Ãýÿ9Âüÿ9Ãýÿ8ÃüÿUËüÿ±çþÿõüÿÿÿÿÿÿñúþÿ»êýÿ{ÖüÿEÅüÿ8Âüÿ8Ãüÿ8Ãýÿ:Ãþÿ;Äþÿ9Ãüÿ8Âûÿ8Âûÿ9Âüÿ9ÃüÿFÇüÿ{Öüÿ½êýÿöüÿÿÿÿÿÿ¾ëÿÿ^Îþÿ:Âüÿ9Ãýÿ;Äþÿ:Ãýÿ9Ãýÿ9Ãýÿ8Âûÿ8Âüÿ9Ãýÿ:Äþÿ8Âüÿ7Áûÿ8Âýÿ9Ãýÿ9Âüÿ9Âûÿ9Âûÿ8Âûÿ7Áûÿ8Âüÿ:Äþÿ9Âüÿ9Âüÿ9Âüÿ9Âüÿ9Âüÿ9Ãüÿ9Âýÿ9Ãýÿ9Äýÿ9Ãþÿ8Âýÿ9ÃýÿIÇýÿ¡âþÿöüþÿÿÿÿÿþþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûþþÿÿÿÿÿòûþÿ âþÿ\ÎýÿGÈþÿIÉýÿJÉýÿAÆýÿ<Äýÿ:Åüÿ:Äüÿ9Äýÿ;Åýÿ<Æþÿ<Æÿÿ;Äýÿ<Ãýÿ>Åþÿ:Äýÿ9ÃüÿeÐüÿ®æþÿóûþÿÿÿÿÿýþþÿÎðþÿ¡âýÿ}ØýÿeÑüÿNÉüÿDÇýÿAÅýÿ@ÅüÿEÆûÿQÊûÿfÑüÿ~Øýÿ¡âýÿÐðþÿõûþÿÿÿÿÿÿÿÿÿÐñþÿ}×ýÿBÅüÿ:Ãüÿ=Äýÿ:Ãýÿ:Ãýÿ9Ãüÿ9Äüÿ:Äýÿ;Äþÿ;Äþÿ:Ãüÿ9Ãüÿ:Äýÿ;Åþÿ;Äýÿ:Ãüÿ;Ãûÿ;Ãüÿ9Ãüÿ:Äýÿ;Äýÿ;Ãüÿ:Ãüÿ:Ãüÿ:Ãüÿ:Ãüÿ9Ãüÿ:Ãüÿ:Ãüÿ;Åüÿ;Äýÿ:Äýÿ=ÄüÿiÒýÿ¿ìþÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿýþþÿå÷þÿ­æýÿ†ÛýÿˆÛýÿpÔüÿKÈüÿ;Äüÿ:Äûÿ9Äûÿ;Åýÿ=Æþÿ=Çþÿ=Æþÿ=Åýÿ=Åýÿ=Åþÿ?Åýÿ;Äüÿ;ÃüÿdÏüÿ®æýÿç÷þÿÿÿÿÿÿÿÿÿþþÿÿâöþÿ»êýÿ™àüÿ‡Úüÿ€Ùýÿ€Øýÿ‡Ûýÿœáýÿ¼êýÿáöþÿýþÿÿÿÿÿÿÿÿÿÿþþÿÿÿÿÿÿìùþÿ©åýÿRËüÿ;Äüÿ=Äüÿ:Äýÿ:Äüÿ;Äüÿ;Åýÿ<Æþÿ<Åþÿ;Äüÿ;Äüÿ<Åüÿ<Åýÿ<Åýÿ<Åýÿ;Äüÿ<Åýÿ=Åýÿ=Åýÿ<Åüÿ;Äüÿ<Äüÿ=Äüÿ<Äüÿ<Äüÿ;Äüÿ:Äüÿ;Äüÿ;Äûÿ;Äûÿ>Åüÿ;ÅüÿDÇûÿ“ÞüÿßõþÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿõüþÿïúþÿäöþÿŸâþÿSÌýÿ<Æûÿ<Æûÿ=Çýÿ?Çþÿ=Æýÿ<Åûÿ=Æüÿ>Çýÿ>Èýÿ<Çüÿ<Æýÿ=Åýÿ=Åüÿ=ÅûÿWÌûÿ–ßüÿØóþÿÿÿÿÿÿÿÿÿÿÿÿÿ÷üþÿñúþÿíùþÿëùþÿëùþÿíùþÿñúþÿ÷üþÿÿÿÿÿÿÿÿÿÿÿÿÿðúþÿæ÷þÿòûþÿÿÿÿÿ×óþÿrÖþÿ?Æüÿ>Åûÿ<Æüÿ=Çýÿ=Çýÿ=Çýÿ>Æýÿ>Åüÿ=Åüÿ>Åüÿ=Æüÿ<Äûÿ<Äûÿ=Åûÿ=Æüÿ=Æýÿ>Æýÿ>Æüÿ=Åûÿ=Åûÿ>Æýÿ=Åüÿ=Åûÿ=Æýÿ=Æýÿ<Æüÿ=Æüÿ=Åüÿ>Åýÿ@Çþÿ=ÇýÿZÎûÿÁìýÿúýþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³éþÿ\Ðüÿ@Èüÿ@ÈüÿAÉýÿ@Èýÿ>Çüÿ=Æûÿ>Çüÿ?Èýÿ?Èýÿ=Çûÿ>Çüÿ?ÇýÿBÇüÿ>Çûÿ?ÆûÿTÍüÿ|Ùüÿ¨åýÿÑòþÿíúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýþÿå÷þÿÆïþÿ–áýÿßýÿÉïþÿÿÿÿÿóüÿÿ¨æÿÿZÎýÿ>Æûÿ>ÇüÿCÉýÿ@Èýÿ@Èýÿ?Èüÿ?Çüÿ@Çüÿ@Çüÿ?Çüÿ>Æûÿ>Æûÿ?Çûÿ?Çüÿ?Çýÿ@Èýÿ@Èýÿ?Çüÿ>Æüÿ>Çýÿ?Çüÿ?Çüÿ@Èýÿ?Çüÿ>Æûÿ>ÆûÿAÇüÿ?Çýÿ@ÇýÿKËýÿŒÞýÿæ÷þÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿúýþÿÿÿÿÿûþþÿÂíýÿrÖüÿDÊýÿCËýÿDÊýÿAÉüÿ@ÉüÿAÉüÿ@Èüÿ@Èýÿ@Èýÿ?Çûÿ@Çûÿ@ÈüÿAÉüÿBÉüÿBÉüÿBÉýÿ@ÈüÿRÌûÿ‚Ûýÿ¦æþÿ»ìþÿÎðþÿ×óþÿÛôþÿÜõþÿÚõþÿÕóþÿÊðþÿ¼ëýÿ ãýÿyÙüÿDÊýÿCÊýÿßýÿãöþÿÿÿÿÿã÷þÿŠÜýÿBÇüÿ@ÈüÿAÉüÿBÉýÿAÉüÿAÉüÿAÊüÿAÊüÿAÉýÿAÈýÿ@ÈüÿAÊüÿBÉüÿ@ÇüÿAÈüÿBÊýÿBËþÿBÉþÿ@Èýÿ?Èüÿ@ÉüÿBÊýÿAÊýÿ@Èüÿ?Æûÿ?Çûÿ?Èûÿ@ÈûÿAÈüÿyØýÿÊðÿÿûþÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿáöþÿ™âýÿMÍýÿCËýÿGÍýÿCËýÿCËýÿBËýÿAÉúÿBÊûÿBÊýÿAÉûÿAÈûÿBÉüÿCËýÿBËýÿBÊýÿDÊýÿCÊüÿAÊüÿJÌýÿNÎýÿYÑüÿpÕüÿÚüÿˆÝýÿ‹Þýÿ‡Þýÿ}ÛýÿnÖýÿ[ÑýÿMÍüÿGÊûÿBÊüÿBËýÿaÒüÿ·êýÿÿÿÿÿÿÿÿÿÆîýÿu×üÿBÉüÿBÊüÿFËûÿBÉüÿBÊüÿCËýÿCËýÿBÊýÿBÉüÿBÊüÿCËýÿDËýÿBÉüÿBÉüÿCËýÿCËýÿBÊüÿAÉûÿAÊüÿBËüÿCËüÿBÊýÿBÉýÿAÈûÿDÉûÿAÉûÿBÉûÿeÓüÿ´éýÿ÷ýÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿúýÿÿÈðþÿm×ýÿDÌýÿDÌüÿDÌüÿHÍýÿEËüÿBÊûÿDËüÿEÌýÿCÊûÿCÉûÿDÊüÿEÌýÿDËýÿCÊýÿEÊüÿEÊüÿCËüÿDËýÿCËýÿBÊûÿBÉûÿLÌüÿRÏýÿRÎüÿOÎüÿIÍüÿDÌýÿDËýÿCËüÿCÊüÿFËüÿDÌýÿFÌýÿ‡Ýýÿàöþÿÿÿÿÿúýþÿ¼ëýÿn×üÿBÊûÿBÊûÿCËýÿHÌýÿCËýÿDËüÿDÊüÿCÊüÿBÊûÿCËüÿDËýÿDËýÿCÊüÿDËüÿEÌýÿDËüÿCÊûÿDËûÿDÌüÿDÌüÿCËýÿGÌýÿEËýÿCËüÿCÊüÿbÒüÿªçýÿéøþÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿîúþÿ«èþÿhÕüÿEÌüÿEÍüÿEÌûÿEËûÿDËüÿFÍýÿFÍýÿDËûÿDÊûÿFÌüÿFÍýÿFÌüÿEËüÿEËüÿDËûÿEÌûÿGÍýÿFÌüÿEÊûÿCÊûÿEÌüÿGÍýÿGÍýÿEËûÿDËûÿGÍüÿHÍýÿGÌýÿEÌüÿFÍüÿEÍüÿEÍýÿ\Óýÿ åýÿëùþÿÿÿÿÿöüþÿ·ëýÿnÖûÿEËûÿEÍüÿEÍýÿDËüÿDËûÿEËüÿEËüÿDÊûÿCÊûÿEËüÿEÌýÿEÌüÿDËûÿFÍýÿFÍýÿEÌüÿEËûÿFÌüÿFÍýÿEËüÿFÌýÿGÎþÿGÍýÿeÔýÿ£åþÿéùþÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿëùþÿ±êþÿl×ýÿHÎýÿGÍüÿFÍûÿFÍýÿGÎýÿGÎýÿFÍüÿFÌûÿGÍûÿHÎüÿGÎûÿGÎûÿGÎýÿGÎýÿGÍüÿGÍüÿFÍüÿEÍûÿEÍûÿFÎüÿGÎýÿGÎþÿFÌüÿFËúÿGÍüÿHÏýÿGÏýÿEÍûÿEÍûÿFÎüÿFÍüÿFÍüÿeÖüÿºíþÿ÷ýÿÿÿÿÿÿöüþÿÃîýÿ€ÛüÿLÎúÿGÍûÿEÌüÿFËûÿIÍüÿIÎýÿFÌüÿFÌüÿGÍüÿGÎüÿFÍûÿEÌûÿFÍüÿFÍýÿGÎüÿGÍûÿIÎüÿIÎýÿIÌûÿGÎüÿHÏýÿsÙýÿ¶ëýÿêùÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿëùþÿ¼íþÿŠßýÿj×üÿZÔüÿPÐüÿJÏýÿOÑýÿ^ÓüÿbÕüÿXÒüÿKÏýÿIÏýÿHÏüÿIÏüÿHÏüÿHÏüÿIÎüÿGÎüÿFÎûÿGÏûÿIÏüÿJÐþÿIÐýÿHÍûÿGÌúÿIÏüÿHÏüÿGÏûÿFÎûÿGÏüÿGÏüÿIÍûÿHÎûÿIÏüÿtÚüÿ¸ìþÿóüÿÿÿÿÿÿøýþÿÏòýÿ˜ãûÿm×ûÿPÐüÿGÎüÿGÎüÿHÏýÿHÐýÿIÏüÿKÏüÿLÏüÿKÏüÿKÎüÿIÍûÿGÎüÿHÏüÿIÏüÿIÏüÿIÏüÿLÏüÿaÕüÿ‰àýÿÁîýÿðûþÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿüþþÿÿÿÿÿúýþÿßöýÿ»íþÿšäýÿ‡ßýÿ}Ýýÿ‰àþÿ æýÿåýÿxÛýÿOÑþÿJÐþÿKÐþÿJÏüÿIÐüÿJÐüÿJÐüÿJÐüÿHÏüÿHÏûÿIÐüÿJÑýÿJÑüÿIÏûÿIÏûÿJÐüÿIÏûÿGÎúÿHÏûÿIÐüÿIÐüÿIÎûÿLÏûÿJÏüÿIÏüÿzÜýÿÇðþÿöüþÿÿÿÿÿÿÿÿÿêùþÿ½îþÿ‡àýÿ^ÔüÿPÒüÿQÒüÿKÑýÿJÑüÿJÐüÿJÏüÿKÏüÿJÏüÿIÎûÿIÏûÿJÐüÿOÑýÿQÒüÿ]Ôüÿ}Ýýÿ­éýÿÜõýÿûþþÿÿÿÿÿüþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿõüþÿêùþÿã÷þÿÝöþÿæøþÿðûþÿÓóþÿ‘âýÿSÒûÿKÑüÿNÒýÿLÑýÿLÑýÿLÑýÿLÒýÿLÒýÿLÒýÿLÑýÿJÏüÿJÏûÿLÑýÿLÑýÿJÑüÿJÐûÿJÏúÿIÏúÿJÐûÿJÑûÿKÑûÿLÐüÿMÐüÿKÑüÿLÑýÿ[Õýÿæýÿðûþÿÿÿÿÿÿÿÿÿÿÿÿÿöüþÿâ÷þÿÃïþÿ£èýÿ‡áýÿlÙüÿXÓûÿJÐûÿKÐüÿKÏüÿJÏûÿKÐüÿSÒüÿf×ûÿ€Þüÿšäýÿ¹íýÿÛõþÿòûþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçøþÿåüÿTÓûÿLÒüÿOÓüÿLÑüÿLÑüÿLÑýÿMÑüÿLÒüÿLÒüÿMÓýÿLÒüÿKÑûÿLÑüÿLÑüÿLÑûÿLÑüÿLÑûÿLÑûÿKÐûÿKÑûÿLÑüÿMÑüÿMÑüÿKÑûÿLÑüÿ\Õüÿ™åýÿðûþÿÿÿÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿúýÿÿéùÿÿÓôþÿ¿îýÿ­éýÿ¢æüÿœåýÿ˜äüÿ™äüÿ æýÿ«éýÿºíýÿÎòýÿâ÷þÿôüþÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿüþþÿüþþÿüþþÿûþþÿÿÿÿÿÿÿÿÿèùþÿ¨èýÿZÕüÿMÓüÿOÓüÿMÒûÿLÑûÿLÑüÿMÑûÿMÑûÿLÒûÿNÔüÿNÔýÿMÓüÿLÑûÿLÑûÿMÒûÿNÓýÿNÔýÿMÓüÿLÒûÿMÒüÿMÒüÿMÓüÿOÒüÿLÑûÿLÑûÿkÙûÿ³ìýÿõüþÿÿÿÿÿüþþÿýþþÿüþþÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿúþÿÿùýÿÿùýþÿùýþÿúýþÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿüþþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿôüþÿ¿ïýÿlÚûÿMÓûÿOÓüÿOÔþÿNÒüÿMÒúÿMÓüÿNÓüÿOÓûÿOÔûÿNÔüÿNÓüÿOÓüÿNÒüÿNÓüÿQÖþÿPÕýÿNÔüÿNÓýÿOÓüÿOÔüÿOÕýÿQÕýÿNÔüÿNÓûÿ}ÞüÿÌòþÿúýþÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿýþþÿÿÿÿÿÚöþÿ€ßüÿQÓûÿPÔûÿQÕþÿPÔüÿNÓûÿOÕüÿOÕüÿPÔûÿOÔûÿOÔûÿOÔüÿOÔüÿOÔüÿPÔüÿQÕüÿQÕüÿPÕüÿPÕýÿPÕýÿPÕüÿPÕüÿSÖýÿQÖýÿQÖüÿ“åýÿêùþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿüþþÿüþþÿüþþÿýþþÿýþþÿýþþÿýþþÿýþþÿüþþÿüþþÿüþþÿüþþÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿðûþÿ èýÿ`ØûÿOÔûÿPÖûÿSÖüÿPÖüÿPÕüÿPÕüÿPÕüÿPÕûÿPÕûÿPÕüÿPÕüÿQÖüÿQÕûÿPÔúÿPÔúÿQÕüÿQÖýÿQÖýÿQÖüÿRÕüÿRÕüÿRÖüÿbÚýÿ´íþÿþþþÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþþÿþþþÿþþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿûþÿÿÏóþÿ€áüÿPÕúÿPÕúÿT×ûÿSØüÿRÖüÿQÕüÿRÖüÿS×üÿRÖüÿQÖûÿR×üÿS×üÿQÖüÿPÕúÿPÕúÿQÖûÿQÖûÿR×üÿSØýÿV×üÿSÖüÿX×üÿ“æýÿÚöþÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿþþþÿÿÿÿÿõüþÿ²íýÿeÛûÿRÖúÿRÖûÿW×ûÿT×üÿS×ûÿR×ûÿS×ûÿRÖúÿRÖúÿS×ûÿS×üÿR×üÿQ×ûÿR×üÿR×üÿRÖûÿT×ûÿTØýÿTØýÿTØýÿsÞüÿÈòýÿùýþÿþþÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿÿÿÿÿÿÿÿÿâøþÿ éýÿcÛûÿU×ûÿT×ûÿT×ûÿS×úÿR×úÿSÖúÿT×úÿTØûÿSØûÿS×ûÿS×ûÿSØüÿTÙýÿTÙýÿTØüÿS×ûÿT×üÿUÙýÿmßýÿªìþÿîûþÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿàøþÿšèýÿbÜýÿVÙüÿT×úÿWÖùÿU×úÿU×ûÿUÙüÿVÚýÿVÚýÿTØüÿS×ûÿTÙüÿWÙüÿXÙüÿYÙýÿUØüÿVØüÿiÝüÿªìýÿéúþÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿüþþÿÿÿÿÿþþÿÿÚ÷þÿ¥ëýÿràüÿVÙüÿUÙûÿUÙüÿVÙüÿVÚýÿWÚýÿXÚýÿWÙüÿVØûÿUÙûÿVØûÿVÙüÿVÚýÿZÚýÿ}áüÿ°íýÿåùþÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿèùþÿ¸ïýÿƒäýÿgÞþÿ^ÛýÿWÚüÿVÚüÿVÚüÿUÙûÿVÙûÿWÚüÿVÙûÿYØûÿ]ÙûÿhÞüÿ‹æüÿÃñýÿóüþÿÿÿÿÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿõüþÿÝøþÿ¼ñþÿšéýÿ{âûÿeÝûÿXÚûÿVÙúÿWÚûÿ[ÛüÿjÞüÿãüÿ êüÿÀñýÿàøþÿ÷ýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿôüþÿÞ÷þÿËóýÿ½ðýÿ´îýÿ°íüÿ±îýÿ¶ïýÿÀñýÿÏôþÿâøþÿöýþÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿýþþÿýþþÿüþþÿûþþÿûþþÿûþþÿûþþÿûþþÿûþþÿüþþÿýþþÿýþþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿseafile-6.1.5/msi/seafile-top-banner.bmp000066400000000000000000003375221323477647300201320ustar00rootroot00000000000000BMR¿Š|í: Ⱦ  ÿÿÿÿBGRsÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýÿÿÄçÿÿpÆþÿ2­þÿ¢ýÿ¥ÿÿ:°þÿ}ËÿÿÍëþÿüýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿÆèþÿlÄþÿ*¬þÿ£þÿ¢þÿ£ýÿ¤ÿÿ¥ÿÿ¥ÿÿ£þÿ£ÿÿ¤ÿÿ¤þÿ£þÿ¤ÿÿ£þÿ%©ÿÿW¼þÿ¥Ûþÿì÷þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóúþÿ€Íÿÿ¡ýÿ ýÿ žþÿ üÿ žþÿ žýÿ žþÿ¤þÿ‹Ðþÿ÷ûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüýþÿ˜Öþÿ¦ÿÿ žþÿ žþÿ žþÿ ýÿ žþÿ Ÿþÿ Ÿÿÿ  ÿÿ Ÿÿÿ žþÿœýÿ žþÿ žýÿ œýÿ žýÿ Ÿÿÿ žýÿ ýÿN¸þÿÏëþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ{Ëýÿ Ÿþÿ  ÿÿ Ÿÿÿ žýÿ Ÿþÿ žýÿ Ÿýÿ Ÿþÿ Ÿþÿ Ÿÿÿ}Ëýÿöûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©Ýþÿ¡þÿ ýÿ Ÿýÿ Ÿþÿ  ÿÿ Ÿþÿ Ÿýÿ žþÿ  þÿ  ÿÿ Ÿþÿ žþÿ Ÿþÿ  ÿÿ ¡ÿÿ Ÿÿÿ  ÿÿ žþÿ  ÿÿ  ÿÿ Ÿþÿ/¬þÿÑìþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇéÿÿ¢þÿ  þÿ ¡þÿ  þÿ¡þÿ¡þÿ ¡þÿ¡þÿ þÿ  ýÿ¡ÿÿ  ýÿ{Ëýÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì÷þÿ;±üÿ¡þÿ  ýÿ  ýÿ  þÿ¡þÿ  þÿ  þÿ  ýÿ  ýÿ  þÿ  ýÿ¢ÿÿ  ýÿ¡þÿ£ÿÿ¡þÿ¢ÿÿ  ýÿ þÿ  ýÿ Ÿýÿ ŸþÿK¸ýÿîøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpÇÿÿ£ÿÿ¢þÿ  üÿ¢þÿ¢þÿ¤ÿÿ£þÿ¢þÿ¢ÿÿ¡þÿ£þÿ£þÿ¢þÿ€Íÿÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«Þþÿ£üÿ£ÿÿ¢ÿÿ¢þÿ¢ÿÿ§ÿÿL¹ýÿT¼ýÿ1¯ÿÿ¢þÿ£ÿÿ¢þÿ£þÿ¢ÿÿ¡ýÿ¢þÿ£þÿ¢ýÿ¢ýÿ£ÿÿ¢þÿ¡ýÿ¡ýÿ¢þÿ©ÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿN¼ÿÿ¤þÿ¢üÿ¢ýÿ¤þÿ¤ýÿ£þÿ¤þÿ¥ÿÿ£þÿ¢ýÿ¤þÿ£þÿ¤ýÿ¤þÿÎþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠÑþÿ¢ýÿ£ýÿ¥þÿ£þÿ>µþÿ¾æþÿçõþÿì÷þÿÕïÿÿuÉþÿ¤þÿ¤ÿÿ¢ýÿ¢ýÿ£ýÿ¤þÿ£ýÿ£þÿ£þÿ£ýÿ£þÿ¢þÿ¢ýÿ¢þÿ]Àþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]Àýÿ¦þÿ¤þÿ¦ÿÿ¦ÿÿ¦þÿ¥þÿ¤ýÿ£ýÿ¤ýÿ¥þÿ¤þÿ¥ýÿ¥þÿ¥ýÿ¨ÿÿ€Ïþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰Òþÿ¥þÿ¥þÿ¥þÿ(­þÿÉêþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöûþÿkÇþÿ¨ÿÿ¥ÿÿ£ýÿ¤þÿ¦þÿ¤ýÿ¥þÿ¦þÿ¥ÿÿ¥ýÿ¥ýÿ¥þÿ£ýÿ,­ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—Øþÿ¦ýÿ§ÿÿ§þÿ¦ýÿ§þÿ§þÿ¨ÿÿ¥üÿ¦þÿ¦ýÿ§ýÿ§þÿ¦þÿ¦þÿ¦þÿ©ÿÿ„Ñþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥Ýþÿ¨þÿ§þÿ§þÿ^ÂþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍìÿÿ ¬þÿ¨þÿ¨ÿÿ¥ýÿ§þÿ§þÿ¦ýÿ¨ÿÿ¨ýÿ¨ÿÿ¦ýÿ¦üÿ§þÿªýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèöþÿ;µýÿªÿÿ¨þÿ¨ýÿ§ýÿ§ýÿªÿÿ©þÿ©ýÿ§üÿ§ýÿ§üÿ¨ýÿ¨þÿ§ýÿªÿÿªþÿ…Ðýÿùüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßóþÿ>¶þÿ©ÿÿ©þÿqÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìøÿÿ0²ýÿ©þÿ©þÿ©ýÿ§ýÿ§ýÿ©þÿ§ýÿ©þÿªÿÿ¨ýÿ¨þÿ¨þÿ)¬üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿çþÿ1²þÿ©ýÿªþÿªýÿªýÿªÿÿ©üÿ§üÿ©þÿªýÿ©ýÿªþÿ«þÿ©ýÿ©ýÿ«ÿÿ©þÿ‡Óýÿøüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•Øþÿ«þÿªþÿJ¼ýÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæõþÿ.²þÿªýÿ©ýÿ©ýÿ§üÿªþÿ©üÿ¨ýÿªþÿ«þÿ«þÿªýÿ«ÿÿT¿þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËëþÿaÅþÿ3´þÿ­ÿÿ¬þÿ¬ýÿ«þÿ«ýÿ¬ÿÿ¬ÿÿ¬þÿ¬þÿ¬ýÿªýÿ¬ÿÿ«ýÿªýÿ­þÿ‹Õþÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüþÿ€Ñÿÿ#®þÿ¬ýÿ”ØþÿûýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇêþÿ#®þÿªüÿªüÿ«ýÿ«ýÿ¬þÿ¬þÿ«ýÿ¬þÿ«þÿ«ýÿªüÿ¬þÿ›Úþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüÿÿ¾çÿÿC¼ÿÿ®þÿ­ýÿ®ýÿ®ýÿ®þÿ®ÿÿ®ýÿ®ýÿ­ýÿ¬üÿ¯ÿÿ®ýÿ®þÿ °ÿÿ¯þÿŒÖÿÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþþÿªàþÿZÃþÿ6¶þÿ×þÿåöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕýÿ®þÿ¬ýÿ¬ýÿ®þÿ®þÿ­ýÿ®þÿ­ýÿ­ýÿ®þÿ­ýÿ®þÿC»ÿÿãõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãõþÿF½ýÿ °ýÿ"°þÿ!°þÿ#±þÿ ®ýÿ!¯ýÿ!¯ýÿ"±ÿÿ!°ÿÿ ¯þÿ#²ÿÿ ¯þÿ!°ýÿ"±ÿÿ"±ÿÿ#¯ýÿÖþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíøþÿÁèþÿ¹åþÿé÷ÿÿÿÿÿÿÿÿÿÿê÷þÿ?¹ûÿ ¯ýÿ ¯ýÿ®üÿ#°ýÿ2´ýÿ!°þÿ ¯ýÿ!°þÿ ¯þÿ ®ýÿ °þÿ.´þÿ¼çþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­âþÿ$²ýÿ °ûÿ!°üÿ#±þÿ$±þÿ#±ýÿ$³þÿ$²ÿÿ#²þÿ$²þÿ#²ÿÿ$³þÿ"±ýÿ!°üÿ#±ýÿ$²þÿ"±üÿ&²ýÿ×þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€Ñýÿ!°üÿ"°ýÿ#²þÿ#±ýÿ#°ýÿmËþÿOÁýÿ#²ýÿ#²þÿ"°ýÿ"±þÿ@»ÿÿ¸åþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—Ûþÿ#±üÿ$³ýÿ&³ýÿ%³ýÿ$³üÿ&³ýÿ&³ýÿ$²ýÿ%´ýÿ%³üÿ%´þÿ&´þÿ%³ýÿ%´þÿ%³ýÿ%³üÿ$²ûÿ&´þÿ)³ûÿØþÿûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›Üÿÿ*´ýÿ#²üÿ%²ýÿ'µÿÿ&³þÿ$²üÿ\ÆýÿÅëÿÿ<¼ÿÿ&´þÿF¾þÿ†Õþÿ×ñþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”Úþÿ&´üÿ(µþÿ)¶þÿ(¶þÿ(µýÿ&´ûÿ&³ûÿ'´ýÿ'´üÿ(µýÿ&´üÿ'´üÿ(¶ýÿ&´üÿ'´üÿ(µýÿ(µýÿ)·ÿÿ(¶þÿ)µýÿsÏýÿáõþÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿêøþÿ„Ôýÿ,·ýÿ)¶þÿ(µýÿ'µýÿ'µýÿ'µþÿ(¶þÿ;»þÿàôÿÿÝóÿÿÏîþÿçöÿÿúýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ßýÿ*·ýÿ)¶ýÿ*·üÿ*¶üÿ-¹ÿÿ*·üÿ*¶üÿ*¶ýÿ(µüÿ)¶ýÿ+¸þÿ)¶üÿ)¶ýÿ+·ýÿ*¶ýÿ)·ýÿ)¶üÿ,¸ÿÿ)·ýÿ(¶üÿ+¸þÿ@¾þÿŒØýÿÄëþÿåöþÿé÷þÿç÷þÿÊíþÿ—ÛþÿHÀüÿ*µýÿ*·ýÿ+·þÿ,¸ÿÿ*·ýÿ+¸ÿÿ*¸ýÿ(¶üÿ)·þÿ®ãþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃêþÿ;½þÿ,¹ýÿ.ºþÿ-¹ýÿ.ºÿÿ,¹ýÿ,¹ýÿ-ºþÿ,¹ýÿ-ºýÿ-ºýÿ-¹ýÿ-¸þÿ.ºþÿ,¹ýÿ,¹ýÿ.ºþÿ,¹þÿ,¹üÿ,¸üÿ,¸ýÿ-ºÿÿ-ºÿÿ1ºýÿA¿ýÿGÂüÿDÁýÿ4»ýÿ.ºþÿ.ºþÿ-¹üÿ,¸ýÿ,¸üÿ,¸üÿ.ºþÿ.¹þÿ-¹þÿ,¸üÿ-¹ýÿžÞýÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðúþÿ^Éüÿ.ºüÿ/¼ýÿ/»ýÿ.ºýÿ/ºüÿ/¼ýÿ0»þÿ1½ÿÿ0¼þÿ.»üÿ/»ýÿ/»üÿ.ºýÿ/»ýÿ/»þÿ0¼þÿ/»ýÿ.¹üÿ/»üÿ/ºüÿ/»üÿ0¼þÿ0»þÿ/»ýÿ0»ýÿ1½þÿ0¼þÿ0½ÿÿ/»ýÿ/»ýÿ/»ýÿ/¼ýÿ.ºýÿ/»ýÿ/»þÿ.»üÿ0»ýÿ/¹üÿšÝþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðúþÿíùþÿîùþÿîùþÿîùþÿîùþÿîùÿÿîùþÿëøþÿõüþÿÿÿÿÿ¬ãýÿ3½ýÿ3¾þÿ2½üÿ3¾þÿ2½ýÿ2¾þÿ3½þÿ2½ýÿ2¾ýÿ3¾þÿ0¼üÿ2½þÿ1¼üÿ0»ûÿ2½ýÿ2¾ýÿ1¼üÿ1½ýÿ2½ýÿ2¾þÿ1¼ýÿ2¾ýÿ2¾þÿ1¼üÿ2½þÿ1½ýÿ2¾ýÿ2¿ýÿ2½þÿ2½ýÿ3¾þÿ2½þÿ1¼üÿ1¼üÿ2¾þÿ2¾ýÿ1¾ýÿ2½ýÿžàþÿýþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºéþÿeÎýÿbÎýÿbÍýÿdÎþÿbÍýÿbÍüÿcÎþÿcÍýÿaÍýÿyÕþÿç÷þÿøüþÿ{Õýÿ5¿ýÿ4¿üÿ6Àþÿ3¿üÿ2¾üÿ3½ûÿ4¿ýÿ4¿ýÿ4¾þÿ3¾ýÿ4¿ýÿ4¾ûÿPÆüÿ@Âüÿ3¾üÿ5¿ýÿ4Àýÿ4¾üÿ5Áþÿ3¾üÿ4¿üÿ4¿ýÿ4¿ýÿ6Áþÿ4¿þÿ4¾ýÿ4Àýÿ4¿þÿ6Áþÿ5Àþÿ4¿ýÿ5Àþÿ4¿ýÿ4¿ýÿ5¾ýÿ4¾üÿ4¿þÿ®åþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJÆûÿ6Áýÿ6Áüÿ5Àüÿ7Áýÿ6Âþÿ5¿üÿ5Àüÿ6Àüÿ6¿ûÿ7Áüÿ‘Üýÿÿÿÿÿïùþÿ|Öýÿ7Áüÿ5¿ûÿ6Àüÿ6Àüÿ7Áüÿ6Àüÿ7Áüÿ6Àüÿ7Áýÿ6Áûÿ…ÙýÿÒðþÿ[Ìýÿ6Áýÿ7Âýÿ7Âýÿ7Áüÿ6Àýÿ7Áýÿ6Áüÿ6Àûÿ7Áýÿ7Áüÿ8Áýÿ7Áþÿ7Âüÿ5Àüÿ7Àýÿ8Ãþÿ7Àüÿ6Àýÿ9Ãÿÿ6Àýÿ6Àüÿ5¿ûÿ>ÃüÿÎïþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRÊýÿ:Äþÿ9Äýÿ9Ãþÿ:Äýÿ:Åþÿ8Âýÿ9Ãýÿ9Äþÿ9Ãüÿ9Ãýÿ>Äüÿµèþÿÿÿÿÿõüþÿ áýÿLÈüÿ8Ãüÿ9Ãýÿ;Äþÿ9Ãüÿ8Âûÿ:ÃüÿLÈüÿ¢âýÿõüþÿÿÿÿÿwÖþÿ9Âüÿ:Äþÿ:Ãýÿ9Ãýÿ8Âûÿ9Ãýÿ:Äþÿ7Áûÿ9Ãýÿ:Ãýÿ9Âûÿ9Âûÿ7Áûÿ:Äþÿ9Âüÿ9Âüÿ9Âüÿ9Ãüÿ9Âýÿ:Äýÿ9Ãþÿ9Ãýÿ_ÏýÿìùþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊïýÿsÕýÿtÕüÿNÊüÿ;Äüÿ9Äûÿ;Åýÿ=Çþÿ=Æþÿ<Äýÿ=Åþÿ;ÄüÿDÆüÿ²èýÿýþþÿÿÿÿÿç÷þÿ°çýÿ|×üÿjÒüÿiÒüÿ€Øýÿ°çýÿç÷þÿÿÿÿÿÿÿÿÿÿÿÿÿ²èýÿAÆüÿ;Äüÿ:Äýÿ:Äüÿ;Åýÿ<Åþÿ;Äüÿ;Äüÿ<Åýÿ<Åýÿ;Äüÿ=Åýÿ<Åýÿ;Äüÿ<Äüÿ<Äüÿ;Äüÿ:Äüÿ;Äüÿ;Äûÿ;Åüÿ;Äûÿáýÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå÷þÿcÑýÿ=Æûÿ>Çýÿ?Çþÿ<Åûÿ=Æüÿ?Èýÿ<Çüÿ=Æýÿ=ÅüÿAÆûÿ’ÞüÿèøþÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóûþÿÖóþÿòûþÿñúþÿiÔþÿ=Åûÿ=Çüÿ>Çýÿ>Çýÿ>Æüÿ>Åüÿ>Æüÿ<Äûÿ=Åûÿ=Æüÿ>Æýÿ>Æüÿ=Åûÿ>Æýÿ=Åûÿ>Çýÿ=Æüÿ=Æüÿ>Åýÿ>ÇþÿQÌüÿÞõþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóûþÿ|ÚüÿBÊýÿBÊýÿ@Éüÿ@Èüÿ@Èüÿ@Èýÿ?Çûÿ@Èüÿ@Éüÿ@ÈüÿAÉýÿXÎûÿ¡äþÿÎñþÿå÷þÿíúþÿîúþÿêùþÿÜõþÿ¾ìýÿ}ÚüÿGËýÿµéýÿÿÿÿÿÂíþÿGÉüÿ@ÈüÿBÉýÿAÉüÿAÉüÿAÉüÿAÈýÿ@ÈüÿAÉüÿ@ÇüÿAÉýÿBÊþÿ@Èýÿ?ÈüÿAÉýÿAÉýÿ?Æûÿ?Çûÿ?ÈûÿBÈüÿ©çþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸ëþÿEËýÿCÌýÿCËýÿCËýÿAÉúÿCËýÿAÉûÿBÉüÿCËýÿBÊýÿDÊýÿBÊüÿCÊýÿEÌüÿdÒûÿuØüÿxÙýÿm×ýÿYÐýÿBÊüÿBÉûÿCËýÿhÔüÿïúþÿÿÿÿÿ™áüÿBÊüÿBÊûÿBÉüÿCËýÿCËýÿBÉüÿBÊüÿDËýÿBÉüÿCËýÿCËýÿBÉûÿBËüÿCËüÿBÊýÿBÉüÿAÉûÿBÉûÿ…Üýÿóûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóûþÿ‡ÞýÿEÌüÿDÍüÿEËûÿDËüÿFÍýÿCÊûÿEËüÿFÍýÿEËüÿDËüÿDËûÿEÍýÿCÊûÿCÊûÿFÍýÿFÌüÿDËûÿFÍýÿEÌýÿDÌüÿEÍüÿEÍýÿäýÿÿÿÿÿøýþÿ‘àüÿBÊûÿEÍýÿDËüÿDËûÿEËüÿCÊûÿDËüÿEÌýÿDËûÿFÍýÿEÌüÿEËûÿFÍýÿEËüÿFÍþÿEÌýÿÜýÿêùþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìúþÿŒàýÿHÎýÿFÍûÿGÎýÿGÎýÿGÍüÿGÍûÿHÎüÿGÎûÿHÎýÿGÎüÿGÍüÿEÍûÿFÎûÿGÎýÿGÎþÿFËúÿHÎüÿGÏýÿEÍûÿFÎüÿFÍüÿNÐüÿ¾îþÿÿÿÿÿöüþÿ¤åýÿOÏúÿFÍüÿEÌûÿGÎýÿFÍüÿGÍüÿGÎüÿFÍûÿFÍüÿFÎüÿGÎûÿGÎýÿGÍûÿHÏýÿ”âýÿîúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõüþÿÅïýÿáýÿqÙüÿoÙþÿ‘âýÿyÛýÿJÐþÿJÐþÿIÏüÿIÐüÿJÏüÿHÏüÿHÏûÿJÑýÿIÐüÿHÎûÿJÐüÿGÎúÿHÏûÿIÐüÿIÎûÿJÏüÿUÒüÿÄðþÿÿÿÿÿýþþÿÑòýÿÞýÿHÏüÿIÐüÿJÑýÿJÐüÿJÏüÿJÏüÿHÎûÿJÐüÿJÐýÿKÐüÿuÛýÿÀîýÿ÷ýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøýþÿòûþÿòûþÿùýþÿ§èýÿJÐûÿLÒýÿLÑýÿLÑýÿLÒýÿLÒýÿLÑýÿJÏûÿLÑýÿKÑüÿJÐûÿJÏúÿJÐûÿKÑûÿLÐüÿKÑüÿLÑýÿ„ßüÿüþþÿÿÿÿÿÿÿÿÿõüþÿÐóþÿ çýÿvÛüÿ[ÔûÿOÑüÿLÏûÿXÓüÿqÚûÿ˜äýÿÅðþÿñûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹íýÿLÒüÿMÓüÿLÑûÿLÑüÿMÑûÿLÒûÿNÔýÿMÓüÿLÑûÿLÑûÿNÓýÿMÓüÿLÑûÿMÒüÿMÒüÿLÑûÿLÑûÿ™åýÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿ÷üþÿîúþÿêùþÿéùþÿíúþÿõüþÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×õþÿa×ûÿNÓûÿPÔþÿMÒúÿNÔüÿOÓûÿOÔûÿNÓüÿOÓüÿNÓüÿQÖþÿOÔüÿOÔýÿOÔüÿOÕýÿOÕýÿOÔûÿÂïýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýþÿ„áüÿOÔûÿQÖüÿPÕüÿPÕüÿPÕüÿPÕûÿPÕüÿPÕüÿQÕûÿPÔúÿQÕüÿQÖýÿQÖüÿQÕüÿRÖüÿgÜýÿîúþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊòþÿW×úÿPÕúÿSØüÿRÖüÿRÖüÿS×üÿQÖûÿS×üÿR×üÿPÕúÿQÖûÿQÖûÿSØýÿS×üÿSÖüÿ³íýÿüþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþþÿ¡éýÿT×ûÿT×ûÿT×ûÿR×úÿSÖúÿS×úÿS×ûÿS×ûÿSØüÿTÙýÿS×ûÿS×üÿUÙýÿ‰äýÿôüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõüþÿ™èýÿWÚýÿT×úÿS×úÿUØüÿVÚýÿVÚýÿS×ûÿUÙüÿVÙüÿUÙýÿVØüÿƒãüÿéúþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ýþÿ´îýÿiÞýÿWÚýÿVÚüÿVÚüÿUÙûÿVÙüÿVÙûÿVØûÿ^Üüÿ¤êýÿðûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿçúþÿ³îýÿ…äüÿhÝûÿ_ÛúÿgÞüÿ~ãüÿªìüÿÚ÷þÿûþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿseafile-6.1.5/msi/seafile.ico000066400000000000000000003453571323477647300160700ustar00rootroot00000000000000 hf  ¨Î00 ¨%v@@ (B;€€ (F} En…(    SSS©©©2©©©2SSSÈÈÈP¸ÑæÄ“ÉøüzÀýÿzÀýÿ“Éøü¸ÑæÄÈÈÈPsssÊ×â£t¿ýÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿt¿ýÿÊ×â£sssÍÛç¥S²þÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿS²þÿÍÛç¥ÜÜÜTrÁýÿ8©ÿÿ<ªÿÿN²ÿÿ8©ÿÿ8©ÿÿ8©ÿÿK±ÿÿW¶ÿÿW¶ÿÿ=«ÿÿrÁýÿÜÜÜT»ÛòÊ=®þÿ=®þÿ¾äÿÿÿÿÿÿœÕÿÿ=®þÿX¹þÿáòÿÿàòÿÿÿÿÿÿÖîÿÿ=®þÿ»ÛòÊÆÆÆ“ÒüþA³þÿA³þÿ‹Ñþÿþÿÿÿÿÿÿÿ×þÿP¹þÿ‹Ñþÿ‰ÏþÿÿÿÿÿíøÿÿA³þÿ“ÒüþÆÆÆéééyÍýÿK½þÿÂéÿÿÕïÿÿ´äÿÿÕðÿÿÅêÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£ÞþÿK½þÿK½þÿyÍýÿîîî>èèè“ØüÿPÃþÿuÐþÿÜóÿÿ÷üÿÿßôÿÿÊíÿÿÏïÿÿþÿÿÿÓðÿÿ[ÇþÿPÃþÿPÃþÿ“Øüÿèèè»åúÖUÈþÿUÈþÿWÈþÿéøÿÿÿÿÿÿÕñÿÿUÈþÿWÈþÿUÈþÿUÈþÿUÈþÿUÈþÿ»åúÖóöøeuÓýÿYÌýÿYÌýÿhÑýÿŽÝþÿbÏýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿuÓýÿóöøeëëëÓíú¼eÑýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]ÑýÿeÑýÿÓíú¼ëëë÷÷÷ÒíúÀuÖýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿuÖýÿÒíúÀ÷÷÷÷÷÷ñöúo·æûâÝüÿyØýÿyØýÿÝüÿ·æûâñöúo÷÷÷÷÷÷úúú.úúúRúúúRúúú.÷÷÷ü?àÀ€€€€€€Ààø( @   jjj9¡¡¡\°°°m°°°m¡¡¡\jjj9    [ÎÎθéééòêóúÿÌåûÿ½Þüÿ½ÞüÿÌåûÿêóúÿéééòÎÎθ   [ ¡¡¡YàààÜÜíûÿŒÉýÿN­þÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/ŸÿÿM­þÿŒÉýÿÜíûÿàààÜ¡¡¡YIIIÎÎάåðùþyÁýÿ2¡ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ2¡ÿÿyÁýÿåðùþÎÎάIIIsssáááѽàüÿ@¨ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ@¨ÿÿ½àüÿáááÑsssbbbäääÒªØüÿ5¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ5¤ÿÿªØüÿäääÒbbbÚÚÚ±¹Þüÿ6¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ6¦ÿÿ¹ÞüÿÚÚÚ±ÂÂÂ`ßîûÿ@¬ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ@¬ÿÿßîûÿÂÂÂ`QQQ îîîänÀþÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿH°ÿÿsÃÿÿW·ÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿH°ÿÿtÃÿÿwÄÿÿwÄÿÿwÄÿÿuÄÿÿN³ÿÿ9ªÿÿ9ªÿÿnÀþÿîîîäRRR ÓÓÓfÌçûÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ_»ÿÿóúÿÿÿÿÿÿþÿÿÿšÔÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿS¶ÿÿïøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýÿÿyÆÿÿ;¬ÿÿ;¬ÿÿÌçûÿÓÓÓféééÅ~Éýÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ¨Ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›Õþÿ>¯þÿ>¯þÿ>¯þÿ•Óþÿþÿÿÿ—ÔþÿŠÏþÿøüÿÿÿÿÿÿÿÿÿÿÿÿÿÿçõÿÿ>¯þÿ>¯þÿ~Éýÿéééʼn‰‰òöøûH´þÿ@±þÿ@±þÿ@±þÿ@±þÿyÉþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›Öþÿ@±þÿ@±þÿzÉþÿë÷ÿÿ@±þÿ@±þÿÂæÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýÿÿ@±þÿ@±þÿH´þÿòöøü‰‰‰×××IÐêûÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿsÇþÿûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›×þÿB´þÿC´þÿ”ÕþÿoÆþÿC´þÿßòÿÿþÿÿÿÿÿÿÿÿÿÿÿ»äÿÿB´þÿB´þÿB´þÿÐêûÿ×××Iæææo³àüÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿ^Àþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÚþÿF·þÿE·þÿE·þÿžÙþÿÿÿÿÿóúÿÿºäÿÿ§ÝÿÿL¹þÿE·þÿE·þÿE·þÿ³àüÿæææoìì삤ÛüÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿT¾þÿüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàóÿÿ½æÿÿÝòÿÿÿÿÿÿÿÿÿÿÿÿÿÿbÃþÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿ¤Ûüÿììì‚îîî„£ÛüÿJ¼þÿJ¼þÿJ¼þÿªßÿÿ¹åÿÿ¹åÿÿœÚþÿ­áÿÿÿÿÿÿÿÿÿÿÿÿÿÿåõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ_ÄþÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿ£Ûüÿîîî„îîîu­ßüÿL¿þÿL¿þÿL¿þÿ©àÿÿýþÿÿÿÿÿÿÿÿÿÿ›ÛþÿŠÕþÿ¶åÿÿ ÝþÿZÄþÿ×ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâõÿÿM¿þÿL¿þÿL¿þÿL¿þÿL¿þÿL¿þÿ­ßüÿîîîuíííTÄèûÿOÁþÿOÁþÿOÁþÿOÁþÿÕðÿÿÿÿÿÿÿÿÿÿÿÿÿÿáôÿÿ¹æÿÿÅêÿÿåöÿÿ}Òþÿøýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûþÿÿ|ÑþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿÄèûÿíííTÞÞÞ!èôúÿQÄþÿQÄþÿQÄþÿQÄþÿ`Éþÿ±åÿÿÃëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆìÿÿtÐþÿÓðÿÿüþÿÿýþÿÿ×ñÿÿzÒþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿèôúÿÞÞÞ!÷÷÷ÚsÏýÿTÆþÿTÆþÿTÆþÿTÆþÿTÆþÿ]ÉþÿúþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖòÿÿTÆþÿTÆþÿWÈþÿWÈþÿTÆþÿTÆþÿTÆþÿTÆþÿTÆþÿTÆþÿTÆþÿTÆþÿsÏýÿ÷÷÷Úõõõ€²ãüÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿ¬åþÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿƒ×þÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿ²ãüÿõõõ€ëëëò÷úöeÍýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿ‘ÝþÿÅíþÿ¾ëþÿ{ÖýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿeÍýÿò÷úöêêê÷÷÷†½æûÿZÍýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÎýÿZÍýÿ½æûÿ÷÷÷†ëëë ùùù׎Ùüÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\ÐýÿŽØüÿùùù×ëëë õõõ+ó÷úðÕüÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^ÒýÿÕüÿó÷úðõõõ+÷÷÷=ò÷úò‰×üÿ_Óýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ_Óýÿ‰×üÿò÷úò÷÷÷=÷÷÷0ùùúÞ²âûÿdÑýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿdÑýÿ²âûÿùùúÞ÷÷÷0÷÷÷ùùù˜êôúü¡ÞüÿgÑýÿaÕýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿaÕýÿgÑýÿ¡Þüÿêôúüùùù˜÷÷÷øøø)úúúš÷ùúñÏêûÿ«àüÿ•ÛüÿŠÙüÿŠÙüÿ•Ûüÿ«àüÿÏêûÿ÷ùúñúúúšøøø)÷÷÷ùùùBúúúxúúú›úúú¬úúú¬úúú›úúúxùùùB÷÷÷ÿÿÿÿÿðÿÿ€ÿþü?øðààÀÀÀ€€€€€€€€ÀÀÀààðøü?þÿ€ÿÿàÿÿÿÿÿ(0` $  !!!3{{{`ƒ«««›±±±¦±±±¦«««›ƒ{{{`!!!3lllU³³³ªÖÖÖäöööýúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿöööýÖÖÖä³³³ªlllU –––zÕÕÕÞùùùþøùúÿÏçûÿœÐüÿs½ýÿT°þÿ@¦ÿÿ6¢ÿÿ6¢ÿÿ@¦ÿÿT°þÿs½ýÿœÐüÿÏçûÿøùúÿùùùþÕÕÕÞ–––z `ÚÚÚàúúúÿâïûÿŽÊýÿE©þÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/ŸÿÿE©þÿŽÊýÿâïûÿúúúÿÚÚÚà`+++¼¼¼¯øøøþçñúÿ€Äýÿ4¢ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ4¢ÿÿ€Äýÿçñúÿøøøþ¼¼¼¯+++aaa4ÛÛÛÚúúúÿ­Øüÿ>§ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ>§ÿÿ­ØüÿúúúÿÛÛÛÚaaa4sss>çççêó÷úÿyÂýÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿyÂýÿó÷úÿçççêsss>ppp5éééëíôúÿa·þÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿa·þÿíôúÿéééëppp5LLLâââÞñöúÿ_·þÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ4¥ÿÿ_·þÿñöúÿâââÞLLLÐÐжøùúÿrÀýÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿrÀýÿøùúÿÐÐ欬¬iúúúÿŸÓüÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿŸÓüÿúúúÿ¬¬¬iNNNëëëéÚìûÿ=«ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ=«ÿÿÚìûÿëëëéNNNÈÈȈúúúÿmÀþÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿZ¸ÿÿŽÏÿÿÎÿÿV·ÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ?­ÿÿ~Çÿÿ–Òÿÿ–Òÿÿ–Òÿÿ–Òÿÿ–Òÿÿ–Òÿÿ’Ðÿÿg¾ÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿmÀþÿúúúÿÈÈȈCCCîîîìËçûÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ›Ôÿÿþþÿÿÿÿÿÿÿÿÿÿüþÿÿ—Óÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿG±ÿÿÛðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀäÿÿ@®ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿÊçûÿîîîìBBBÃÃÃfúúúÿvÅýÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ_¼þÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿšÕþÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ¡Øÿÿÿÿÿÿÿÿÿÿùýÿÿöûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡Øÿÿ=®þÿ=®þÿ=®þÿvÅýÿúúúÿÃÃÃfááá¾çóúÿA°þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿËþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿšÕþÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿÈèÿÿÿÿÿÿÎëÿÿJ´þÿC±þÿ¬Ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë÷ÿÿ>¯þÿ>¯þÿ>¯þÿA°þÿçóúÿááá¾IIIõõõ÷®Üüÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿX»þÿûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™Õþÿ@±þÿ@±þÿ@±þÿ@±þÿ­Þÿÿÿÿÿÿ|Êþÿ@±þÿ@±þÿH´þÿüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ@±þÿ@±þÿ@±þÿ@±þÿ®Üüÿõõõ÷HHHÁÁÁIúúúÿ}ÊýÿA³þÿA³þÿA³þÿA³þÿA³þÿA³þÿA³þÿA³þÿ…Îþÿõûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™ÖþÿA³þÿA³þÿA³þÿW¼þÿíøÿÿ¢ÚÿÿA³þÿA³þÿK·þÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛñÿÿA³þÿA³þÿA³þÿA³þÿ}ÊýÿúúúÿÁÁÁIÛÛÛzúúúÿV¼þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿQºþÿöûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™×þÿC´þÿC´þÿC´þÿU¼þÿŸÙþÿgÃþÿC´þÿƒÎþÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿþÿÿÿÌþÿC´þÿC´þÿC´þÿC´þÿV¼þÿúúúÿÛÛÛzåååŸïöúÿF·þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿgÄþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™×þÿE¶þÿD¶þÿD¶þÿD¶þÿD¶þÿU¼þÿçöÿÿÿÿÿÿÿÿÿÿ»åÿÿýþÿÿìøÿÿˆÑþÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿF·þÿïöúÿåååŸêêê¸ÛîûÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿoÈþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»åÿÿcÃþÿH¸þÿLºþÿÎþÿæõÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·ãÿÿZÀþÿI¹þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿÛîûÿêêê¸íííÅÐëûÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿQ½þÿùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöüÿÿûýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐíÿÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿÐëûÿíííÅïïïÇÎêûÿI»þÿI»þÿI»þÿI»þÿI»þÿyÍþÿ–Øþÿ–Øþÿ–Øþÿ–ØþÿmÉþÿ©ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌìÿÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿÎêûÿïïïÇîîî¿ÒìûÿK½þÿK½þÿK½þÿK½þÿK½þÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçöÿÿZÃþÿ´äÿÿýþÿÿÿÿÿÿÿÿÿÿýþÿÿ´äÿÿœÛþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªàÿÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿÒìûÿîîî¿îîîªâñûÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿ|ÐþÿÀèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛòÿÿdÇþÿfÈþÿ×þÿ×þÿfÈþÿRÁþÿ_ÆþÿùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿjÊþÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿâñûÿîîîªííí‰õøúÿQÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿ~ÒþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýÿÿÁéÿÿ™Ûþÿ“Ùþÿ°ãÿÿíùÿÿÒþÿ¡Þþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±äÿÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿQÁþÿõøúÿííí‰ééé\úúúÿmËýÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿQÃþÿ¾éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæöÿÿ\Çþÿ±äÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾éÿÿSÄþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿmËýÿúúúÿééé\ÓÓÓ#úúúÿ–ÙüÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿÔþÿŸßþÿ§áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍîÿÿRÄþÿ€ÔþÿÎïÿÿùýÿÿÿÿÿÿûþÿÿÔðÿÿˆ×þÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿ–ÙüÿúúúÿÓÓÓ#öööÛÇèûÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿhÍþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐïÿÿSÆþÿSÆþÿSÆþÿUÇþÿ_ÊþÿVÇþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿÇèûÿöööÛòòò‰öøúÿ`ÉþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿÖòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÜþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿ`Éþÿöøúÿòòò‰ååå)úúúý ÜüÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿqÒþÿñûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈîþÿXÊþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿ Üüÿúúúýååå)ööö¶êôúÿ\ÊýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿmÑýÿÄíþÿõüÿÿþÿÿÿèøÿÿ£ãþÿZÌýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿ[Êýÿéôúÿööö¶îîî8úúúý¤ÝüÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿ[Íýÿ^ÎýÿZÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿ¤Ýüÿúúúýîîî8ööö¤ôøúÿmÎýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[ÎýÿmÎýÿôøúÿööö¤ëëëùùùé×íûÿ]Ìýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ]Ìýÿ×íûÿùùùéëëëôôôIúúúü»äûÿ[Íýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ[Íýÿ»äûÿúúúüôôôI÷÷÷uúúúÿ®àüÿ[Îýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ[Îýÿ®àüÿúúúÿ÷÷÷u¥¥¥÷÷÷‰úúúÿµâûÿ]Îýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ]Îýÿµâûÿúúúÿ÷÷÷‰¥¥¥½½½øøø}úúúþÍêûÿgÍýÿ`ÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿaÔýÿ`ÔýÿgÍýÿÍêûÿúúúþøøø}½½½÷÷÷VúúúñíõúÿÖüÿ\ÎýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿ\ÎýÿÖüÿíõúÿúúúñ÷÷÷V÷÷÷"ùùù½úúúÿ×íûÿ†Ôüÿ[ÍýÿbÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿbÖýÿ[Íýÿ†Ôüÿ×íûÿúúúÿùùù½÷÷÷"çççùùùTúúúÖúúúÿãòúÿ¥ÜüÿuÐýÿYËýÿ^ÑýÿbÖýÿc×ýÿc×ýÿc×ýÿc×ýÿbÖýÿ^ÑýÿYËýÿuÐýÿ¥ÜüÿãòúÿúúúÿúúúÖùùùTçççðððùùùNúúú³úúúùúúúÿðöúÿÍéûÿ²ßüÿ£ÛüÿÙüÿÙüÿ£Ûüÿ²ßüÿÍéûÿðöúÿúúúÿúúúùúúú³ùùùNððð÷÷÷ùùùTúúúúúú¿úúúâúúúöúúúþúúúþúúúöúúúâúúú¿úúúùùùT÷÷÷%%%ðððööööööððð%%%ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿþÿÿøÿÿàÿÿÀÿÿ€ÿÿÿþü?øøððààÀÀÀÀÀÀÀÀÀÀÀÀÀÀààððøøü?þÿÿÿÿÿÀÿÿàÿÿðÿÿü?ÿÿÿ€ÿÿÿÿü?ÿÿÿÿÿÿÿÿ(@€ @   0GGG[‚‚‚‡¨¬¬¬¿···Ì»»»Ò»»»Ò···Ì¬¬¬¿¨‚‚‚‡GGG[0222L“““šÁÁÁÕèèèõúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿèèèõÁÁÁÕ“““š333L$}}}ÅÅÅ×õõõüúúúÿúúúÿúúúÿíôúÿÇãûÿ©Õüÿ’ËýÿƒÄýÿ|Áýÿ|ÁýÿƒÄýÿ’Ëýÿ©ÕüÿÇãûÿíôúÿúúúÿúúúÿúúúÿõõõüÅÅÅ×}}}$ˆˆˆŠÚÚÚèúúúÿúúúÿøùúÿÆãûÿ‡ÆýÿQ®þÿ0Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ0ŸÿÿP®þÿ‡ÆýÿÆãûÿøùúÿúúúÿúúúÿÚÚÚ興ˆŠ eeefÓÓÓàúúúÿúúúÿèòúÿ”ÌýÿE©þÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/ŸÿÿE©þÿ”ÌýÿèòúÿúúúÿúúúÿÓÓÓàeeef $¬¬¬°öööüúúúÿêóúÿ‰Èýÿ7£ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ7£ÿÿ‰Èýÿêóúÿúúúÿöööü¬¬¬°#LLLEÕÕÕÝúúúÿùúúÿ©Öüÿ>§ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ>§ÿÿ©ÖüÿùúúÿúúúÿÕÕÕÝLLLElll_èèèðúúúÿçòúÿiºþÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿ1¢ÿÿiºþÿçòúÿúúúÿèèèðlll_zzziïïïöúúúÿÏçûÿF«ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿF«ÿÿÏçûÿúúúÿïïïözzzixxxaððð÷úúúÿ½àüÿ:¦ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ:¦ÿÿ½àüÿúúúÿððð÷xxxadddHìììòúúúÿ»ßüÿ8¦ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ8¦ÿÿ»ßüÿúúúÿìììòdddH666&áááãúúúÿÈäûÿ:§ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ:§ÿÿÈäûÿúúúÿáááã666& ÇÇǺúúúÿÞîûÿC¬ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿC¬ÿÿÞîûÿúúúÿÇÇǺ šššqúúúÿõøúÿ\·þÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ7§ÿÿ\·þÿõøúÿúúúÿšššq;;;"êêêìúúúÿ“Ïýÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ8¨ÿÿ“Ïýÿúúúÿêêêì;;;"ÀÀÀœúúúÿ×ìûÿ<«ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ9©ÿÿ<«ÿÿ×ìûÿúúúÿÀÀÀœVVV*òòòöúúúÿmÀþÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ;«ÿÿsÃÿÿ§Ùÿÿ³Þÿÿ—ÒÿÿSµÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿtÃÿÿ«Ûÿÿµßÿÿµßÿÿµßÿÿµßÿÿµßÿÿµßÿÿµßÿÿµßÿÿ®Üÿÿ„ÊÿÿA®ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿmÀþÿúúúÿòòòöVVV*ÄÄÄ–úúúÿÊæûÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿG±ÿÿÎêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýÿÿ”Òÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ>­ÿÿ¿äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèõÿÿd½ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿÊæûÿúúúÿÄÄÄ–ííííúúúÿrÃýÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ¾ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ™Ôÿÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ—ÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòùÿÿS¶þÿ<­þÿ<­þÿ<­þÿ<­þÿrÃýÿúúúÿíííí±±±búúúÿáðûÿ>¯þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿJ´þÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜Ôþÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿâóÿÿÿÿÿÿÿÿÿÿùüÿÿºâÿÿ±ßÿÿîøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³ßÿÿ=®þÿ=®þÿ=®þÿ=®þÿ>¯þÿáðûÿúúúÿ±±±bØØØµúúúÿ›Ôüÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿWºþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜Ôþÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ÷üÿÿÿÿÿÿýþÿÿjÁþÿ>¯þÿ>¯þÿMµþÿâóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíøÿÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ›ÔüÿúúúÿØØØµññññúúúÿ_½ýÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿA±þÿéöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—Õþÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿÝñÿÿÿÿÿÿÒíÿÿ?±þÿ?±þÿ?±þÿ?±þÿ‹Ðþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ?±þÿ?±þÿ?±þÿ?±þÿ?±þÿ_½ýÿúúúÿññññ¦¦¦DúúúÿåòúÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿzÉþÿüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—ÕþÿA²þÿA²þÿA²þÿA²þÿA²þÿŒÑþÿÿÿÿÿÚðÿÿA²þÿA²þÿA²þÿA²þÿ~ËþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêöÿÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿåòúÿúúúÿ¦¦¦DÏÏÏ|úúúÿ¸áûÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿoÆþÿÑíÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—ÕþÿB³þÿB³þÿB³þÿB³þÿB´þÿ«ÝÿÿþÿÿÿÍþÿB³þÿB³þÿB³þÿžØþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­ÞÿÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿ¸áûÿúúúÿÏÏÏ|ÞÞÞ©úúúÿ”ÓüÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿG¶þÿñùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–ÕþÿCµþÿCµþÿCµþÿCµþÿCµþÿdÂþÿ–ÖþÿcÁþÿCµþÿEµþÿâóÿÿÿÿÿÿÿÿÿÿüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì÷ÿÿS»þÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿ”ÓüÿúúúÿÞÞÞ©æææÍúúúÿwÉýÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿnÆþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–ÖþÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿ›ØþÿÿÿÿÿÿÿÿÿÿÿÿÿÑíÿÿßóÿÿÿÿÿÿÿÿÿÿÝòÿÿaÁþÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿwÉýÿúúúÿçççÍîîîåúúúÿaÂýÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿÎþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§ÝÿÿI¹þÿF·þÿF·þÿF·þÿF·þÿG¸þÿ™ØþÿþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿûýÿÿiÅþÿ¢ÛÿÿzÌþÿH¸þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿF·þÿaÂýÿúúúÿîîîå ôôôõúúúÿQ¼þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿrÉþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåõÿÿŸÚþÿ|ÍþÿzÌþÿšØþÿÞòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿtÊþÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿQ¼þÿúúúÿôôôõ øøøýúúúÿK»þÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿN¼þÿôûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…ÑþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿK»þÿúúúÿøøøý úúúÿúúúÿJ»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿT¿þÿrÊþÿrËþÿrËþÿrËþÿrËþÿrËþÿR¾þÿ¢ÜþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐþÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿJ»þÿúúúÿúúúÿ øøøûúúúÿM½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿäõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯âÿÿM¾þÿÇëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ™ÙþÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhÇþÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿM½þÿúúúÿøøøû ôôôðúúúÿVÁþÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿäõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿ†ÓþÿN¿þÿœÛþÿíùÿÿÿÿÿÿÿÿÿÿÿÿÿÿØñÿÿxÎþÿL¾þÿÕðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê÷ÿÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿVÁþÿúúúÿôôôðñññÜúúúÿiÈýÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿXÃþÿhÉþÿøýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿÜþÿOÀþÿNÀþÿhÉþÿsÍþÿ^ÅþÿM¿þÿNÀþÿVÃþÿŠÕþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÝþÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿiÈýÿúúúÿñññÜîîî½úúúÿÑýÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿÖðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäõÿÿ¡ÞþÿzÐþÿlËþÿxÏþÿžÜþÿßôÿÿºçÿÿOÁþÿÒïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãõÿÿTÃþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿNÁþÿ€Ñýÿúúúÿîîî½ëëë”úúúÿÚüÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿ€ÓþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿuÏþÿ_ÇþÿåöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïùÿÿjËþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿÚüÿúúúÿëëë”æææaúúúÿÂæûÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿŽØþÿòûÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéøÿÿbÉþÿ_ÈþÿÍîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚòÿÿhËþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿQÃþÿÂæûÿúúúÿæææaÉÉÉ%úúúÿìõúÿQÃþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿWÆþÿzÒþÿ}Óþÿ‘ÚþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐïÿÿRÅþÿRÅþÿƒÕþÿÉíÿÿõüÿÿÿÿÿÿÿÿÿÿøýÿÿÏïÿÿÙþÿSÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿQÃþÿìõúÿúúúÿÉÉÉ%õõõÜúúúÿvÎýÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿuÑþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇìÿÿSÆþÿSÆþÿSÆþÿSÆþÿTÆþÿ`ÊþÿaÊþÿTÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿvÎýÿúúúÿõõõÜðððŽúúúÿ­àüÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿVÈþÿíùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•ÜþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿ­àüÿúúúÿðððŽßßß3úúúÿëôúÿVÆþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿšßþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæ÷ÿÿZÊþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿVÆþÿëôúÿúúúÿààà3õõõÌúúúÿŽÖüÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿ¿ëþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòûÿÿtÓþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿWÊþÿŽÖüÿúúúÿõõõÌîîî]úúúÿÝïûÿVÈýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿŸáþÿñûÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÍïþÿmÑýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿVÈýÿÝïûÿúúúÿîîî]¦¦¦÷÷÷ÛúúúÿŽÖüÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿ]ÍýÿØýÿ–ßþÿÝþÿlÒýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿŽÖüÿúúúÿ÷÷÷Û¦¦¦ðððXúúúÿéóúÿ]ÉýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿ]ÉýÿéóúÿúúúÿðððX```÷÷÷Àúúúÿ´áûÿXÌýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[ÎýÿXÌýÿ´áûÿúúúÿ÷÷÷À```ëëë'ùùùõúúúÿ„Òüÿ[Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ[Ïýÿ„Òüÿúúúÿùùùõëëë'ôôôiúúúÿðöúÿkËýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]ÐýÿkËýÿðöúÿúúúÿôôôiGGG÷÷÷¤úúúÿâñûÿbÊýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^ÑýÿbÊýÿâñûÿúúúÿ÷÷÷¤GGGááá øøøÄúúúÿÛîûÿaÊýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_ÒýÿaÊýÿÛîûÿúúúÿøøøÄááá ìììùùùÐúúúÿÞïûÿeÊýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_ÓýÿeÊýÿÞïûÿúúúÿùùùÐìììïïïùùùÊúúúÿêôúÿvÍýÿ]Ðýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ]ÐýÿvÍýÿêôúÿúúúÿùùùÊïïïîîî ùùù²úúúÿ÷ùúÿ ÙüÿXÊýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿXÊýÿ Ùüÿ÷ùúÿúúúÿùùù²îîî ÚÚÚøøø€úúúüúúúÿ×íûÿrËýÿ[ÎýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿ[ÎýÿrËýÿ×íûÿúúúÿúúúüøøø€ÚÚÚ÷÷÷<ùùùÚúúúÿúúúÿ½ãûÿkÊýÿYÍýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿYÍýÿkÊýÿ½ãûÿùúúÿúúúÿùùùÚ÷÷÷<ðððùùù~úúúóúúúÿùúúÿÇçûÿ‚ÏýÿWÇýÿ\Ðýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿ\ÐýÿWÇýÿ‚ÏýÿÇçûÿùúúÿúúúÿúúúôùùù~ðððõõõùùùŒúúúòúúúÿúúúÿðöúÿ»âûÿÒüÿkÊýÿSÅýÿWÊýÿ[Îýÿ]Ñýÿ_Òýÿ_Òýÿ]Ñýÿ[ÎýÿWÊýÿSÅýÿkÊýÿÒüÿ»âûÿðöúÿúúúÿúúúÿúúúòùùùŒõõõõõõùùùjùùùÇúúúþúúúÿúúúÿúúúÿôøúÿÛïûÿÇçûÿ¸áûÿ´ßüÿ´ßüÿ¸áûÿÇçûÿÛïûÿôøúÿúúúÿúúúÿúúúÿúúúþùùùÇùùùjõõõ÷÷÷ùùùdùùù¤úúúÙúúúýúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúýúúúÙùùù¤ùùùd÷÷÷óóó øøø*ùùùDùùùVúúú^úúú^ùùùVùùùDøøø*óóó ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿþÿÿÿÿðÿÿÿÿÀÿÿÿÿÿÿÿþÿÿü?ÿÿðÿÿàÿÿÀÿÿ€ÿÿ€ÿÿÿþü?ü?øøðððàààààÀÀÀÀÀÀÀÀàààààðððøøü?ü?þÿÿÿ€ÿÿ€ÿÿÀÿÿàÿÿðÿÿøÿÿþÿÿÿÿÿÿÿÀÿÿÿÿðÿÿÿÿþÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(€     2FYiw$$$‡>>>”NNNžYYY¤]]]§]]]§YYY¤NNNž>>>”$$$‡wiYF2,Kj000mmm¯–––ȶ¶¶ÛÑÑÑêæææõ÷÷÷ýúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿ÷÷÷ýæææõÑÑÑê¶¶¶Û–––Èmmm¯000jK,>fAAA•‹‹‹Á¾¾¾ßèèèöúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿèèèö¾¾¾ß‹‹‹ÁAAA•f>9i[[[£ªªªÓãããóúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿããã󪪪Ó\\\£i9!R===¡¡¡ÍæææôúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿíôúÿßîûÿÓèûÿÌåûÿÈãûÿÈãûÿÌåûÿÓèûÿßîûÿíôúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿæææô¡¡¡Í===R!(blll«ÉÉÉäùùùþúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿó÷úÿÌåûÿ¥ÔüÿƒÄýÿe·þÿK«þÿ4¡ÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ.žÿÿ4¡ÿÿK«þÿe·þÿƒÄýÿ¥ÔüÿÌåûÿò÷úÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùþÉÉÉälll«b(&d}}}µÝÝÝïúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿô÷úÿÂáûÿ‹Èýÿ[³þÿ3¡ÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ2 ÿÿY²þÿ‹ÈýÿÂáûÿô÷úÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿÝÝÝï}}}µd&Yvvv¯àààðúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿñöúÿ³Úüÿp¼ýÿ8£ÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ8£ÿÿp¼ýÿ³Úüÿñöúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿàààðvvv¯YCTTT™ÔÔÔèúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿÎæûÿ}Âýÿ9£ÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ/Ÿÿÿ9£ÿÿ}ÂýÿÎæûÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿÔÔÔèUUU™C%!!!t²²²Óùùùþúúúÿúúúÿúúúÿúúúÿúúúÿ÷ùúÿ³ÛüÿX²þÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿ/ ÿÿX²þÿ³Ûüÿ÷ùúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùþ²²²Ó"""t% Eppp¨éééõúúúÿúúúÿúúúÿúúúÿúúúÿ÷ùúÿ­ØüÿK¬þÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿK¬þÿ­Øüÿ÷ùúÿúúúÿúúúÿúúúÿúúúÿúúúÿéééõppp¨E hµµµÓúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿ¼ÞüÿP®þÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿ0 ÿÿP®þÿ¼ÞüÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿµµµÓh*KKKŒßßßîúúúÿúúúÿúúúÿúúúÿúúúÿÜíûÿg¹þÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿ0¡ÿÿg¹þÿÜíûÿúúúÿúúúÿúúúÿúúúÿúúúÿßßßîJJJŒ+;zzzªóóóúúúúÿúúúÿúúúÿúúúÿöøúÿ™Ïüÿ7¤ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ7¤ÿÿ™Ïüÿöøúÿúúúÿúúúÿúúúÿúúúÿóóóúzzz«; J¡¡¡ÃùùùÿúúúÿúúúÿúúúÿúúúÿÝíûÿ[´þÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ1¡ÿÿ[´þÿÝíûÿúúúÿúúúÿúúúÿúúúÿùùùÿ¡¡¡ÃJ U»»»Ôúúúÿúúúÿúúúÿúúúÿúúúÿ¯Ùüÿ;¦ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ;¦ÿÿ¯Ùüÿúúúÿúúúÿúúúÿúúúÿúúúÿ»»»Ô U [ÉÉÉÝúúúÿúúúÿúúúÿúúúÿõøúÿ‚Åýÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ2¢ÿÿ‚ÅýÿõøúÿúúúÿúúúÿúúúÿúúúÿÉÉÉÝ[ [ÏÏÏáúúúÿúúúÿúúúÿúúúÿêóúÿa·þÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿ2£ÿÿa·þÿêóúÿúúúÿúúúÿúúúÿúúúÿÏÏÏá[ VÏÏÏàúúúÿúúúÿúúúÿúúúÿßîûÿO¯þÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿ3£ÿÿO¯þÿßîûÿúúúÿúúúÿúúúÿúúúÿÏÏÏàV  KÈÈÈÚúúúÿúúúÿúúúÿúúúÿ×ëûÿF¬ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿ3¤ÿÿF¬ÿÿ×ëûÿúúúÿúúúÿúúúÿúúúÿÈÈÈÚ K;¹¹¹ÍúúúÿúúúÿúúúÿúúúÿÕêûÿC«ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿC«ÿÿÕêûÿúúúÿúúúÿúúúÿúúúÿ¹¹¹Í;*žžž·úúúÿúúúÿúúúÿúúúÿÙìûÿD«ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿ4¤ÿÿD«ÿÿØìûÿúúúÿúúúÿúúúÿúúúÿžžž·+www˜øøøþúúúÿúúúÿúúúÿâðûÿI®þÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿI®þÿâðûÿúúúÿúúúÿúúúÿøøøþxxx˜ HHHqðððøúúúÿúúúÿúúúÿíõúÿU³þÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿ5¥ÿÿU³þÿíõúÿúúúÿúúúÿúúúÿðððøHHHq GÛÛÛåúúúÿúúúÿúúúÿ÷ùúÿj½þÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿ5¦ÿÿj½þÿ÷ùúÿúúúÿúúúÿúúúÿÛÛÛåG%°°°¾úúúÿúúúÿúúúÿúúúÿÌýÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿ6¦ÿÿŽÌýÿúúúÿúúúÿúúúÿúúúÿ°°°¾%kkk„øøøþúúúÿúúúÿúúúÿ½àüÿ7§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ6§ÿÿ7§ÿÿ¼àüÿúúúÿúúúÿúúúÿøøøþlll„FãããìúúúÿúúúÿúúúÿåñûÿE­ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿE­ÿÿäñûÿúúúÿúúúÿúúúÿãããìF­­­¶úúúÿúúúÿúúúÿùúúÿl¾þÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿ7¨ÿÿl¾þÿùúúÿúúúÿúúúÿúúúÿ­­­¶OOOfõõõûúúúÿúúúÿúúúÿ­Úüÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ­ÚüÿúúúÿúúúÿúúúÿõõõûOOOf&ÊÊÊÑúúúÿúúúÿúúúÿéóúÿE®ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿ8©ÿÿE®ÿÿéóúÿúúúÿúúúÿúúúÿÊÊÊÑ&pppyúúúÿúúúÿúúúÿúúúÿÈýÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿ9ªÿÿÈýÿúúúÿúúúÿúúúÿúúúÿpppy(ÕÕÕÚúúúÿúúúÿúúúÿÓêûÿ;«ÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿC®ÿÿ_ºÿÿj¿ÿÿc¼ÿÿH°ÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿJ±ÿÿe½ÿÿj¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿk¿ÿÿh¾ÿÿRµÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ:ªÿÿ;«ÿÿÓêûÿúúúÿúúúÿúúúÿÕÕÕÚ(wwwyúúúÿúúúÿúúúÿúúúÿl¿þÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ>­ÿÿ†ËÿÿÒìÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝðÿÿ•ÒÿÿE°ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ<¬ÿÿ…ËÿÿØïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíøÿÿ®ÝÿÿY¸ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿ:«ÿÿk¿þÿúúúÿúúúÿúúúÿúúúÿwwwy!ÒÒÒÔúúúÿúúúÿúúúÿÉæûÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿb¼ÿÿàòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí÷ÿÿƒÊÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿM³ÿÿÑëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿ§Ùÿÿ@®ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿÈæûÿúúúÿúúúÿúúúÿÒÒÒÔ!bbbdùùùþúúúÿúúúÿúúúÿkÀþÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿmÁÿÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–Òÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿI²ÿÿáòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐëÿÿF±ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿ;¬ÿÿkÀþÿúúúÿúúúÿúúúÿùùùþbbbd½úúúÿúúúÿúúúÿÑêûÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿQ¶þÿòùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”Òÿÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ¾äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊéÿÿ>®þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿÑéûÿúúúÿúúúÿúúúÿ½)))>òòò÷úúúÿúúúÿúúúÿ~Èýÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ´àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“Òþÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿe¾þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•Òÿÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ<­þÿ~Èýÿúúúÿúúúÿúúúÿòòòø)))>¡¡¡úúúÿúúúÿúúúÿêôúÿB°þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿE±þÿøüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”Òþÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ¯ÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôûÿÿI³þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿ=®þÿB°þÿêôúÿúúúÿúúúÿúúúÿ¢¢¢ØØØÖúúúÿúúúÿúúúÿ¤Øüÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿjÁþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’Òþÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿÜñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçõÿÿÐþÿ\»þÿS¸þÿrÅþÿ»ãÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑþÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ=¯þÿ¤ØüÿúúúÿúúúÿúúúÿØØØÖJJJHøøøýúúúÿúúúÿúúúÿ]»ýÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿxÇþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’Òþÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿñùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐìÿÿH³þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿxÇþÿùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉéÿÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ>¯þÿ]»ýÿúúúÿúúúÿúúúÿøøøýIIIH«««‘úúúÿúúúÿúúúÿØìûÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿjÁþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ’Òþÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿîøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõûÿÿP·þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿÑþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíøÿÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿØìûÿúúúÿúúúÿúúúÿ«««‘ÕÕÕÎúúúÿúúúÿúúúÿ›Õüÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿE³þÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑþÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿÔíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶áÿÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿB±þÿì÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ?°þÿ›ÕüÿúúúÿúúúÿúúúÿÕÕÕÎ/ôôôøúúúÿúúúÿúúúÿc¿ýÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ±ßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÒþÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ¡Ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•Ôÿÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ¾åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿ@±þÿc¿ýÿúúúÿúúúÿúúúÿôôôø/húúúÿúúúÿúúúÿèóúÿA²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿQ¸þÿîøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÒþÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿW»þÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÿÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ´áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèöÿÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿ@²þÿA²þÿèóúÿúúúÿúúúÿúúúÿh¾¾¾ úúúÿúúúÿúúúÿ¸àûÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿjÃþÿóúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿŽÑþÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿ ÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎëÿÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿÃçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁæÿÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿA²þÿ¸àûÿúúúÿúúúÿúúúÿ¾¾¾ ÙÙÙÍúúúÿúúúÿúúúÿ‹ÏüÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿ_¿þÿØïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿŽÒþÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿD´þÿÂçÿÿÿÿÿÿÿÿÿÿÿÿÿÿqÆþÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿâôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ„ÎþÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿB³þÿ‹ÏüÿúúúÿúúúÿúúúÿÙÙÙÍïïïñúúúÿúúúÿúúúÿbÀýÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿC´þÿÌþÿÈéÿÿøüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿŽÒþÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿEµþÿ¥ÛÿÿüþÿÿÿÿÿÿîøÿÿfÂþÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿW¼þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿê÷ÿÿG¶þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿB´þÿcÀýÿúúúÿúúúÿúúúÿïïïñ^^^@úúúÿúúúÿúúúÿó÷úÿEµþÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿÇéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿŒÑþÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿ^¿þÿ«Þÿÿßòÿÿõûÿÿ¬ÞÿÿZ½þÿC´þÿC´þÿC´þÿC´þÿœ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚ÍþÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿC´þÿEµþÿó÷úÿúúúÿúúúÿúúúÿ^^^@¡¡¡húúúÿúúúÿúúúÿÔìûÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿU¼þÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÒþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿK¸þÿíøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöûÿÿüþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±àÿÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿCµþÿÔìûÿúúúÿúúúÿúúúÿ¡¡¡h½½½Œúúúÿúúúÿúúúÿ¶áüÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿ‡ÐþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÒþÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿ«Þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿš×ÿÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´áÿÿF¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿD¶þÿ¶áüÿúúúÿúúúÿúúúÿ½½½ŒÎÎΩúúúÿúúúÿúúúÿžØüÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿªÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ‹ÒþÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿ€Íþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯àÿÿ…Ïþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïùÿÿ‰ÑþÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿE¶þÿžØüÿúúúÿúúúÿúúúÿÎÎΩ ÚÚÚÂúúúÿúúúÿúúúÿˆÐýÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿ»åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ–×þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿ~ÍþÿùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïùÿÿG¸þÿªÞÿÿÿÿÿÿôûÿÿÌëÿÿÔþÿMºþÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿE·þÿˆÐýÿúúúÿúúúÿúúúÿÚÚÚ äääÕúúúÿúúúÿúúúÿsÈýÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿ½åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀçÿÿT½þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿK¹þÿ¦ÜÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿkÆþÿH¸þÿO»þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿsÈýÿúúúÿúúúÿúúúÿäääÕëëëåúúúÿúúúÿúúúÿaÂýÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿ®àÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóúÿÿ¢Ûÿÿ[ÀþÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿQ¼þÿ’Õþÿçöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“ÕþÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿF¸þÿ`ÂýÿúúúÿúúúÿúúúÿëëëåñññðúúúÿúúúÿúúúÿW¾þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿÔþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÞòÿÿ»åÿÿ©Þÿÿ§Þÿÿ¶ãÿÿÕïÿÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯áÿÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿG¹þÿW¾þÿúúúÿúúúÿúúúÿñññðõõõøúúúÿúúúÿúúúÿP¼þÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿ_ÂþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀçÿÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿP¼þÿúúúÿúúúÿúúúÿõõõøøøøüúúúÿúúúÿúúúÿK»þÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿÓîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆêÿÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿHºþÿK»þÿúúúÿúúúÿúúúÿøøøüúúúÿúúúÿúúúÿúúúÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿ|ÎþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁèÿÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿI»þÿúúúÿúúúÿúúúÿúúúÿùùùýúúúÿúúúÿúúúÿK¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿuÌþÿšÙÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿœÚÿÿkÈþÿJ¼þÿJ¼þÿÃéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²âÿÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿK¼þÿúúúÿúúúÿúúúÿùùùý÷÷÷úúúúÿúúúÿúúúÿM½þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿžÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚñÿÿK½þÿJ¼þÿUÀþÿáôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúýÿÿšÚþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ÙþÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿJ¼þÿM½þÿúúúÿúúúÿúúúÿ÷÷÷úôôôôúúúÿúúúÿúúúÿR¿þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿôûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ÙþÿK½þÿK½þÿ]Äþÿßóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüÿÿ€ÑþÿN¾þÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿrËþÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿK½þÿR¿þÿúúúÿúúúÿúúúÿôôôôðððéúúúÿúúúÿúúúÿXÁþÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿôûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùýÿÿqËþÿL¾þÿL¾þÿTÁþÿ¸åÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜòÿÿkÉþÿL¾þÿL¾þÿÉëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòúÿÿN¿þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿXÁþÿúúúÿúúúÿúúúÿðððé ìììÙúúúÿúúúÿúúúÿjÈýÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿŸÜÿÿÿÿÿÿÿÿÿÿýþÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðúÿÿjÉþÿL¾þÿL¾þÿL¾þÿoËþÿÀèÿÿøüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÖðÿÿ‹ÕþÿN¿þÿL¾þÿL¾þÿL¾þÿ‹Õþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·åÿÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿL¾þÿjÈýÿúúúÿúúúÿúúúÿìììÚ çççÅúúúÿúúúÿúúúÿ{ÍýÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿxÎþÿ˜ÚÿÿmÊþÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòúÿÿ{ÐþÿM¿þÿM¿þÿM¿þÿM¿þÿRÁþÿvÎþÿ‘×þÿ›Ûÿÿ–ÙÿÿÒþÿ\ÅþÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿRÁþÿîùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿmËþÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿM¿þÿ{ÍýÿúúúÿúúúÿúúúÿçççÅááá¬úúúÿúúúÿúúúÿÕüÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿëøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿ®âÿÿVÃþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿQÁþÿsÍþÿMÀþÿMÀþÿ›ÛþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆëÿÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿMÀþÿÕüÿúúúÿúúúÿúúúÿááá¬ÚÚÚúúúÿúúúÿúúúÿ¦ÜüÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿÉìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðúÿÿ£Þÿÿ`ÆþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿZÄþÿ˜Úþÿç÷ÿÿòúÿÿVÃþÿNÀþÿRÂþÿàôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøüÿÿeÈþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿNÀþÿ¦ÜüÿúúúÿúúúÿúúúÿÚÚÚÏÏÏiúúúÿúúúÿúúúÿ¿åûÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿØþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþÿÿÚòÿÿ²äÿÿ˜Ûÿÿ‹ÖþÿŠÖþÿ•Úþÿ®ãÿÿÓðÿÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ÞÿÿOÁþÿOÁþÿpÍþÿùýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•ÚþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿOÁþÿ¿åûÿúúúÿúúúÿúúúÿÏÏÏi´´´@úúúÿúúúÿúúúÿÛîûÿNÁþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿSÃþÿåöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöüÿÿcÉþÿOÂþÿOÂþÿŽØþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·æÿÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿOÂþÿNÁþÿÛîûÿúúúÿúúúÿúúúÿ´´´@HHHøøøûúúúÿúúúÿúúúÿRÀþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿwÐþÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏîÿÿQÂþÿPÂþÿPÂþÿ˜Ûþÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿éÿÿRÃþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿPÂþÿRÀþÿúúúÿúúúÿúúúÿøøøûHHHïïï×úúúÿúúúÿúúúÿvÌýÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿ…Õþÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨áÿÿPÃþÿPÃþÿPÃþÿŠ×þÿ÷üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ«âÿÿQÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿPÃþÿvÌýÿúúúÿúúúÿúúúÿïïï×ååå¤úúúÿúúúÿúúúÿÙüÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿjÌþÿËíÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿ•ÛþÿQÄþÿQÄþÿQÄþÿjÌþÿÕñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéøÿÿÔþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿQÄþÿÙüÿúúúÿúúúÿúúúÿååå¤×××iúúúÿúúúÿúúúÿÈçûÿPÃþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿhÌþÿ–Ûþÿ¯äÿÿ±äÿÿžÞÿÿtÐþÿÂêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÙþÿRÄþÿRÄþÿRÄþÿRÄþÿ‹ØþÿÞôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíùÿÿ ßÿÿXÆþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿRÄþÿPÃþÿÈçûÿúúúÿúúúÿúúúÿØØØi¤¤¤)úúúÿúúúÿúúúÿõøúÿRÁþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿ¼éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³æÿÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿvÑþÿ¯äÿÿÛóÿÿúýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿäöÿÿºèÿÿ…ÖþÿUÆþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÅþÿRÁþÿõøúÿúúúÿúúúÿúúúÿ¥¥¥)òòòÛúúúÿúúúÿúúúÿ~ÎýÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿ©âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ßÿÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿUÆþÿfÌþÿrÐþÿsÐþÿjÍþÿXÇþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿ~ÎýÿúúúÿúúúÿúúúÿòòòÛæææ•úúúÿúúúÿúúúÿ³àüÿRÅþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿ†×þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ}ÔþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿSÆþÿRÅþÿ³àüÿúúúÿúúúÿúúúÿæææ–ÏÏÏGúúúÿúúúÿúúúÿìõúÿPÁþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿ\ÊþÿøýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóûÿÿXÈþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿTÇþÿPÁþÿìõúÿúúúÿúúúÿúúúÿÏÏÏG111 õõõèúúúÿúúúÿúúúÿÎýÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿ½êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµçÿÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿUÇþÿÎýÿúúúÿúúúÿúúúÿõõõè222 ééé•úúúÿúúúÿúúúÿÀäûÿRÅþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿmÐþÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøýÿÿgÎþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿUÈþÿRÅþÿ¿äûÿúúúÿúúúÿúúúÿééé•ÊÊÊ7úúúÿúúúÿúúúÿøùúÿ]ÄþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿªäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢áþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿ]ÄþÿøùúÿúúúÿúúúÿúúúÿÊÊÊ7òòòÍúúúÿúúúÿúúúÿ£ÙüÿTÇþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿXÊþÿÏðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈíÿÿWÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿVÉþÿTÇþÿ¢ÙüÿúúúÿúúúÿúúúÿòòòÍäääfúúúÿúúúÿúúúÿíõúÿTÁýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿ^ÌýÿÑñþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËïþÿ\ÌýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿTÁýÿíõúÿúúúÿúúúÿúúúÿäääf ÷÷÷éúúúÿúúúÿúúúÿ•ÔüÿVÉýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿZËýÿ±çþÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿ«åþÿYËýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿWÊýÿVÉýÿ•Ôüÿúúúÿúúúÿúúúÿ÷÷÷退€ êêêúúúÿúúúÿúúúÿêôúÿSÁýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿwÕýÿÊïþÿýþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüþÿÿÆíþÿsÔýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿXËýÿSÁýÿêôúÿúúúÿúúúÿúúúÿêêꪪªøøøïúúúÿúúúÿúúúÿ›ÖüÿUÈýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿhÑýÿ˜àþÿ»êþÿÐðþÿÖòÿÿÏðþÿºêþÿ–ßþÿfÐýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿXÌýÿUÈýÿ›Öüÿúúúÿúúúÿúúúÿøøøïªªªììì€úúúÿúúúÿúúúÿñ÷úÿYÁýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÌýÿYÁýÿñ÷úÿúúúÿúúúÿúúúÿìì쪪ª÷÷÷çúúúÿúúúÿúúúÿµàûÿRÅýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿRÅýÿµàûÿúúúÿúúúÿúúúÿ÷÷÷窪ªêêêhúúúÿúúúÿúúúÿúúúÿpÇýÿYÌýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿZÍýÿYÌýÿpÇýÿúúúÿúúúÿúúúÿúúúÿêêêhaaaõõõÍúúúÿúúúÿúúúÿßðûÿP¿ýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[ÎýÿP¿ýÿßðûÿúúúÿúúúÿúúúÿõõõÍaaaààà8úúúüúúúÿúúúÿúúúÿ©ÛüÿRÅýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[Îýÿ[ÎýÿRÅýÿ©Ûüÿúúúÿúúúÿúúúÿúúúüààà8ñññúúúÿúúúÿúúúÿúúúÿuÈýÿXËýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\Ïýÿ\ÏýÿXËýÿuÈýÿúúúÿúúúÿúúúÿúúúÿñññ¸¸¸ ÷÷÷ØúúúÿúúúÿúúúÿëôúÿX¿ýÿ[Îýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ\Ðýÿ[ÎýÿX¿ýÿëôúÿúúúÿúúúÿúúúÿ÷÷÷ظ¸¸ äää6ùùùùúúúÿúúúÿúúúÿÑëûÿN¾þÿ\Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ]Ðýÿ\ÐýÿN¾þÿÑëûÿúúúÿúúúÿúúúÿùùùùäää7ïïïtúúúÿúúúÿúúúÿúúúÿ´àûÿMÀþÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]ÑýÿMÀþÿ´àûÿúúúÿúúúÿúúúÿúúúÿïïïtGGGõõõ®úúúÿúúúÿúúúÿúúúÿšÖüÿPÃýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]Ñýÿ]ÑýÿPÃýÿšÖüÿúúúÿúúúÿúúúÿúúúÿõõõ®GGGÎÎÎøøøÔúúúÿúúúÿúúúÿúúúÿ‰ÏüÿRÄýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^Ñýÿ^ÑýÿRÄýÿ‰ÏüÿúúúÿúúúÿúúúÿúúúÿøøøÔÎÎÎâââ"ùùùéúúúÿúúúÿúúúÿøúúÿ‚ÌýÿRÅýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^Òýÿ^ÒýÿRÅýÿ‚Ìýÿøúúÿúúúÿúúúÿúúúÿùùùéâââ"ëëë6ùùùóúúúÿúúúÿúúúÿøùúÿƒÍýÿPÃýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_Òýÿ_ÒýÿPÃýÿƒÍýÿøùúÿúúúÿúúúÿúúúÿùùùóëëë6íííFùùùøúúúÿúúúÿúúúÿùúúÿŒÐüÿMÀþÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_Óýÿ_ÓýÿMÀþÿŒÐüÿùúúÿúúúÿúúúÿúúúÿùùùøíííFïïïOúúúùúúúÿúúúÿúúúÿúúúÿ ØüÿI¼þÿ^Ñýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ`Óýÿ^ÑýÿI¼þÿ ØüÿúúúÿúúúÿúúúÿúúúÿúúúùïïïOðððMùùù÷úúúÿúúúÿúúúÿúúúÿ»âûÿLºþÿZÎýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`ÔýÿZÎýÿLºþÿ»âûÿúúúÿúúúÿúúúÿúúúÿùùù÷ðððMðððBùùùñúúúÿúúúÿúúúÿúúúÿØíûÿ[½ýÿSÆýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`Ôýÿ`ÔýÿSÆýÿ[½ýÿØíûÿúúúÿúúúÿúúúÿúúúÿùùùñðððBîîî1ùùùäúúúÿúúúÿúúúÿúúúÿðöúÿ‚ÍüÿJ¼þÿ^ÒýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿ^ÒýÿJ¼þÿ‚Íüÿðöúÿúúúÿúúúÿúúúÿúúúÿùùùäîîî1êêêøøøËúúúÿúúúÿúúúÿúúúÿúúúÿ¹âûÿO¹þÿTÇýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿaÕýÿTÇýÿO¹þÿ¹âûÿúúúÿúúúÿúúúÿúúúÿúúúÿøøøËêêêÚÚÚ ÷÷÷Ÿúúúÿúúúÿúúúÿúúúÿúúúÿéôúÿ~ËýÿG¹þÿ[ÎýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿbÕýÿ[ÎýÿGºþÿ~Ëýÿéôúÿúúúÿúúúÿúúúÿúúúÿúúúÿ÷÷÷ŸÚÚÚ ôôôaúúúóúúúÿúúúÿúúúÿúúúÿúúúÿÈèûÿ^¾ýÿL¾þÿ]ÑýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿ]ÑýÿL¾þÿ^¾ýÿÈèûÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúóôôôañññ&ùùùÈúúúÿúúúÿúúúÿúúúÿúúúÿøùúÿ°ÞüÿTºþÿL¿þÿ\ÐýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿbÖýÿ\ÐýÿL¿þÿTºþÿ°ÞüÿøùúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùÈñññ&ÏÏÏ÷÷÷uúúúõúúúÿúúúÿúúúÿúúúÿúúúÿõøúÿ¬ÝüÿW»þÿI¼þÿYÌýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿcÖýÿYÌýÿI¼þÿW»þÿ¬Ýüÿõøúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúõ÷÷÷uÏÏÏñññ"øøø²úúúÿúúúÿúúúÿúúúÿúúúÿúúúÿøùúÿ¼ãûÿmÄýÿD¶þÿQÄþÿ]Ñýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿ]ÑýÿQÄþÿD¶þÿmÄýÿ¼ãûÿøùúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿøøø²ñññ"õõõGùùùÑúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿÞðûÿ–ÔüÿV»þÿE¸þÿQÄþÿ[Ïýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿ[ÏýÿQÄþÿE¸þÿV»þÿ–ÔüÿÞðûÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùÑõõõGÆÆÆ÷÷÷[ùùùØúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿÒëûÿ˜ÕüÿbÀýÿB´þÿJ¼þÿRÅþÿYÍýÿ`Ôýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿc×ýÿ`ÔýÿYÍýÿRÅþÿJ¼þÿB´þÿbÀýÿ˜ÕüÿÒëûÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùØ÷÷÷[ÆÆÆÖÖÖ÷÷÷VùùùÉúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿêõúÿ½ãûÿ“ÓüÿmÄýÿH¶þÿB´þÿGºþÿL¿þÿPÃþÿTÇþÿVÊýÿYÌýÿZÍýÿ[Îýÿ[ÎýÿZÍýÿYÌýÿVÊýÿTÇþÿPÃþÿL¿þÿGºþÿB´þÿH¶þÿmÄýÿ“Óüÿ½ãûÿêõúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿùùùÊ÷÷÷VÖÖÖööö9ùùù¢úúúöúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿäóúÿËèûÿ®Þüÿž×üÿŠÏüÿzÊýÿrÆýÿoÄýÿnÄýÿnÄýÿoÄýÿrÆýÿzÊýÿŠÏüÿž×üÿ®ÞüÿËèûÿäóúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúöùùù¢ööö9ðððøøøcùùù¼úúúûúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúûùùù¼øøøcðððñññøøø^ùùù§úúúêúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúêùùù§øøø^ñññ¿¿¿ööö+øøøeùùù›ùùùÌúúúõúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúÿúúúõùùùÌùùù›øøøeööö+¿¿¿ÛÛÛôôô!øøøDøøøcùùù}ùùù“ùùù¥ùùù±úúúºúúú¾úúú¾úúúºùùù±ùùù¥ùùù“ùùù}øøøcøøøDôôô!ÛÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿÿÿÿÿÿÿü?ÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿþÿÿÿÿÿÿü?ÿÿÿÿÿÿøÿÿÿÿÿÿàÿÿÿÿÿÿÀÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿü?ÿÿÿÿøÿÿÿÿðÿÿÿÿàÿÿÿÿÀÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÿÿÿþÿÿü?ÿÿü?ÿÿøÿÿøÿÿðÿÿðÿÿàÿÿàÿÿÀÿÿÀÿÿ€ÿÿ€ÿÿÿÿÿÿÿþþþþü?ü?ü?ü?ü?øøøøøøøøøøøøøøøøøøü?ü?ü?ü?ü?þþþþÿÿÿÿÿÿÿ€ÿÿ€ÿÿÀÿÿÀÿÿàÿÿàÿÿðÿÿðÿÿøÿÿøÿÿü?ÿÿü?ÿÿþÿÿÿÿÿÿÿ€ÿÿÿÿ€ÿÿÿÿÀÿÿÿÿàÿÿÿÿðÿÿÿÿøÿÿÿÿü?ÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÀÿÿÿÿÿÿàÿÿÿÿÿÿøÿÿÿÿÿÿü?ÿÿÿÿÿÿþÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿü?ÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿàÿÿÿÿÿÿÿÿÿÿü?ÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿü?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‰PNG  IHDR\r¨fEHIDATxÚíy|TÕùÿ?çÞY2K2Ù÷„„a•EDQÜ@@D-­Zk¿õÛZë×bý¶jZiµ»¸µ¶´_µTq«7\APû–@X!$„,d²Of2Û½ç÷Ç™brgŸ;3¹ï×ë¾XæÜ{Ï=3ÏsŸóœçy                                       »¹; zN:¥MNNÎäy>ƒ’Êó|€DŽãtô„5¥”'„h€Rê$„”R›(Šý,‚ ôRJ;A0www·;ä~6…Т(€¤¥¥Eo0ƨTªžçGQJG( „äBò$#ôß-ÐM)m¦”6h$„Ô ‚pÒív×Z­Öšœœ›Üc£àŠˆrººº 5ÍTžç'¸ˆ2ŽR€—»o PJë)¥‡T ‚Pép8ö§¦¦6ÈÝ1…¡Q@qèÐ!uQQѵZ=ÀLBÈ%„¹û ”ÒJé.Û].×–úúúý&LpÉÝ/†¢ddîܹäý÷ß§Õj¯â8î*BÈF¹ûfú(¥[EQÜàp86.Y²¤zË–-TîN Waª««5EEEóU*Õ"BÈu„r÷IN(¥ ”ÒÝn÷úúúúÏÇï”»Oà EDÐ_«R©n&„,"„$Ëݧh„RÚM)]ïv»ßª¯¯ÿDQᇓ»ñÊwÞI,Ël»Ýþ÷ÒÒÒfFóÇq·)Â?4„dŽãnÓh4ï•––6Ûíö¿[,–ÙwÞy§ò¢ ÊÀ†˜¶¶¶¬ÄÄÄïs÷}BÈhY:AEG`o\½ ®>@°‚E€Šžvž©7ñü pÀk>TmÔI@B6¨6“}.ÇãPz\„öõõý333ó¬,ˆSHooï,FóŽã–Єý†ö ÷8HÐßÒwèoqônÇ9áÙ  Ò‚jM€.ÔXèÒ@u™@ÒhЄˆ,V8EQ\çt:ŸOJJÚ› Š‚íÛ·k&Mšô-•JõSBÈ´ðÜ…‚ô驱4ÝA¬-€ÛËô˜çp<À{ÞìÇ™pì›xóSÊD‰Šìï¢ÈADp € HßO¥5äÉA @Mc@“Æ"\?1Jé^·Ûý\UUÕ›—^z©â+EÀñãÇùùùÿÍóü}„‚^\t‚tîé>Ò±¤÷àdÙœç­P« û“ªT€Z¨Táyp·p¹AÜnÀåœNö§Ã9¸‚P©A“ŠAÓ.M.Mp¡5Ž(¥n·û馦¦ÿ=zt_x<~Q€;v,±  àn•Jõ3BHf¨®KúN‚˜÷€˜w€t÷×hÔ@B Õ‚jµ€VËÞîÑ„[‡p8»p^ ¸xhòhÐŒ™ Ó@£Bv{Ji›Ûí~ª±±ñ¯eee¹‡#VP€ìÙ³GW^^~·J¥z€’Šk’νàÚv´~ ôw÷a®×êt@‚–½ícAìþ~ÀÖÏÃù¾ ] höe3g0ë PJÍn·ûÉ#GŽüuúôéýrA´£( Ö¬YÃßtÓMw¨ÕêGCaê“îƒàZ·€4o罤ÔjÀ Õ뽎ÍÕãQlý 6`µ±éÃÚDÐÜ+ fÏMžô­(¥g\.×Êÿüç?kî¸ã!è Æ)ŠÒÓÓs•V«ý=Çq“‚º£ ¤é3pg>¬æs$h£Ô``sùáˆÃ bµ}}€ý¼LcCÄü… yW³åÇ Eñ Ãáø¹ÉdÚeÕà( àZ[[GšL¦?ñ<¿4˜ëömàNÒ¶÷ܺ»V$&‚&Ù[_á.ˆ¥°X˜Sš9 báBÐôYA]^„w{zzîÏÎή“ûQ£ ExØ´iSÂŒ3P«ÕÐtÁ®éCpõëkû?žgBoJds{ï8 =¦ V ™‹–AÌ»à½r¿Ëåzr×®]O^qÅv¹3P@ººº.Óétã8®,  8»@Þ×ð>àòøt €ÉÄÞöD怠”Y==@¿G^Õ:ˆ#–€Ž¸T“ÐeEQ<Ößßÿã”””/1̧Ãú—yðàÁ¤’’’'Õjõ@^q˜ÁÕ½Òø1[º#H4‚&'+oûPãp€tw–>¶’À«@ @ùPm@ 3¢ËåúÇÉ“'˜8qb¯Ü'ÃUÎÎÎ+ ˤãg¸ºµ §?b‚Ïq€)‰ ~´­ÏÇn)‚ž^¶ªÀ«@ B,¹- ‹€RÚ`µZššº ÃÐv À³¦ÿ[µZýSøûÖìàN½îÔÛ,—çdh²)~—î¢Qéîº{˜Ÿ@¥X|#Äâ[ñˆ.—ë¹#GŽür¸Å +ÐÜÜ<.55õÕ@–ö¸3ëÁ‰­ßs’¬~40 ºº™E M„8ú¿ æ/ àRâÁ®®®[rrrËýX‘b¸(ÒÝÝýN÷,!Dï׉=‡Àþ ÐSÇæøÉ&ДäØÎ‹W¤«›Y”¦‘ÆÝjšà×e(¥¶þþþŸ&''¿ˆa0%ˆ{°qãFãÌ™3ÿ¬V«ïðç<âêWó73Ÿ³”Ñšž¾D…Ðàvƒ´w°à"B@óçCócPu’_—q¹\ÿÚ¹sç=óçÏ룸V§N*ÉÉÉyÛ_“ŸkÙîÈó€³Ðh@3ÒÙ²žBìÐo1·³ŒEbùO æ\é×%DQ¬jii¹±¸¸ø¤Ü.âU¶¶¶«L&Ók„4ŸOr˜Á~äì6·OMaó|…˜…t÷]€(‚fM‡8î>¿– )¥===·dffÆe(q<*ÒÝÝý½^ÿ4Ÿíu®m ¸ƒ\6–˜“‘®˜ûñ‚Ûͬ« Pë!NüÄÌËüº‚Íf»/99ùyÄ™ˆ+ö#<¢¶X,Ïêõú?ÃWáìàªWÛ÷ :@³2As²á'T*МlЬL@t€Û÷8¸êU¬N¢WÐëõ¶X,Ï>öØcq•Ä7À|`œ?þ«*•j‰Ïßs|Õïk+ Ó±ˆÈ߸³m@?`Ȇ0é— ¦±¾Ÿîv¿ÿùçŸßºxñâ¸pÆ…¨¬¬Ì3fÌû<Ï_âë9\ÃÀû?æáÿj®áàzÎ7@IJÿ†8â&ŸÏagMMÍ’É“'›}>)J‰ù_üáÇ FŽù1Ïóã|:A°ƒ?´ ¤eóðgf ß|üáŽÃ ÒÖ8] 9³ LxÐç(BAŽÔÕÕ];nܸF¹#bYÚÚÚQùùùŸrWìÓ ýgÀï_ ô6°¤Œt%So¸C)sZú€¤¦¬Õåûtª(Š§Îœ9sͨQ£j£ÎÁXýõ“ãÇ—~ÆqœOß骿ïW€»Ÿô$%Êý ÑD¯…©t¦þ4Å·ÐQÏœ>}úêÑ£GC *XT¤¶¶¶íFÁ5}®ú9€4;KIÕU‡¤õ,@qü½óútš(Š-gΜ¹jÔ¨QGcJ ÖÀÀ›#Çq¹¾œÀÕ¾îĬ¤vv&À+Ë{ nÖ6Àá€Xúmˆ£~àÓi¢(6Ÿ>}úÊX³bIªªª‘cÆŒÙÌqœz)øê'A?g=™Ê|_Á7(i3VhÁ|ã€/¢"ŠbcMMÍå“&MªCŒ(˜‘ˆ={öäŽ?þ žçK½6¦nð•+AZw±Bi©rw_!!@O/hö “WÄ»õ(‰êêêyÓ§Oo–»ÿ¾‘€Ÿ}öYê¸qã>òIøEø½‚´îMMQ„_!`hZ*hj Hë.ðûD‡×sxž/7nÜGŸ}öYLüð¢>ìí©§žÒÝpà ï©ÕjïA>‚ü¾‡@:«Ù_’)  ß !P«@ÚëAº‚fÏ8iK€ã¸ì¼¼¼‹ÓÓÓÿýé§Ÿº}»‘Òy” ¿Á w÷â «ÄÜš2Âô'Î{ÀÃáxmÆŒß;räHÔ*hV\GGÇ£‰‰‰¿òÚRt‚ß÷ HG5söé+믠 ‰­¤Í š6ÂÔU>ítl±XKKK[ @”»ûƒ­ €´´´Üš––ö²×>Rüþ_‚˜(¯~”@ÆE¦ü ^gÑ´££ãöœœœW…+ѨȱcǦoö¥~_õk–mÌì×ûUîOA!0l66È™aÒ£^›SJmõõõWŒ3f7¢L DÝ*À† rFŒñ–/ÂÏ{¤¹‚…ö*¯)ôzÐô4æ pÇžóÚœ¢/,,ü÷çŸîSäj$‰ªU€%K–hW¬Xñ¶Z­žì­-×ðop'^gË|FÅá§a4j€çÁ5WšÐdédTŽãL999UWW¿YSS5Û•GÓ€ooo,))é!¯n«¿ÿ7žÝx”š} òAº{€ž^S~š9ÛkûÞÞÞUéééˆ %- €œ/77÷Eoý!Î.–Ò«æASáWˆhj æÁïûˆ³Ë[s.77÷Åõë×çÉÝo ,£Ñ¨niiù@«Õ^#ÙŠà÷ü ¤·†¥ô*[r)D¢Òz4q4„‹ŸˆôïÓáp|ZRR²¸­­Í%g·å–"îøñãwy~\Íó ]ž(?Eø¢ ŽÍHé>®æy¯ÍµZí5•••?†Ì2(çÍÉöíÛǦ¦¦>áµaÛVpõ0¿JÍfNÊ¡Ñv¨Ô i©àê?iÛêURSS·}ûö±Ñ—M”——k&L˜°šã8É5<Òß¾ê÷¬„—N‰òSˆrt: )|ÕïAú¥3‚9Ž3L˜0áïååå²U¥•KópMMM+222þ$ÙŠŠàwÝ Ò_ÏÂ|bÒfÕA˜ñœW€Ùlþß¼¼¼g ÃÒ ùøãKÒÒÒ~íµs'×€ôÖ*9ý 1MKé­wr×¶iii+?üðÑá…,‡ îîî^§×ëIv¬ç(ø+˜ð'(;ó*Ä v;HG'„KžñºûÍf[Ÿœœ¼ @DW"mp5557x~P7øƒO½"ü ±KB`г߲(-×z½~QMMÍ ˆ°LF4`ÅŠ¦n¸á-žçS¤ÚqÇÿÒ¹½ýeTPP­¤§ pÛ@Ó§I65Ól6Ûš;wú¼ki°DR¼ø–––_§¥¥ý?ÉõÖ€ß~/[ï×ÄÕF¬ ç ¤½ÂÌç@“ÆH6íèèømNNΣˆC0RæyóÍ7‹RRRVxkÈW?òûáWˆ4jÀ``¿m/¤¤¤¬xóÍ7‹¡—s¤€jþüù+½­ùs ëk=¨²m—BœA“k=ûKÀqœaþüù+Dd›H(²yóæ)IIIß‘läìwb Kï%€üa]Ê¡!<@“MàŽ¯ñš0”””ôÍ›7OA¬€H˜š®®®÷ õRøCO‚tnMIñõº 1éêMaÂ’íúúú>NMM] ÀÎþ„Ûà¶oß>Ç`0H&ûËqæÍ I¦0wGAA^¨ÉÒ¼Är\²Ñh¼vÇŽsf ·ÐÕÕõ‘Á`¸\ª¿ç~W=¨ÑæîD1ê] ÉT‰çq‚ŠNÀÕ 8Í ýgw¯Ü=UÒת.‚0]:ÞjµnNIIY lË‚át4p³ Ã<ÉÁhßÒ}ÄëOÃØ(ƒÓ‚˜¦ÉSAÇjïáΜm ½‡žý =U•5\!¨ÁÒv¤}'húÐ^ †y³gÏž½ aÚW œ@BggçûF£ñ*©Fªm?UuŸˆ¿„¬ë@Òfù´»Œ$î>ÐŽ- g?œr?™‚?Øí îd¸gýC²™ÅbÙ––¶a²Â5¿à>þøã©F£ñJÉF­›û™á!üšTâ»Áÿ#HÆüà…TF¬…à&<Rø}6uPˆ {“ ¯üä“O¦"L². @c6›_5™L7I5RUü¨Æ hµaêFt@2¯Éÿvh„^ whã¿@;*ä~d_p8@z¸çüS²YOOÏ222nà}{b? G.ùÇ?þQ:cÆŒg zß$®õ Ö @<;þTFp£~’u­O{Ë §I¹Ðf=UÚ=)€çA¬€.ÔX4d3­V[ZXXøÆ|òy^8Ì Õ‚ î"„HÆò’º×ãÛëŸ ®üqÀ49â·&i³Á] ¨•˜Šh‡ u¯K¶!„¨,XpÂà´µ Ë–-KNKK»]²QÇ^û™ø÷×åƒ+û5{Ë…¾˜)R>=ªÑ¨Aìg@:öH6KKK»}Ù²eÉñ´=Ô>þСCw3æ/’ö>"ÔÙJ¡…m&Hùo¢çíko=òà¶ÈÝ…¡p:AùbÓž”lVSSsÏ„ V#„™‚¡¶´yyyß—j@¬ ݇âSøùÑDðlÙ±ô#ãƒP ¤»ÄÚ ÙÌ#[!õ˜‡Rpÿþ÷¿/2S$5¼⳺/)ú! Ë—»ß$± ¤à;Á_G!|tL6$0Sßzë­‹B¹ ¥P͘1ã6HM+;H˦ø\öK ¤Í’»C“}86øë(„­–Ɇ ï㑱™s¡R¤¼¼<1==ýFÉ›5} h<+ƒ”ÆÏÁ%€Œ¸#TßI˜ Eÿ €“¼”ã›hxpMŸH~‹iii7•——'"Dþ»P)nõêÕW«ÕjÉâý\ãz@Q$g  N–»ÞÑådΗ» C¡K×ø¡dµZ¾zõê«"Ù •ÐŒ5J2êXjgküíëÇ€ì…r÷ÂwroP‚Ñ ÇÎV&+xd-$^ôPH#¹êª«’SRR®–lÔ´‘Å?Ëmj…ø —| 955i@ê ÙÇM9†8˜¬H’’rõ5×\“ŒLB¡ø•+W.ày^2¬;ûy|þÄ IM2®» C¡Q3Y‘€çyã£>º!å…P1Bz—Ÿö] ke#yÐtyr÷ÂLãµIî^( q2™‘ °°p€ ß¨Á*RRR’˜’’"Yñ‡kÛÉ–þ(âê É;þ2Á˜&Ë>~Ê1Ä¡Õ2™‘ %%åò’’’ W‚UÜ3Ï<3[­–vsÀóQ0²!>’ʃ>I*—ü”cðƒç™ÌH V«“Ÿyæ™ÙR†ƒUê±cÇJ;ÿ:÷$NËVJäîAàGÊÝ)ˆ‹ÉŽÙ jÌz’’r™d£ö,k¤dB•¨“äîEà$ä” ¤_ ¯´ š@e8ÏJ¡ÔÕ 8ÚW'¾ ~Q¤ýhêБõÙK+Ѐ¥V¬XQ˜˜˜(¹Ùg®4\ ý‹^´1žfË©u"àê ì|ÂÆQ ¦ñ€q4³(¼¤5Y€í4ÐW ôeÅM]J¶â×à9pæ­Gÿ`È&‰‰‰cî»ï¾Â§Ÿ~º2(þæ›ož 'q˜w ÑGhÔ"QÇAý=u’ÿ i,HÆe,– P ˆÓÆQìȾè=´omß ¸ûä™èÀÝ b7ƒ& `Kn¾ùæyO?ýôQX58 ÉÍͽTªiÛ¨cÔüç´ÌŒ% ÚW¾ö $ÆÓ™©nß¾N ’1È]èÑíH€¤±L¹Ý˜+@›ßlr’¼¨5 æ K†lâ‘Áäh T &“ébÉF]Õ€jÀû娓AÒ/’'²7“æ‚:ý¢°zƒvîg Ñ Zó'ÀÞ,ÝŽp YWßúæx„ Nd]’u9³^ì­r˜<¨x&C À#ƒ làG°¸ë®»òF‰J†HoUˆ"–Ⱦ¤àf m&@$«8-`,Œ% ¹KÁ&wσºA®º+¥Û%–”ü0Œ©£HŸ ’v Ðôhã[Ìw0Ì ½U’Ÿ †¢»îº+õêÕ]@º È_ýõÓ!5ÿ·5±·f,«z HÑ “ŸÒgK ÿ #ƒ~ *‚û#ÐU)1.j6.+£ðŸQù7²ïÉX*ÿï&҇豑¡¥K—NG€aÁ*uQQ‘dåÒ±PEiÖYBȤU@Þÿ?†¡§^:vû6.Ù8Út¹ ä-–»'‘E¥éŽ1bĨ„j’’’&K5 }…Ëú ¿‰üýPÒú)ÐüÑП›ÆŒ} ºw"Urr²¤€³ ‰ÿÉ[å¦",QÆmOn§T6mѦ³ø}®Zûƒ›Ž*#HùCQ>&~uÐwhú0økE%Ä#SCã‘ɰ+@«×ë‹%YŽ!z¤Ÿ²¯”»_Gt݇€îƒ ½Çk ô{}ˆ±Hž¤^$íÌlß ôüRcþHÈ”{B ù}О#@_Ü] ÏóYŽI~î‘I-˜Œú,|)ƒÁ Y‹ô7GÏ2²i|ô”¿ê>´líÜí]à/„ €õ4¨õ4pös[ºËždÌ:—z˳ÚÁȺH›!÷H„¢)ûè¾ûõ'H“äçF£1‘P3fÌHÖétÒ®t¡?å CIž(s(Knix‹½éC†tí>œ| $ ·ˆåäwìú¹—ÚRò_2GÑ€ÜÚð†Ü= =^–;RfΜ™¼cÇŽ.ë¯,Y²d¤B€íf„póÒà‘NW/½GA÷ý ôÈC,üàê=µt×–OAϼ7h3R|ktú„‚ÂmFð׉:l Y´h‘¤l†¿?räHé|PËI€ q¥™`Hȉü=hÝK@ó'‘WèñçÿL—d_ù±ˆ4œ¤èКgäîIˆŸ‹0Ùº6Š‹‹ ÀdÚçI€*333Wª±·#šV ŠpÒŽõ4èá'[Sð× !dÄòØ]ï÷—¬y@Û@¿_Öp”C@ìí’b••••?'ßþ*.))IÚ¾’+M6õ"Ü…,ƒMt݇A߉ì:wÇfîûêàKÈIÏÊiéóØrŸJ¦@ݬL–à XÏ€ZŽ=‡·ŸÎC€½52çDnä†p ù׃žX-wOB‹ÙòȦ_ZÞï)€N§K—láêA¤_ÿdä÷€Â ¶&4ŒÉ¾"r àì ÇžaÞz)´é ÙWYs}t[Œ2<;*]Uì^æm>çÇ“œkb?àÇ_²/êÖø¿ÚÍx)ßæ‘ͰY€*!!A²ò#±7GVþ3.ý¦ð©@—¶­ GŸ–Œ×†.¤øÛ@æÜÀ…‘ð@êÂ;ê@ã» g>ð udÇÞöeAÃë@2fƒ¶l»'!ƒx©à¤ÕjÓÁdÚg'œ?æ V©T’‹êÄKÄRÈ¥`iDï÷ ºª@<5´ðóZ’;@f<d]º7±ÚŒüÈŒ¿3%8¦òد`(q6í!ÎNÉÏÕjuX]ŸWüžh4éu$¡5’J#w¯ éo­^5tà‰q$ȸ_„©¦mÈø‡Ø´ æùo˜¼$=ƒ~|%e"‹‹ˆÕòmâ%À#›~É´¿€J­V¤;éŒl²”\Pôðn°~eÌ™ú‡ð ÿùdÍ™ú'@›õõ~¤Æêþ…!€ð )“dOæ Ù!Hû|<²Éà Àßu!•J¥ÒI¶ ®ÒÒ{"²÷ þß@ïñÁ?Ë»dü¬h$1‚Lû`ð8ÕIÑQ×ON’ÇÉ݃ÐáE¶<²6 xžç¥ëüR7"©ééuaï!éomø÷à}ʹdÌO [2„&dòoY²OÒ(yúM$†ü¯î^€G6ýr2ù;àT*•´Ý‘—¶í@Ã[þÕIRv/dτҦ‚Lú5H,ï^* E%²ËnHÑ« “é°99Bˆ—‹G~bNk×A 1“7œËÖÓ€y½Û5É ãde¬£CPt³Ü½•Иg·Ü= Ò²å‘ͰŽã¤M q` a:övì‹ü}=1wš”à/ÒN ³àŸ¡ÐfŽÈ.O‡/Slúe~ú Hˆ·€r9]ó2‘6 Èœ%w/†€hLrw!Dxµü2ÿ¥TºìðpI8ùêy HiçØÇ*£Ü= ^d‹RJfQ¥ƒÝ‡›Ù™v±¼5¼/¿I/Ï!Šþï”⯀z´ŒT/oMâR0̶ªŠUââ7)ýr÷.›ßÄ_ €ºÝné‚k\´oB´©@Ú0Ž´‹DGð׈¼È–G6ýÚÈo Àív; L4ÃÆH2.ìkþ ÞqÙâã7I¼*'ü|R€èr¹¤38­¿}ˆ]†sœ} Aˆ‹ß¤—Ðr—Ëå@- @t8’¨J7|Þ‰¦1r÷@¨tºªK¨­‰mlâödÝqj|£Ë1ŽLe@êd@“,O¥‹iÆ ÔKŽÃá°)Ÿµ¿€àp8ú$[pº¸P¶^Q$ 4Æ%ÝG€3Ÿ€¶m\Ö¡Û Nö¹µ´ýû?B€ärÜ«€œË>B‰RÎÀÙ+÷È…Ϋ胟%¹ýUn‡Ãa‘l¡I°кøÚYG’Ž µ/3(”]Õ ]ÕÀñAŠ–#–…_ôÕ#n~š$É=²é×R ¿SÁjµJÆTRmÆð˜ÄMt™övУÚv„öº®^Ðk€Æõ cd^ô%‡$¥eP/ûX­Ön0 lS·Åb‘®K¤M‹…+‰t®¤9» ´ú)ÀÕüµ†¢¿tÿ¯¼«AÊï ‹5@»ªÏýy-óC¸­á}®p¡•®Çk±X:f ÀÕÙÙ)mè21,4€·ê¿± “kAk_EľǦOA-'A¦>Úú…‚è¨ò<™ü0q±ç3;Ð×ôíØ´ï•.®P´à‘MÂdPîÆÆÆ6ÉV^´T¼@{üMuD'èþ_íû#ïÞZÐ]÷Lÿ Ë Í5Û÷}U:ßxNø–2n*L¥ …‹™Bhù´~Ço…x‘-lú•Žëo$ PSSÓ*Õ€&d^ð –»ôL(æ û~˜÷Ë7¦ÖVÐÝ„,wŸ6ή›6ýéÆ|-È쿃Lzˆ¥Ëý»° P‚´bôȦ_¦©¿ @Ü´iÓHiɳ»MŒX8þV€ús½ û>ùÇÕÖºïQ@ r‹ogжH,¹è?‚s9Èœ€‚kåc °ÉÐPlúõ£ôÛ¨­­íéëë“\X¥¡2á¢ÑXåîEHžƒî_éþ(¡ûPóBp×hüÐe‚L_Åb6üE¥ÿ3‰¿`M2ãM¦úúúzkkk{f À ÀÖÕÕ%íÐåÈ®0#rtÅø“èb^ø¶=òå…æný;@סŸË ÚQ2ã,a+ò®™ú8À%È;&^v¹öȤ ~®ø  ¿³³Srë[:\JQ·ï•»ó•ðï’»'ƒC)hõsM³, =º…ô) S8ùê P£´Lutt4ð{Wž@€½©©©^º³Eýƒ¶íòº[KTò•ðï”} %Ë) i£ÿÏg*Ô‰þŸ'Eú4« ×oÍKÑ™–––vø©üN਩©9½pá¡[%ûÙÅmZ¶ùWËÝß] û„?Œp* m HÆ–4eÈ4‰¬j²õ PÿhÓF¶³’ôäë ùW!*Ò® ±¸‚æÍ‘¿wb±äÇÇŽkà@$À† jî»ï¾¡ér•.°½ìc zêmXQ¢ tßÊðšýêD¶æ>bÑ7³ÿìfÐc/2ò5ª¯h?¤O‘kÔ¾whû¾È&©tL¦$ظqc " À½qãÆÆ¾¾>‹ÑhÜÎ"4±$P'N´C8 m2Höl¶Æ P7èÇÃøæ'@áu ewn~ŸÝZù$ Ãõ—¦Q£ 1”ÞzøÏ»%M,aÙ”CÐ××gÙ°aC#üt*–ÖÖÖÆQ£F ¹õ 5•ÅŸà4 … â›}Nð׋Ô ºï1àlEx®¯2€L~È¢4zÓç •«àçõ¹îŸÝBÅè©8]¸8ù:`oÈí¨©LòóÖÖÖF~gT[gì;}úôq©FÔT&»)¤GæLyk€qÿ›ÂßZžqѤ€Ì|fháï®­úóæzg/Ð{Rî‘<§)\±ßž7à‘E¿k) ÀZYYyL²QJùyÍcøàT W€L‚¨ô 3þÆ`éï¯ x ï—Þ¸u+Ð[š›YêÃö‘‘’pÔPàmË9úöÛo‹ð{Žè¤Ê¹{÷îF³Ù,HS&Êþøà4 ¯Ò&ñõÉ™ð·l ßøä^Á©n4~ºûõŸ•{T¿IŸ~ó?Eú÷g6›ÛvïÞÝÀÈ3ª\ºëêꤧÑâ¹ 2ñ~ u¼ÜÝð*‚ø-þpÁkAÊì­#@Geè+ëú%GÀð²ïÄ©S§Žè“I¿ Tz«ªªª%;Ÿ:l¢$÷ëÜÏ#wU€C##TÝÿ[ iSXLJ.¼„ÙÚª‡è¾ÑX¬ÃXÖqˆWpàÀj½À®(€¾—_~yävDj#hrŒ­p ãîpXdä|á÷]ï½?BhïÉë¼ß3Ò$¤‡×ü7•ê¡76¥”ÒW^ye/Ø ÀÐr(A0 À¾{÷îú–––fɆ—„|Üà )\À¾ØX‚  û÷¼ùÃŒ©ÄóæóBˆcñ‰1 ʤûÍ”–––––Ý»wŸB9YáÐqôèQÉhš9ò¿Öý8F, bHd€ 1û¿2ÿÓ§úÖ/ Ц„îÞé“å顾€°Lv†æÈ‘#t @ œô|öÙg{$‡'±TŸ'»\ûtès‡^ÓŽF¨ºÿ àLÌþÃ4Úçî‘ÌKBsO•aè@#9]aü-æzIÚ°aÃ~9Ÿ``Y½zõ^«Õj“l˜=;$ãnHê¹»à;T=ð$p&€tÙ`0æùÞ¶øz„"‹”,gÉeц£+l—½ÈŒÍf³­^½z/Xp@æ?¼°÷÷÷·9rDz5 û2Èÿz÷á01d@ø?‰üù3·O\Üý’J€ÒïÈ=âƒcm Û83™š#GŽT÷÷÷·"ˆù?œØÚcÇæÍ›%óK©©”E4EŒK^¶^Š „ÿô'òŒç_þ™xß¹úþ ™ 3~5ù¥§6,cL  ¦RÉ[oÚ´i7Øü?¨ê©Á*@÷³Ï>»Ín·K.ÔÒÜùAÞJákÂ/þÖxPéAf= ¤Œõï¼äÑ sÿè³å{V/Ðöªð\׋¬ØívdzÏ>» ,(¨ÒÔÁ* Àf6›Ï y‹Üƒ#ï÷rèù°Œ­Xp­×-Ì<2Ö† ¢ÿÎ'T @ÐõÎ;飼«;-9|E×û½”Iè©w#[ñuð^œþ(„žxCî.ÈÇ©€Ž0ÔºäTL6¤n}êÔéwÞyç€.éýÿê¶!ê>3Iά_¿þKɆ é 9sCtÛ0à´G_’±Ñ-ü€îã@c„#£Kè¡¿„åÒ4{¨—$´>øàKgÀ@CÊu97€¶'žxb£·Ð`±ä[ @Ô8¹Ží—'UÏ‚œz_ö1ð:F‡þ8ºå#9pö;q÷‡e<ÅQË%ooµZmO<ñÄç`æÐÞÿB©D=u›7o–,>OM£Yµ ¹ç³C"°k%`9íÛ“‡Šªg€ÚÿDÁóûpô·{CÜl‘.…Ë lû9û=„a,iúP/IV›7oÞÙÑÑq¬øGÈ=Ô‘9Í«V­úØívKf( ¥·„øÖ!ÆÙl½°4Dæ~ÂK´î*Ÿ’»áÅÞlùæùÞdÁív «V­ú@3XìȵtìÞ½ûÐÞ½{¥ë¤Oöì»þvà‹gü$:cSø¨{Øû;@ô{OŠè§½ Øôæó4u‚×Ú™{÷î=´{÷îC`±ÿ!5¹Â±ß±€ïîîÖÝtÓM³ zO#ªË×øiºBÐøKý̘ÚĔӟ[îÌûå~Êàè>œÝ dNc€Æ:.+Pý7àÀÙßÈpÑÏÃÐûþQJéÏþó=zt+Xô_À¹ÿƒŽ-W €T³÷îÝûû‰'JNnTÛîiCPE8Ð&c¾ Œ\¨ô_§upt ÐQø5¢^ Œ¹ ýíàÆG.\VàÔ{@ÍkaÍõ€¦O†{Ö3’m~ü87wîܲ¢¢¢¡ë;qj !ܰÎ4Sˆw„É÷ƒ¦”I¶Ù²eKÕÃ?¼Àa±ë/„[P0Ï%9tè½ýöÛç¨Tª!ïIM%à:‚Ø¢)'_A!4ÐŒ)&üD²Ãáp}ç;ßYÝÚÚº,ò/¬V‘pź4WVVî_·n]…·ÆÂäû>JB)(ø¯a¿m/¬[·®¢²²r?˜ð‡Ý+n `7úå—_ºî¸ãŽ™ƒ!aÈ–š$€¨À…£à¢‚‚Låw‚æHoöa6›»—,Yò7»Ý¾aˆúŒH) Àe·ÛyBˆñÊ+¯œ(Ù8µ\ë.þöuOA!|Д2SôûðøãÿgÓ¦MŸ8'ý E¤À¬aÇŽî ŒÏÍÍÚåO8Ðô à>h&™( x-„YðZ sïÞ½Çï¼óΗT" I?CÉp,,šéè½÷Þû–Ýn—\Û¤‰EÆý(‚ÝSP=¸&I¶±ÛíÎ{ï½÷-GÁd$ì¦ÿ‘´ày0Wss3ÉÊÊJŸ>}ú(©Æ4µ\Ǿ¦wSA!xhÖÅ&¯€·ˆûüã^zé¥wÁ–ý‚ÚìÓ_äÈÒP(æyþò<\VV–/ÙAGTïì2tUA!@Rá¾r ¨6E²YMM͙ɓ'?.Âf§ÏÿùDÚ˜vsRJqøðaaùòåÓ¥b Ò&öÔ ˆ˜bTPÂÁ=ó PÓHÉf‡Ãuë­·¾X__ÿ%XÔ_Dç#‡ØTÀÙÐЀÔÔÔ”K.¹Dz+TC.á@b½p†Â°@,¿bѯížþùÏ^xá…÷Ѓ9þÎG.@Á\7nt,^¼¸<;;[ÒV¢é“Àu‰Úýûš3 ”ûámv]YYY·|ùò—ìF˜rý}AÎíz]š)¥U·ß~ûkÝÝÝ^æ Üÿ 4q„Œ]VPš8î‹oÂßÝÝm½ýöÛ_£”V!BC!—0€€½½½vww«.\8Aª† x höÅàNªìO§]h!\ö«%§Æß[Ÿ~úé'ªÁ²ýdsnÉ­(˜ösìß¿ß]ZZš=a„É34&Д±àNo€ S&…oBTpÏú½×,?xã7v>òÈ#oضÉGÄÖüCn0)vpôÑG¶Å‹—gee™$Ï0ä†lpM[åî»Â°‡@˜þKÐ<ïÛÝ:tèôõ×_ÿ¢ ;4€ýîe%À´`¿ tóæÍ¶åË—OÖëõZ©hr)ǃ´í“»ï Ãqü!ŽºÉk»öövË¢E‹^0›ÍjDE‘ÈhQóôwvvŠÇw/]ºt¢J¥’tRÒŒÉ Ž.®£r÷]a"–,ƒ0ñn¯íœN§ûŽ;îxuÇŽÐ(™¿F“X´?~ÜM)M˜7oÞhI§ š} Hßž“r÷_a!^ aÚƒ^KžSJéo~ó›^zé¥õ87ïš ·hRÓŠvŽŠŠ {QQQƤI“¤‚„€æÎé©éÐ>~ Ã1ï23Vœwñyå•Wvþâ¿xl½ÿ ÂXà3¢MÌ`à\¿~}ßœ9sŠŠŠŠ¤×Vš¸îJ BX¡¹³ \ú¸O[Ä}ùå—Ç–/_þ2¥t'Xyúz#ÀL$¥Ô½nݺžë®»nLVVV’䄇˜9Hw-H¤vôUVˆ¹s \ú;Ÿ„ÿСCg®¹æšNçv0§_X‹{J´*€ÅØ\.—{ýúõ½K—.›œœ,½ááAó/±ÔƒôÖËÝ…8B,¸ÂLßÞü íW_}õK`)¾=ˆBá¢[ 8­‹ÅýÙgŸYn¸á†òÄÄÄɳÇ”€­ ¤+|Û:+ ÄâEf<êÓœ¿¥¥¥gÁ‚k<~Á6ô”5ØGŠhVÀ9§ µ££Ã½uëÖ¾¥K—–ëõzé²Á„€æÍúAÚÉý 1ŒXv+„©÷û´—a{{{ßÒ¥K_9tèÐ Ê<þƒí `J €µ¥¥ÅµsçNëõ×__®Ó鼨b4{ Iwv7¢ÔSˆVᢟB÷_ð¥nNWW—í¦›nZ»k×®M`Ë}­ˆrábCç”@_cc£k÷îÝ}‹/ë] 4m<`*×RˆQÿ}(Dª3ƒX¼È§æ]]]¶›o¾ùÕŠŠŠMöBæ ?ˆ0%`Ð×ÐÐàÚ¾}»eñâÅe^§hRhÎ%àš·±ýà†B—÷¼ç@³¦ùÔ¼££ÃºlÙ²×***6ض™gL?[ `JÀ ÀÒØØèÚºu«eÑ¢E£ ƒÖ뙺tЫAÚØÚä~…(„¦O€0ïÏ ‰…>µokk³Üpà ¯íܹó |=Ð'fæ›±¦€ó”@SS“ãÓO?í¾îºëJM&“Îë™j=Ä¢, ó˜ÜÏ¡Eˆ%K!Ìú- Iô©}ccc×u×]·¶²²òK°7Ì ?› 8§zÍf³ó½÷Þë¼æškŠÓÓÓ^Ï$wîÜüüüüd_N¦É¥ ù—˜‚Ø;ä~ )£!Ì{4ëbŸÏÙµkWýÕW_ýjkkë60oÿ€Ã/愈mœËè±Û펵k×¶7.½¬¬,Ó§³µ)G.q;@:ªcô+TðB ޹•Åô'¤ù|Ú{ï½W½dÉ’×­VëvûÁ–úbÆá7±®€sK„=¢(ö¿õÖ[:N;cÆŒŽã¼/à4ghúDpg÷*«ñŽ.îÙ« –.óÙäA|ê©§*îºë®u¢(î‹ð3#Öù½ 81ØÀúùçŸ÷666:/¿üòb­V«òé Æ<ˆ#ô·ƒt×Êý< a@,Z÷e¼lØq>‹ÅqÏ=÷|ôÔSO} `Xl'â@øy¶ '<€D#L:uê%¯¿þúÒ¢¢¢T.Bš·Aµç÷€­UîçQúl¸§ÿœ9ý ¾¾¾ó–[nywïÞ½»Àœ}u`{÷Eml¿¿Ä‹0+´Ø  §¥¥Å¶víÚ³]tQÆÈ‘#}Ÿì%BµDt€t¨âˆI8âèoÃ=g`*ñëÔ 6_¸pá›uuuÛìþ>DI)¯Po `7˜¦î¶Ûí¶W_}µÂ͘1#ß[Á¯àÔ 9—€æÏé­±¶ÈýL ~@3§@˜óGˆÅ }JáÀáp¸W­ZµõG?úÑ{v»}'˜§ÿ Ø3îÞñ6¸5€Tc\4wîÜé/¼ð§Àþ|埾f¹ŸIA c.„Éÿ±p¾ß§Ö××wÝyçmÙ²e˜—ÿ8Ø|?¦=ýRÄ«0À€s° @wCCƒuÍš5­%%%‰cÇŽÍðVpô|¨i$ók’ÀuUv&Š6´&“~ á’GASJý:•RJ×­[wxñâÅoŸ8qbÀ䯫Þξ¡ˆwœ+,Ò Óétö½ýöÛæS§NYgÍš•o0¼&}áAÓ'@,]©XÁ1n_±Ú±üv¸gÿ4kªOE;ÎÇl6[ï¹çžO}ôÑOœNç€ÉßdWóýÁˆ÷)À…¨$(0)##cüêÕ«¯\´hѬ¯pö‚?ö¸š®>¹Ÿmx¡6Bó-e·š$¿O§”Òõë××Üu×]Ífs5ØÚ~-Ø[Øhõᦶ#²@.€qÆ/_¾|ÚOÄÒA3&u©;wž^±bÅ–ýû÷{ã×h{ëÇM`¿ w°1Pù ŒPvûí·_ôÈ#Ì1bDJPWwô0« î¥ÐÔ2ˆ#³·½6°YÙ Ý=öØö—_~ù€cŽ8sþa÷Ö?Eœƒ lZ0V¥Rz衇¦ß}÷ÝSÓÒÒôÁ] =uàê?©ÿ ¤¯Iîç*¨1´èjˆEׂú«?¶¿þõ¯ûžxâ‰=n·»Lðë´ƒ- «¹þP( à›ð ²Œ0&11±dåÊ•ï{ß›˜””ä½ü˜Îp›@Î| Ò=<76¥É% ù—A,¸4uLH®ÙÛÛëø×¿þupåÊ•»-ËI0S¿,u׊alg`Z¶Z0 Àè´´´âGydú­·Þ:Îd2%u‡óofmiª×² äì^À[LJµ4kÄœ y³A 9!»too¯}íÚµ‡{ì±½u`Q|µ`Þ} sP ÍÀj @Xü@ijjêˆ|pÊm·Ý6>===è©Á× HÇQV©È\ Î\ôÇhÅ"­‰Ne^š54­Üç|_ioo·­]»¶zÕªUû;;;À„¾¬LW†©wßWà €$0E0@IBBBÁ½÷Þ;áŽ;î˜0jÔ(¿ó |…ô1éªé¬aõ ì]rÉ×IHMš:4e hú8Ÿ«ëBmmmçš5k=÷Üs‡ìv{#€“`sü&°lP'”y¾Wàç+‚lÅ`Ê oÙ²ecîºë®ñ³gÏ.ô9ã0ì] =§@,lKô¾&[+ˆµ#ÑOu ÏJ«2AõÙ€14±€¦b !¸Å_p»ÝbEEÅéÕ«WW¯[·®LØëœ›ã+‚ï'Š lj` ¶|X `äÈ‘?ýéOÇ/Y²¤4//Ï·Ó¡†Rg`ï½ . àì\6@p€ˆ.¦ *"s*–çÀ©^ ¨õ€ÆªN´I@B*¨Æ- ššš,ï¿ÿþ‰gŸ}¶º®®®@#€z°å¼6°<}Á÷EÇ€³PU˜`€BBHÖÒ¥KK¾ûÝ7oÞ£Ñè{Ò‘úúúœ_|ñEÃ+¯¼Róî»ïž¤”žø°7'XâÜ E„‚sqI`VA>€¹:.ã»ßýnéÒ¥KG^zé¥ùz½>°XÖ8Çf³¹vìØÑôÎ;ïœ|å•WNô÷÷›Á¼ø`E9ÚÀÌüu|EðƒDQ¡g`z  Ì2È¥×ëÓ—/_>ráÂ…#.½ôÒ¼ŒŒ ƒÜ–³Ùlݾ}{ÓG}Ôðæ›oÖÙl¶vgÁ¿Éó÷.°ÊÏŠ™b>¬ Øa@dƒådBRæÎ›wÝu×Ξ=;wüøñ™ ¾U1ŽQìv»»ººº­¢¢¢ùÃ?<½eË–&JiX™í0gÞ€ÐÛpΩ§¼íÀ¢"‹0Tƒ)ƒdi` ! ,ü8U«Õ&]uÕU¹W\qEÞ”)S2ÇŽ›–’’â}ÏÃ(¦«««ÿèÑ£û÷ïoÛ´iSÓ† šG/Ø~àm@X|¾ ìM/@ú°£(€È3`¨Á|‰`Fi2À”AŠçÿŒãÇO›3gNÖäÉ“ÓËÊÊR‹‹‹M™™™Ÿ6=‰ ¢(Ò¶¶6ë©S§zŽ;ÖYYYÙ¾uëÖ³ÕÕÕ`^ú°·zûyGX”žçÌ{Eè#HTýˆ†!ç¬ ˜B0‚9“ÁV’=G’ç3]RR’qúôé©åååÉ%%%I………‰ÙÙÙ†ÌÌL}jjª.\+V«ÕÙÑÑÑßÖÖfkmmµž>}ÚròäÉÞ#GŽtïÙ³§³···l®Þæ¬ëöž?{=ŸÙÁLû·¼"ô2¡(€èâ|… S :°ä$#˜µ„sÊÀà9t´žö½^¯)**Òçååé322’““5IIIj½^¯Òét*µZÍñ<Ï©Õj\.—(‚èr¹Äþþ~·Ífs÷ööºº»»f³ÙÞÔÔd«¯¯·Ùl6'˜à:Áö_èK°±âœÐ÷‚½Õû<ÿßïi¾Y¯|” (€è‡Ã9¥ òZÏ‘&üzÏßþø\ã9ÔžóxÏ1p͈ÅÓ[Rl}Ý…¯ ¼ìím;ïÏ~Ïß>w{á¼k*D)ŠˆMÈÇ€ps8§(Îúó?ç.88÷VØEàÆ×•ÁÀ¿Ïÿœ^p(ÄŠˆOÎnrÁÿûä+(((((((((((((((((((((((((((((((((((((((DÿbÆíûÉú[“IEND®B`‚seafile-6.1.5/msi/seafile.wxs000066400000000000000000000206471323477647300161270ustar00rootroot00000000000000 1 SEAFILE_AUTO_START Installed AND (NOT VersionNT64) Installed AND VersionNT64 UPGRADINGPRODUCTCODE OR WIX_UPGRADE_DETECTED (NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") (NOT Installed) AND (NOT SUPPRESS_LAUNCH_SEAFILE_AFTER_INSTALL_FINISH) seafile-6.1.5/msi/shell.wxs000066400000000000000000000474361323477647300156330ustar00rootroot00000000000000 NOT VersionNT64 VersionNT64 seafile-6.1.5/msi/strip-files.py000066400000000000000000000010001323477647300165450ustar00rootroot00000000000000import glob import os os.chdir('bin') ignored = [] def do_strip(fn): try: os.system('strip "%s"' % fn) except Exception, e: print e else: print 'strip: ', fn for dll in glob.glob('*.dll'): if dll.startswith('python') or dll.startswith('msvc'): ignored.append(dll) continue else: do_strip(dll) for exe in glob.glob('*.exe'): do_strip(exe) print '----------------------------' print 'ignored:' for i in ignored: print '>> ', i seafile-6.1.5/msi/zh_CN.wxl000066400000000000000000000012671323477647300155060ustar00rootroot00000000000000 Seafile Seafile 安装包 Seafile 安装包 北京海文互知网络技术有é™å…¬å¸ 检测到您已ç»å®‰è£…了更新版本的 Seafile 。安装程åºå°†è‡ªåŠ¨é€€å‡º 删除 Seafile å¯åЍ Seafile 开机自动å¯åЍ Seafile seafile-6.1.5/python/000077500000000000000000000000001323477647300144745ustar00rootroot00000000000000seafile-6.1.5/python/Makefile.am000066400000000000000000000000221323477647300165220ustar00rootroot00000000000000SUBDIRS = seafile seafile-6.1.5/python/seafile/000077500000000000000000000000001323477647300161045ustar00rootroot00000000000000seafile-6.1.5/python/seafile/Makefile.am000066400000000000000000000001131323477647300201330ustar00rootroot00000000000000seafiledir=${pyexecdir}/seafile seafile_PYTHON = __init__.py rpcclient.py seafile-6.1.5/python/seafile/__init__.py000066400000000000000000000005671323477647300202250ustar00rootroot00000000000000 from rpcclient import SeafileRpcClient as RpcClient from rpcclient import SeafileThreadedRpcClient as ThreadedRpcClient from rpcclient import MonitorRpcClient as MonitorRpcClient from rpcclient import SeafServerRpcClient as ServerRpcClient from rpcclient import SeafServerThreadedRpcClient as ServerThreadedRpcClient class TaskType(object): DOWNLOAD = 0 UPLOAD = 1 seafile-6.1.5/python/seafile/rpcclient.py000066400000000000000000000736101323477647300204500ustar00rootroot00000000000000 import ccnet from pysearpc import searpc_func, SearpcError class SeafileRpcClient(ccnet.RpcClientBase): """RPC used in client""" def __init__(self, ccnet_client_pool, *args, **kwargs): ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafile-rpcserver", *args, **kwargs) @searpc_func("object", []) def seafile_get_session_info(): pass get_session_info = seafile_get_session_info @searpc_func("int", ["string"]) def seafile_calc_dir_size(path): pass calc_dir_size = seafile_calc_dir_size @searpc_func("int64", []) def seafile_get_total_block_size(): pass get_total_block_size = seafile_get_total_block_size; @searpc_func("string", ["string"]) def seafile_get_config(key): pass get_config = seafile_get_config @searpc_func("int", ["string", "string"]) def seafile_set_config(key, value): pass set_config = seafile_set_config @searpc_func("int", ["string"]) def seafile_get_config_int(key): pass get_config_int = seafile_get_config_int @searpc_func("int", ["string", "int"]) def seafile_set_config_int(key, value): pass set_config_int = seafile_set_config_int @searpc_func("int", ["int"]) def seafile_set_upload_rate_limit(limit): pass set_upload_rate_limit = seafile_set_upload_rate_limit @searpc_func("int", ["int"]) def seafile_set_download_rate_limit(limit): pass set_download_rate_limit = seafile_set_download_rate_limit ### repo @searpc_func("objlist", ["int", "int"]) def seafile_get_repo_list(): pass get_repo_list = seafile_get_repo_list @searpc_func("object", ["string"]) def seafile_get_repo(): pass get_repo = seafile_get_repo @searpc_func("string", ["string", "string", "string", "string", "string", "int"]) def seafile_create_repo(name, desc, passwd, base, relay_id, keep_history): pass create_repo = seafile_create_repo @searpc_func("int", ["string"]) def seafile_destroy_repo(repo_id): pass remove_repo = seafile_destroy_repo @searpc_func("objlist", ["string", "string", "string", "int"]) def seafile_diff(): pass get_diff = seafile_diff @searpc_func("object", ["string", "int", "string"]) def seafile_get_commit(repo_id, version, commit_id): pass get_commit = seafile_get_commit @searpc_func("objlist", ["string", "int", "int"]) def seafile_get_commit_list(): pass get_commit_list = seafile_get_commit_list @searpc_func("objlist", ["string"]) def seafile_branch_gets(repo_id): pass branch_gets = seafile_branch_gets @searpc_func("int", ["string", "string"]) def seafile_branch_add(repo_id, branch): pass branch_add = seafile_branch_add ##### clone related @searpc_func("string", ["string", "string"]) def gen_default_worktree(worktree_parent, repo_name): pass @searpc_func("string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"]) def seafile_clone(repo_id, repo_version, peer_id, repo_name, worktree, token, password, magic, peer_addr, peer_port, email, random_key, enc_version, more_info): pass clone = seafile_clone @searpc_func("string", ["string", "int", "string", "string", "string", "string", "string", "string", "string", "string", "string", "int", "string"]) def seafile_download(repo_id, repo_version, peer_id, repo_name, wt_parent, token, password, magic, peer_addr, peer_port, email, random_key, enc_version, more_info): pass download = seafile_download @searpc_func("int", ["string"]) def seafile_cancel_clone_task(repo_id): pass cancel_clone_task = seafile_cancel_clone_task @searpc_func("int", ["string"]) def seafile_remove_clone_task(repo_id): pass remove_clone_task = seafile_remove_clone_task @searpc_func("objlist", []) def seafile_get_clone_tasks(): pass get_clone_tasks = seafile_get_clone_tasks @searpc_func("object", ["string"]) def seafile_find_transfer_task(repo_id): pass find_transfer_task = seafile_find_transfer_task @searpc_func("object", ["string"]) def seafile_get_checkout_task(repo_id): pass get_checkout_task = seafile_get_checkout_task ### sync @searpc_func("int", ["string", "string"]) def seafile_sync(repo_id, peer_id): pass sync = seafile_sync @searpc_func("object", ["string"]) def seafile_get_repo_sync_task(): pass get_repo_sync_task = seafile_get_repo_sync_task @searpc_func("object", ["string"]) def seafile_get_repo_sync_info(): pass get_repo_sync_info = seafile_get_repo_sync_info @searpc_func("int", []) def seafile_is_auto_sync_enabled(): pass is_auto_sync_enabled = seafile_is_auto_sync_enabled ###### Property Management ######### @searpc_func("int", ["string", "string"]) def seafile_set_repo_passwd(repo_id, passwd): pass set_repo_passwd = seafile_set_repo_passwd @searpc_func("int", ["string", "string", "string"]) def seafile_set_repo_property(repo_id, key, value): pass set_repo_property = seafile_set_repo_property @searpc_func("string", ["string", "string"]) def seafile_get_repo_property(repo_id, key): pass get_repo_property = seafile_get_repo_property @searpc_func("string", ["string"]) def seafile_get_repo_relay_address(repo_id): pass get_repo_relay_address = seafile_get_repo_relay_address @searpc_func("string", ["string"]) def seafile_get_repo_relay_port(repo_id): pass get_repo_relay_port = seafile_get_repo_relay_port @searpc_func("int", ["string", "string", "string"]) def seafile_update_repo_relay_info(repo_id, addr, port): pass update_repo_relay_info = seafile_update_repo_relay_info @searpc_func("int", ["string", "string"]) def seafile_set_repo_token(repo_id, token): pass set_repo_token = seafile_set_repo_token @searpc_func("string", ["string"]) def seafile_get_repo_token(repo_id): pass get_repo_token = seafile_get_repo_token @searpc_func("object", ["int", "string", "string"]) def seafile_generate_magic_and_random_key(enc_version, repo_id, password): pass generate_magic_and_random_key = seafile_generate_magic_and_random_key class SeafileThreadedRpcClient(ccnet.RpcClientBase): """RPC used in client that run in a thread""" def __init__(self, ccnet_client_pool, *args, **kwargs): ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafile-threaded-rpcserver", *args, **kwargs) @searpc_func("int", ["string", "string", "string"]) def seafile_edit_repo(): pass edit_repo = seafile_edit_repo @searpc_func("int", ["string", "string"]) def seafile_reset(repo_id, commit_id): pass reset = seafile_reset @searpc_func("int", ["string", "string"]) def seafile_revert(repo_id, commit_id): pass revert = seafile_revert @searpc_func("int", ["string", "string"]) def seafile_add(repo_id, path): pass add = seafile_add @searpc_func("int", ["string", "string"]) def seafile_rm(): pass rm = seafile_rm @searpc_func("string", ["string", "string"]) def seafile_commit(repo_id, description): pass commit = seafile_commit class MonitorRpcClient(ccnet.RpcClientBase): def __init__(self, ccnet_client_pool): ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "monitor-rpcserver") @searpc_func("int", ["string"]) def monitor_get_repos_size(repo_ids): pass get_repos_size = monitor_get_repos_size class SeafServerRpcClient(ccnet.RpcClientBase): def __init__(self, ccnet_client_pool, *args, **kwargs): ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafserv-rpcserver", *args, **kwargs) # token for web access to repo @searpc_func("string", ["string", "string", "string", "string", "int"]) def seafile_web_get_access_token(repo_id, obj_id, op, username, use_onetime=1): pass web_get_access_token = seafile_web_get_access_token @searpc_func("object", ["string"]) def seafile_web_query_access_token(token): pass web_query_access_token = seafile_web_query_access_token @searpc_func("string", ["string"]) def seafile_query_zip_progress(token): pass query_zip_progress = seafile_query_zip_progress ###### GC #################### @searpc_func("int", []) def seafile_gc(): pass gc = seafile_gc @searpc_func("int", []) def seafile_gc_get_progress(): pass gc_get_progress = seafile_gc_get_progress # password management @searpc_func("int", ["string", "string"]) def seafile_is_passwd_set(repo_id, user): pass is_passwd_set = seafile_is_passwd_set @searpc_func("object", ["string", "string"]) def seafile_get_decrypt_key(repo_id, user): pass get_decrypt_key = seafile_get_decrypt_key # Copy tasks @searpc_func("object", ["string"]) def get_copy_task(task_id): pass @searpc_func("int", ["string"]) def cancel_copy_task(task_id): pass class SeafServerThreadedRpcClient(ccnet.RpcClientBase): def __init__(self, ccnet_client_pool, *args, **kwargs): ccnet.RpcClientBase.__init__(self, ccnet_client_pool, "seafserv-threaded-rpcserver", *args, **kwargs) # repo manipulation @searpc_func("string", ["string", "string", "string", "string"]) def seafile_create_repo(name, desc, owner_email, passwd): pass create_repo = seafile_create_repo @searpc_func("string", ["string", "string", "string", "string", "string", "string", "int"]) def seafile_create_enc_repo(repo_id, name, desc, owner_email, magic, random_key, enc_version): pass create_enc_repo = seafile_create_enc_repo @searpc_func("object", ["string"]) def seafile_get_repo(repo_id): pass get_repo = seafile_get_repo @searpc_func("int", ["string"]) def seafile_destroy_repo(repo_id): pass remove_repo = seafile_destroy_repo @searpc_func("objlist", ["int", "int"]) def seafile_get_repo_list(start, limit): pass get_repo_list = seafile_get_repo_list @searpc_func("int64", []) def seafile_count_repos(): pass count_repos = seafile_count_repos @searpc_func("int", ["string", "string", "string", "string"]) def seafile_edit_repo(repo_id, name, description, user): pass edit_repo = seafile_edit_repo @searpc_func("int", ["string", "string"]) def seafile_is_repo_owner(user_id, repo_id): pass is_repo_owner = seafile_is_repo_owner @searpc_func("int", ["string", "string"]) def seafile_set_repo_owner(email, repo_id): pass set_repo_owner = seafile_set_repo_owner @searpc_func("string", ["string"]) def seafile_get_repo_owner(repo_id): pass get_repo_owner = seafile_get_repo_owner @searpc_func("objlist", []) def seafile_get_orphan_repo_list(): pass get_orphan_repo_list = seafile_get_orphan_repo_list @searpc_func("objlist", ["string", "int"]) def seafile_list_owned_repos(user_id, ret_corrupted): pass list_owned_repos = seafile_list_owned_repos @searpc_func("int64", ["string"]) def seafile_server_repo_size(repo_id): pass server_repo_size = seafile_server_repo_size @searpc_func("int", ["string", "string"]) def seafile_repo_set_access_property(repo_id, role): pass repo_set_access_property = seafile_repo_set_access_property @searpc_func("string", ["string"]) def seafile_repo_query_access_property(repo_id): pass repo_query_access_property = seafile_repo_query_access_property @searpc_func("int", ["string", "string", "string"]) def seafile_revert_on_server(repo_id, commit_id, user_name): pass revert_on_server = seafile_revert_on_server @searpc_func("objlist", ["string", "string", "string"]) def seafile_diff(): pass get_diff = seafile_diff @searpc_func("int", ["string", "string", "string", "string", "string"]) def seafile_post_file(repo_id, tmp_file_path, parent_dir, filename, user): pass post_file = seafile_post_file @searpc_func("int", ["string", "string", "string", "string"]) def seafile_post_dir(repo_id, parent_dir, new_dir_name, user): pass post_dir = seafile_post_dir @searpc_func("int", ["string", "string", "string", "string"]) def seafile_post_empty_file(repo_id, parent_dir, filename, user): pass post_empty_file = seafile_post_empty_file @searpc_func("int", ["string", "string", "string", "string", "string", "string"]) def seafile_put_file(repo_id, tmp_file_path, parent_dir, filename, user, head_id): pass put_file = seafile_put_file @searpc_func("int", ["string", "string", "string", "string"]) def seafile_del_file(repo_id, parent_dir, filename, user): pass del_file = seafile_del_file @searpc_func("object", ["string", "string", "string", "string", "string", "string", "string", "int", "int"]) def seafile_copy_file(src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, user, need_progress, synchronous): pass copy_file = seafile_copy_file @searpc_func("object", ["string", "string", "string", "string", "string", "string", "int", "string", "int", "int"]) def seafile_move_file(src_repo, src_dir, src_filename, dst_repo, dst_dir, dst_filename, replace, user, need_progress, synchronous): pass move_file = seafile_move_file @searpc_func("int", ["string", "string", "string", "string", "string"]) def seafile_rename_file(repo_id, parent_dir, oldname, newname, user): pass rename_file = seafile_rename_file @searpc_func("int", ["string", "string"]) def seafile_is_valid_filename(repo_id, filename): pass is_valid_filename = seafile_is_valid_filename @searpc_func("object", ["string", "int", "string"]) def seafile_get_commit(repo_id, version, commit_id): pass get_commit = seafile_get_commit @searpc_func("string", ["string", "string", "int", "int"]) def seafile_list_file_blocks(repo_id, file_id, offset, limit): pass list_file_blocks = seafile_list_file_blocks @searpc_func("objlist", ["string", "string", "int", "int"]) def seafile_list_dir(repo_id, dir_id, offset, limit): pass list_dir = seafile_list_dir @searpc_func("objlist", ["string", "string", "sting", "string", "int", "int"]) def list_dir_with_perm(repo_id, dir_path, dir_id, user, offset, limit): pass @searpc_func("int64", ["string", "int", "string"]) def seafile_get_file_size(store_id, version, file_id): pass get_file_size = seafile_get_file_size @searpc_func("int64", ["string", "int", "string"]) def seafile_get_dir_size(store_id, version, dir_id): pass get_dir_size = seafile_get_dir_size @searpc_func("objlist", ["string", "string", "string"]) def seafile_list_dir_by_path(repo_id, commit_id, path): pass list_dir_by_path = seafile_list_dir_by_path @searpc_func("string", ["string", "string", "string"]) def seafile_get_dir_id_by_commit_and_path(repo_id, commit_id, path): pass get_dir_id_by_commit_and_path = seafile_get_dir_id_by_commit_and_path @searpc_func("string", ["string", "string"]) def seafile_get_file_id_by_path(repo_id, path): pass get_file_id_by_path = seafile_get_file_id_by_path @searpc_func("string", ["string", "string"]) def seafile_get_dir_id_by_path(repo_id, path): pass get_dir_id_by_path = seafile_get_dir_id_by_path @searpc_func("string", ["string", "string", "string"]) def seafile_get_file_id_by_commit_and_path(repo_id, commit_id, path): pass get_file_id_by_commit_and_path = seafile_get_file_id_by_commit_and_path @searpc_func("object", ["string", "string"]) def seafile_get_dirent_by_path(repo_id, commit_id, path): pass get_dirent_by_path = seafile_get_dirent_by_path @searpc_func("objlist", ["string", "string", "int", "int", "int"]) def seafile_list_file_revisions(repo_id, path, max_revision, limit, show_days): pass list_file_revisions = seafile_list_file_revisions @searpc_func("objlist", ["string", "string"]) def seafile_calc_files_last_modified(repo_id, parent_dir, limit): pass calc_files_last_modified = seafile_calc_files_last_modified @searpc_func("int", ["string", "string", "string", "string"]) def seafile_revert_file(repo_id, commit_id, path, user): pass revert_file = seafile_revert_file @searpc_func("string", ["string", "string"]) def seafile_check_repo_blocks_missing(repo_id, blklist): pass check_repo_blocks_missing = seafile_check_repo_blocks_missing @searpc_func("int", ["string", "string", "string", "string"]) def seafile_revert_dir(repo_id, commit_id, path, user): pass revert_dir = seafile_revert_dir @searpc_func("objlist", ["string", "int", "string", "string", "int"]) def get_deleted(repo_id, show_days, path, scan_stat, limit): pass # share repo to user @searpc_func("string", ["string", "string", "string", "string"]) def seafile_add_share(repo_id, from_email, to_email, permission): pass add_share = seafile_add_share @searpc_func("objlist", ["string", "string", "int", "int"]) def seafile_list_share_repos(email, query_col, start, limit): pass list_share_repos = seafile_list_share_repos @searpc_func("objlist", ["string", "string"]) def seafile_list_repo_shared_to(from_user, repo_id): pass list_repo_shared_to = seafile_list_repo_shared_to @searpc_func("int", ["string", "string", "string", "string", "string", "string"]) def share_subdir_to_user(repo_id, path, owner, share_user, permission, passwd): pass @searpc_func("int", ["string", "string", "string", "string"]) def unshare_subdir_for_user(repo_id, path, owner, share_user): pass @searpc_func("int", ["string", "string", "string", "string", "string"]) def update_share_subdir_perm_for_user(repo_id, path, owner, share_user, permission): pass @searpc_func("objlist", ["int", "string", "string", "int", "int"]) def seafile_list_org_share_repos(org_id, email, query_col, start, limit): pass list_org_share_repos = seafile_list_org_share_repos @searpc_func("int", ["string", "string", "string"]) def seafile_remove_share(repo_id, from_email, to_email): pass remove_share = seafile_remove_share @searpc_func("int", ["string", "string", "string", "string"]) def set_share_permission(repo_id, from_email, to_email, permission): pass # share repo to group @searpc_func("int", ["string", "int", "string", "string"]) def seafile_group_share_repo(repo_id, group_id, user_name, permisson): pass group_share_repo = seafile_group_share_repo @searpc_func("int", ["string", "int", "string"]) def seafile_group_unshare_repo(repo_id, group_id, user_name): pass group_unshare_repo = seafile_group_unshare_repo @searpc_func("string", ["string"]) def seafile_get_shared_groups_by_repo(repo_id): pass get_shared_groups_by_repo=seafile_get_shared_groups_by_repo @searpc_func("objlist", ["string", "string"]) def seafile_list_repo_shared_group(from_user, repo_id): pass list_repo_shared_group = seafile_list_repo_shared_group @searpc_func("objlist", ["string", "string", "string"]) def seafile_get_shared_users_for_subdir(repo_id, path, from_user): pass get_shared_users_for_subdir = seafile_get_shared_users_for_subdir @searpc_func("objlist", ["string", "string", "string"]) def seafile_get_shared_groups_for_subdir(repo_id, path, from_user): pass get_shared_groups_for_subdir = seafile_get_shared_groups_for_subdir @searpc_func("int", ["string", "string", "string", "int", "string", "string"]) def share_subdir_to_group(repo_id, path, owner, share_group, permission, passwd): pass @searpc_func("int", ["string", "string", "string", "int"]) def unshare_subdir_for_group(repo_id, path, owner, share_group): pass @searpc_func("int", ["string", "string", "string", "int", "string"]) def update_share_subdir_perm_for_group(repo_id, path, owner, share_group, permission): pass @searpc_func("string", ["int"]) def seafile_get_group_repoids(group_id): pass get_group_repoids = seafile_get_group_repoids @searpc_func("objlist", ["int"]) def seafile_get_repos_by_group(group_id): pass get_repos_by_group = seafile_get_repos_by_group @searpc_func("objlist", ["string"]) def get_group_repos_by_owner(user_name): pass @searpc_func("string", ["string"]) def get_group_repo_owner(repo_id): pass @searpc_func("int", ["int", "string"]) def seafile_remove_repo_group(group_id, user_name): pass remove_repo_group = seafile_remove_repo_group @searpc_func("int", ["int", "string", "string"]) def set_group_repo_permission(group_id, repo_id, permission): pass # branch and commit @searpc_func("objlist", ["string"]) def seafile_branch_gets(repo_id): pass branch_gets = seafile_branch_gets @searpc_func("objlist", ["string", "int", "int"]) def seafile_get_commit_list(repo_id, offset, limit): pass get_commit_list = seafile_get_commit_list ###### Token #################### @searpc_func("int", ["string", "string", "string"]) def seafile_set_repo_token(repo_id, email, token): pass set_repo_token = seafile_set_repo_token @searpc_func("string", ["string", "string"]) def seafile_get_repo_token_nonnull(repo_id, email): """Get the token of the repo for the email user. If the token does not exist, a new one is generated and returned. """ pass get_repo_token_nonnull = seafile_get_repo_token_nonnull @searpc_func("string", ["string", "string"]) def seafile_generate_repo_token(repo_id, email): pass generate_repo_token = seafile_generate_repo_token @searpc_func("int", ["string", "string"]) def seafile_delete_repo_token(repo_id, token, user): pass delete_repo_token = seafile_delete_repo_token @searpc_func("objlist", ["string"]) def seafile_list_repo_tokens(repo_id): pass list_repo_tokens = seafile_list_repo_tokens @searpc_func("objlist", ["string"]) def seafile_list_repo_tokens_by_email(email): pass list_repo_tokens_by_email = seafile_list_repo_tokens_by_email @searpc_func("int", ["string", "string"]) def seafile_delete_repo_tokens_by_peer_id(email, user_id): pass delete_repo_tokens_by_peer_id = seafile_delete_repo_tokens_by_peer_id @searpc_func("int", ["string"]) def delete_repo_tokens_by_email(email): pass ###### quota ########## @searpc_func("int64", ["string"]) def seafile_get_user_quota_usage(user_id): pass get_user_quota_usage = seafile_get_user_quota_usage @searpc_func("int64", ["string"]) def seafile_get_user_share_usage(user_id): pass get_user_share_usage = seafile_get_user_share_usage @searpc_func("int64", ["int"]) def seafile_get_org_quota_usage(org_id): pass get_org_quota_usage = seafile_get_org_quota_usage @searpc_func("int64", ["int", "string"]) def seafile_get_org_user_quota_usage(org_id, user): pass get_org_user_quota_usage = seafile_get_org_user_quota_usage @searpc_func("int", ["string", "int64"]) def set_user_quota(user, quota): pass @searpc_func("int64", ["string"]) def get_user_quota(user): pass @searpc_func("int", ["int", "int64"]) def set_org_quota(org_id, quota): pass @searpc_func("int64", ["int"]) def get_org_quota(org_id): pass @searpc_func("int", ["int", "string", "int64"]) def set_org_user_quota(org_id, user, quota): pass @searpc_func("int64", ["int", "string"]) def get_org_user_quota(org_id, user): pass @searpc_func("int", ["string"]) def check_quota(repo_id): pass # password management @searpc_func("int", ["string", "string"]) def seafile_check_passwd(repo_id, magic): pass check_passwd = seafile_check_passwd @searpc_func("int", ["string", "string", "string"]) def seafile_set_passwd(repo_id, user, passwd): pass set_passwd = seafile_set_passwd @searpc_func("int", ["string", "string"]) def seafile_unset_passwd(repo_id, user, passwd): pass unset_passwd = seafile_unset_passwd # repo permission checking @searpc_func("string", ["string", "string"]) def check_permission(repo_id, user): pass # folder permission check @searpc_func("string", ["string", "string", "string"]) def check_permission_by_path(repo_id, path, user): pass # org repo @searpc_func("string", ["string", "string", "string", "string", "string", "int", "int"]) def seafile_create_org_repo(name, desc, user, passwd, magic, random_key, enc_version, org_id): pass create_org_repo = seafile_create_org_repo @searpc_func("int", ["string"]) def seafile_get_org_id_by_repo_id(repo_id): pass get_org_id_by_repo_id = seafile_get_org_id_by_repo_id @searpc_func("objlist", ["int", "int", "int"]) def seafile_get_org_repo_list(org_id, start, limit): pass get_org_repo_list = seafile_get_org_repo_list @searpc_func("int", ["int"]) def seafile_remove_org_repo_by_org_id(org_id): pass remove_org_repo_by_org_id = seafile_remove_org_repo_by_org_id @searpc_func("objlist", ["int", "string"]) def list_org_repos_by_owner(org_id, user): pass @searpc_func("string", ["string"]) def get_org_repo_owner(repo_id): pass # org group repo @searpc_func("int", ["string", "int", "int", "string", "string"]) def add_org_group_repo(repo_id, org_id, group_id, owner, permission): pass @searpc_func("int", ["string", "int", "int"]) def del_org_group_repo(repo_id, org_id, group_id): pass @searpc_func("string", ["int", "int"]) def get_org_group_repoids(org_id, group_id): pass @searpc_func("string", ["int", "int", "string"]) def get_org_group_repo_owner(org_id, group_id, repo_id): pass @searpc_func("objlist", ["int", "string"]) def get_org_group_repos_by_owner(org_id, user): pass @searpc_func("string", ["int", "string"]) def get_org_groups_by_repo(org_id, repo_id): pass @searpc_func("int", ["int", "int", "string", "string"]) def set_org_group_repo_permission(org_id, group_id, repo_id, permission): pass # inner pub repo @searpc_func("int", ["string", "string"]) def set_inner_pub_repo(repo_id, permission): pass @searpc_func("int", ["string"]) def unset_inner_pub_repo(repo_id): pass @searpc_func("objlist", []) def list_inner_pub_repos(): pass @searpc_func("objlist", ["string"]) def list_inner_pub_repos_by_owner(user): pass @searpc_func("int64", []) def count_inner_pub_repos(): pass @searpc_func("int", ["string"]) def is_inner_pub_repo(repo_id): pass # org inner pub repo @searpc_func("int", ["int", "string", "string"]) def set_org_inner_pub_repo(org_id, repo_id, permission): pass @searpc_func("int", ["int", "string"]) def unset_org_inner_pub_repo(org_id, repo_id): pass @searpc_func("objlist", ["int"]) def list_org_inner_pub_repos(org_id): pass @searpc_func("objlist", ["int", "string"]) def list_org_inner_pub_repos_by_owner(org_id, user): pass @searpc_func("int", ["string", "int"]) def set_repo_history_limit(repo_id, days): pass @searpc_func("int", ["string"]) def get_repo_history_limit(repo_id): pass # virtual repo @searpc_func("string", ["string", "string", "string", "string", "string", "string"]) def create_virtual_repo(origin_repo_id, path, repo_name, repo_desc, owner, passwd=''): pass @searpc_func("objlist", ["string"]) def get_virtual_repos_by_owner(owner): pass @searpc_func("object", ["string", "string", "string"]) def get_virtual_repo(origin_repo, path, owner): pass # system default library @searpc_func("string", []) def get_system_default_repo_id(): pass # Change password @searpc_func("int", ["string", "string", "string", "string"]) def seafile_change_repo_passwd(repo_id, old_passwd, new_passwd, user): pass change_repo_passwd = seafile_change_repo_passwd # Clean trash @searpc_func("int", ["string", "int"]) def clean_up_repo_history(repo_id, keep_days): pass # Trashed repos @searpc_func("objlist", ["int", "int"]) def get_trash_repo_list(start, limit): pass @searpc_func("int", ["string"]) def del_repo_from_trash(repo_id): pass @searpc_func("int", ["string"]) def restore_repo_from_trash(repo_id): pass @searpc_func("objlist", ["string"]) def get_trash_repos_by_owner(owner): pass @searpc_func("int", []) def empty_repo_trash(): pass @searpc_func("int", ["string"]) def empty_repo_trash_by_owner(owner): pass @searpc_func("object", ["string"]) def empty_repo_trash_by_owner(owner): pass @searpc_func("object", ["int", "string", "string"]) def generate_magic_and_random_key(enc_version, repo_id, password): pass seafile-6.1.5/scripts/000077500000000000000000000000001323477647300146425ustar00rootroot00000000000000seafile-6.1.5/scripts/breakpad.py000077500000000000000000000033711323477647300167740ustar00rootroot00000000000000#!/usr/bin/env python #coding: UTF-8 """Generate the breakpad symbol file and place it in the directory structure required by breakpad `minidump_stackwalk` tool. The directory is ./symbols/seaf-daemon.exe/${symbol_id}/seaf-daemon.exe.sym, where symbol_id is the first line of the "dump_syms" output. """ from __future__ import print_function import os from os.path import abspath, basename, exists, dirname, join import re import sys import subprocess import optparse def call(*a, **kw): kw.setdefault('shell', True) subprocess.check_call(*a, **kw) def get_command_output(cmd, **kw): shell = not isinstance(cmd, list) return subprocess.check_output(cmd, shell=shell, **kw) def main(): parser = optparse.OptionParser() parser.add_option('--output', help='the path of the symbol file.') args, _ = parser.parse_args() seafile_src_dir = dirname(abspath(dirname(__file__))) os.chdir(seafile_src_dir) program = 'seaf-daemon.exe' if os.name == 'nt' else 'seaf-daemon' seaf_daemon = join('daemon', '.libs', program) if not exists(seaf_daemon): seaf_daemon = join('daemon', program) if not exists(seaf_daemon): raise RuntimeError('seaf-daemon executable not found!') symbols = get_command_output('dump_syms {}'.format(seaf_daemon)) if args.output: symbol_file = args.output else: symbol_id = symbols.splitlines()[0].split()[3] symbol_dir = join('symbols', program, symbol_id) if not exists(symbol_dir): os.makedirs(symbol_dir) symbol_file = join(symbol_dir, '{}.sym'.format(program)) print('symbols written to {}'.format(symbol_file)) with open(symbol_file, 'w') as fp: fp.write(symbols) if __name__ == '__main__': main() seafile-6.1.5/scripts/build/000077500000000000000000000000001323477647300157415ustar00rootroot00000000000000seafile-6.1.5/scripts/build/build-cli.py000077500000000000000000000527171323477647300201760ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This scirpt builds the seafile command line client (With no gui). Some notes: ''' import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) import os import commands import tempfile import shutil import re import subprocess import optparse import atexit #################### ### Global variables #################### # command line configuartion conf = {} # key names in the conf dictionary. CONF_VERSION = 'version' CONF_SEAFILE_VERSION = 'seafile_version' CONF_LIBSEARPC_VERSION = 'libsearpc_version' CONF_CCNET_VERSION = 'ccnet_version' CONF_SRCDIR = 'srcdir' CONF_KEEP = 'keep' CONF_BUILDDIR = 'builddir' CONF_OUTPUTDIR = 'outputdir' CONF_THIRDPARTDIR = 'thirdpartdir' CONF_NO_STRIP = 'nostrip' #################### ### Common helper functions #################### def highlight(content, is_error=False): '''Add ANSI color to content to get it highlighted on terminal''' if is_error: return '\x1b[1;31m%s\x1b[m' % content else: return '\x1b[1;32m%s\x1b[m' % content def info(msg): print highlight('[INFO] ') + msg def exist_in_path(prog): '''Test whether prog exists in system path''' dirs = os.environ['PATH'].split(':') for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return True return False def prepend_env_value(name, value, seperator=':'): '''append a new value to a list''' try: current_value = os.environ[name] except KeyError: current_value = '' new_value = value if current_value: new_value += seperator + current_value os.environ[name] = new_value def error(msg=None, usage=None): if msg: print highlight('[ERROR] ') + msg if usage: print usage sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Like run_argv but specify a command line string instead of argv''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) return proc.wait() def must_mkdir(path): '''Create a directory, exit on failure''' try: os.mkdir(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) class Project(object): '''Base class for a project''' # Probject name, i.e. libseaprc/ccnet/seafile/ name = '' # A list of shell commands to configure/build the project build_commands = [] def __init__(self): # the path to pass to --prefix=/ self.prefix = os.path.join(conf[CONF_BUILDDIR], 'seafile-cli') self.version = self.get_version() self.src_tarball = os.path.join(conf[CONF_SRCDIR], '%s-%s.tar.gz' % (self.name, self.version)) # project dir, like /seafile-1.2.2/ self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) def get_version(self): # libsearpc and ccnet can have different versions from seafile. raise NotImplementedError def get_source_commit_id(self): '''By convetion, we record the commit id of the source code in the file "/latest_commit" ''' latest_commit_file = os.path.join(self.projdir, 'latest_commit') with open(latest_commit_file, 'r') as fp: commit_id = fp.read().strip('\n\r\t ') return commit_id def append_cflags(self, macros): cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) prepend_env_value('CPPFLAGS', cflags, seperator=' ') def uncompress(self): '''Uncompress the source from the tarball''' info('Uncompressing %s' % self.name) if run('tar xf %s' % self.src_tarball) < 0: error('failed to uncompress source of %s' % self.name) def before_build(self): '''Hook method to do project-specific stuff before running build commands''' pass def build(self): '''Build the source''' self.before_build() info('Building %s' % self.name) for cmd in self.build_commands: if run(cmd, cwd=self.projdir) != 0: error('error when running command:\n\t%s\n' % cmd) class Libsearpc(Project): name = 'libsearpc' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-compile-demo' % self.prefix, 'make', 'make install' ] def get_version(self): return conf[CONF_LIBSEARPC_VERSION] class Ccnet(Project): name = 'ccnet' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-compile-demo' % self.prefix, 'make', 'make install' ] def get_version(self): return conf[CONF_CCNET_VERSION] def before_build(self): macros = {} # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class Seafile(Project): name = 'seafile' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-gui' % self.prefix, 'make', 'make install' ] def get_version(self): return conf[CONF_SEAFILE_VERSION] def update_cli_version(self): '''Substitute the version number in seaf-cli''' cli_py = os.path.join(self.projdir, 'app', 'seaf-cli') with open(cli_py, 'r') as fp: lines = fp.readlines() ret = [] for line in lines: old = '''SEAF_CLI_VERSION = ""''' new = '''SEAF_CLI_VERSION = "%s"''' % conf[CONF_VERSION] line = line.replace(old, new) ret.append(line) with open(cli_py, 'w') as fp: fp.writelines(ret) def before_build(self): self.update_cli_version() macros = {} # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) def check_targz_src(proj, version, srcdir): src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) if not os.path.exists(src_tarball): error('%s not exists' % src_tarball) def validate_args(usage, options): required_args = [ CONF_VERSION, CONF_LIBSEARPC_VERSION, CONF_CCNET_VERSION, CONF_SEAFILE_VERSION, CONF_SRCDIR, ] # fist check required args for optname in required_args: if getattr(options, optname, None) == None: error('%s must be specified' % optname, usage=usage) def get_option(optname): return getattr(options, optname) # [ version ] def check_project_version(version): '''A valid version must be like 1.2.2, 1.3''' if not re.match('^[0-9]+(\.([0-9])+)+$', version): error('%s is not a valid version' % version, usage=usage) version = get_option(CONF_VERSION) seafile_version = get_option(CONF_SEAFILE_VERSION) libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) ccnet_version = get_option(CONF_CCNET_VERSION) check_project_version(version) check_project_version(libsearpc_version) check_project_version(ccnet_version) check_project_version(seafile_version) # [ srcdir ] srcdir = get_option(CONF_SRCDIR) check_targz_src('libsearpc', libsearpc_version, srcdir) check_targz_src('ccnet', ccnet_version, srcdir) check_targz_src('seafile', seafile_version, srcdir) # [ builddir ] builddir = get_option(CONF_BUILDDIR) if not os.path.exists(builddir): error('%s does not exist' % builddir, usage=usage) builddir = os.path.join(builddir, 'seafile-cli-build') # [ outputdir ] outputdir = get_option(CONF_OUTPUTDIR) if outputdir: if not os.path.exists(outputdir): error('outputdir %s does not exist' % outputdir, usage=usage) else: outputdir = os.getcwd() # [ keep ] keep = get_option(CONF_KEEP) # [ no strip] nostrip = get_option(CONF_NO_STRIP) conf[CONF_VERSION] = version conf[CONF_LIBSEARPC_VERSION] = libsearpc_version conf[CONF_SEAFILE_VERSION] = seafile_version conf[CONF_CCNET_VERSION] = ccnet_version conf[CONF_BUILDDIR] = builddir conf[CONF_SRCDIR] = srcdir conf[CONF_OUTPUTDIR] = outputdir conf[CONF_KEEP] = keep conf[CONF_NO_STRIP] = nostrip prepare_builddir(builddir) show_build_info() def show_build_info(): '''Print all conf information. Confirm before continue.''' info('------------------------------------------') info('Seafile command line client %s: BUILD INFO' % conf[CONF_VERSION]) info('------------------------------------------') info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) info('ccnet: %s' % conf[CONF_CCNET_VERSION]) info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) info('builddir: %s' % conf[CONF_BUILDDIR]) info('outputdir: %s' % conf[CONF_OUTPUTDIR]) info('source dir: %s' % conf[CONF_SRCDIR]) info('strip symbols: %s' % (not conf[CONF_NO_STRIP])) info('clean on exit: %s' % (not conf[CONF_KEEP])) info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') dummy = raw_input() def prepare_builddir(builddir): must_mkdir(builddir) if not conf[CONF_KEEP]: def remove_builddir(): '''Remove the builddir when exit''' info('remove builddir before exit') shutil.rmtree(builddir, ignore_errors=True) atexit.register(remove_builddir) os.chdir(builddir) must_mkdir(os.path.join(builddir, 'seafile-cli')) def parse_args(): parser = optparse.OptionParser() def long_opt(opt): return '--' + opt parser.add_option(long_opt(CONF_VERSION), dest=CONF_VERSION, nargs=1, help='the version to build. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_VERSION), dest=CONF_SEAFILE_VERSION, nargs=1, help='the version of seafile as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), dest=CONF_LIBSEARPC_VERSION, nargs=1, help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_CCNET_VERSION), dest=CONF_CCNET_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_BUILDDIR), dest=CONF_BUILDDIR, nargs=1, help='the directory to build the source. Defaults to /tmp', default=tempfile.gettempdir()) parser.add_option(long_opt(CONF_OUTPUTDIR), dest=CONF_OUTPUTDIR, nargs=1, help='the output directory to put the generated tarball. Defaults to the current directory.', default=os.getcwd()) parser.add_option(long_opt(CONF_SRCDIR), dest=CONF_SRCDIR, nargs=1, help='''Source tarballs must be placed in this directory.''') parser.add_option(long_opt(CONF_KEEP), dest=CONF_KEEP, action='store_true', help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') parser.add_option(long_opt(CONF_NO_STRIP), dest=CONF_NO_STRIP, action='store_true', help='''do not strip debug symbols''') usage = parser.format_help() options, remain = parser.parse_args() if remain: error(usage=usage) validate_args(usage, options) def setup_build_env(): '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' prefix = os.path.join(conf[CONF_BUILDDIR], 'seafile-cli') prepend_env_value('CPPFLAGS', '-I%s' % os.path.join(prefix, 'include'), seperator=' ') prepend_env_value('CPPFLAGS', '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], seperator=' ') if conf[CONF_NO_STRIP]: prepend_env_value('CPPFLAGS', '-g -O0', seperator=' ') prepend_env_value('LDFLAGS', '-L%s' % os.path.join(prefix, 'lib'), seperator=' ') prepend_env_value('LDFLAGS', '-L%s' % os.path.join(prefix, 'lib64'), seperator=' ') prepend_env_value('PATH', os.path.join(prefix, 'bin')) prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib', 'pkgconfig')) prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib64', 'pkgconfig')) def copy_scripts_and_libs(): '''Copy scripts and shared libs''' builddir = conf[CONF_BUILDDIR] seafile_dir = os.path.join(builddir, Seafile().projdir) scripts_srcdir = os.path.join(seafile_dir, 'scripts') doc_dir = os.path.join(seafile_dir, 'doc') cli_dir = os.path.join(builddir, 'seafile-cli') # copy the wrapper shell script for seaf-cli.py src = os.path.join(scripts_srcdir, 'seaf-cli-wrapper.sh') dst = os.path.join(cli_dir, 'seaf-cli') must_copy(src, dst) # copy Readme for cli client src = os.path.join(doc_dir, 'cli-readme.txt') dst = os.path.join(cli_dir, 'Readme.txt') must_copy(src, dst) # rename seaf-cli to seaf-cli.py to avoid confusing users src = os.path.join(cli_dir, 'bin', 'seaf-cli') dst = os.path.join(cli_dir, 'bin', 'seaf-cli.py') try: shutil.move(src, dst) except Exception, e: error('failed to move %s to %s: %s' % (src, dst, e)) # copy shared c libs copy_shared_libs() def get_dependent_libs(executable): syslibs = ['libsearpc', 'libccnet', 'libseafile', 'libpthread.so', 'libc.so', 'libm.so', 'librt.so', 'libdl.so', 'libselinux.so'] def is_syslib(lib): for syslib in syslibs: if syslib in lib: return True return False ldd_output = commands.getoutput('ldd %s' % executable) ret = [] for line in ldd_output.splitlines(): tokens = line.split() if len(tokens) != 4: continue if is_syslib(tokens[0]): continue ret.append(tokens[2]) return ret def copy_shared_libs(): '''copy shared c libs, such as libevent, glib, libmysqlclient''' builddir = conf[CONF_BUILDDIR] dst_dir = os.path.join(builddir, 'seafile-cli', 'lib') ccnet_daemon_path = os.path.join(builddir, 'seafile-cli', 'bin', 'ccnet') seaf_daemon_path = os.path.join(builddir, 'seafile-cli', 'bin', 'seaf-daemon') ccnet_daemon_libs = get_dependent_libs(ccnet_daemon_path) seaf_daemon_libs = get_dependent_libs(seaf_daemon_path) libs = ccnet_daemon_libs for lib in seaf_daemon_libs: if lib not in libs: libs.append(lib) for lib in libs: info('Copying %s' % lib) shutil.copy(lib, dst_dir) def strip_symbols(): def do_strip(fn): run('chmod u+w %s' % fn) info('stripping: %s' % fn) run('strip "%s"' % fn) def remove_static_lib(fn): info('removing: %s' % fn) os.remove(fn) builddir = conf[CONF_BUILDDIR] topdir = os.path.join(builddir, 'seafile-cli') for parent, dnames, fnames in os.walk(topdir): dummy = dnames # avoid pylint 'unused' warning for fname in fnames: fn = os.path.join(parent, fname) if os.path.isdir(fn): continue if fn.endswith(".a") or fn.endswith(".la"): remove_static_lib(fn) continue if os.path.islink(fn): continue finfo = commands.getoutput('file "%s"' % fn) if 'not stripped' in finfo: do_strip(fn) def create_tarball(tarball_name): '''call tar command to generate a tarball''' version = conf[CONF_VERSION] cli_dir = 'seafile-cli' versioned_cli_dir = 'seafile-cli-' + version # move seafile-cli to seafile-cli-${version} try: shutil.move(cli_dir, versioned_cli_dir) except Exception, e: error('failed to move %s to %s: %s' % (cli_dir, versioned_cli_dir, e)) ignored_patterns = [ # common ignored files '*.pyc', '*~', '*#', # seafile os.path.join(versioned_cli_dir, 'share*'), os.path.join(versioned_cli_dir, 'include*'), os.path.join(versioned_cli_dir, 'lib', 'pkgconfig*'), os.path.join(versioned_cli_dir, 'lib64', 'pkgconfig*'), os.path.join(versioned_cli_dir, 'bin', 'ccnet-demo*'), os.path.join(versioned_cli_dir, 'bin', 'ccnet-tool'), os.path.join(versioned_cli_dir, 'bin', 'ccnet-servtool'), os.path.join(versioned_cli_dir, 'bin', 'searpc-codegen.py'), os.path.join(versioned_cli_dir, 'bin', 'seafile-admin'), os.path.join(versioned_cli_dir, 'bin', 'seafile'), ] excludes_list = [ '--exclude=%s' % pattern for pattern in ignored_patterns ] excludes = ' '.join(excludes_list) tar_cmd = 'tar czvf %(tarball_name)s %(versioned_cli_dir)s %(excludes)s' \ % dict(tarball_name=tarball_name, versioned_cli_dir=versioned_cli_dir, excludes=excludes) if run(tar_cmd) != 0: error('failed to generate the tarball') def gen_tarball(): # strip symbols of libraries to reduce size if not conf[CONF_NO_STRIP]: try: strip_symbols() except Exception, e: error('failed to strip symbols: %s' % e) # determine the output name # 64-bit: seafile-cli_1.2.2_x86-64.tar.gz # 32-bit: seafile-cli_1.2.2_i386.tar.gz version = conf[CONF_VERSION] arch = os.uname()[-1].replace('_', '-') if arch != 'x86-64': arch = 'i386' dbg = '' if conf[CONF_NO_STRIP]: dbg = '.dbg' tarball_name = 'seafile-cli_%(version)s_%(arch)s%(dbg)s.tar.gz' \ % dict(version=version, arch=arch, dbg=dbg) dst_tarball = os.path.join(conf[CONF_OUTPUTDIR], tarball_name) # generate the tarball try: create_tarball(tarball_name) except Exception, e: error('failed to generate tarball: %s' % e) # move tarball to outputdir try: shutil.copy(tarball_name, dst_tarball) except Exception, e: error('failed to copy %s to %s: %s' % (tarball_name, dst_tarball, e)) print '---------------------------------------------' print 'The build is successfully. Output is:\t%s' % dst_tarball print '---------------------------------------------' def main(): parse_args() setup_build_env() libsearpc = Libsearpc() ccnet = Ccnet() seafile = Seafile() libsearpc.uncompress() libsearpc.build() ccnet.uncompress() ccnet.build() seafile.uncompress() seafile.build() copy_scripts_and_libs() gen_tarball() if __name__ == '__main__': main() seafile-6.1.5/scripts/build/build-deb.py000077500000000000000000000367711323477647300201630ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This scirpt builds the seafile server tarball. Some notes: 1. The working directory is always the 'builddir'. 'os.chdir' is only called to change to the 'builddir'. We make use of the 'cwd' argument in 'subprocess.Popen' to run a command in a specific directory. ''' import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) import os import glob import tempfile import shutil import re import subprocess import optparse import atexit #################### ### Global variables #################### # command line configuartion conf = {} # key names in the conf dictionary. CONF_VERSION = 'version' CONF_LIBSEARPC_VERSION = 'libsearpc_version' CONF_CCNET_VERSION = 'ccnet_version' CONF_SEAFILE_VERSION = 'seafile_version' CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' CONF_SRCDIR = 'srcdir' CONF_KEEP = 'keep' CONF_BUILDDIR = 'builddir' CONF_OUTPUTDIR = 'outputdir' CONF_NO_STRIP = 'nostrip' #################### ### Common helper functions #################### def highlight(content, is_error=False): '''Add ANSI color to content to get it highlighted on terminal''' if is_error: return '\x1b[1;31m%s\x1b[m' % content else: return '\x1b[1;32m%s\x1b[m' % content def info(msg): print highlight('[INFO] ') + msg def exist_in_path(prog): '''Test whether prog exists in system path''' dirs = os.environ['PATH'].split(':') for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return True return False def prepend_env_value(name, value, seperator=':'): '''append a new value to a list''' try: current_value = os.environ[name] except KeyError: current_value = '' new_value = value if current_value: new_value += seperator + current_value os.environ[name] = new_value def error(msg=None, usage=None): if msg: print highlight('[ERROR] ') + msg if usage: print usage sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Like run_argv but specify a command line string instead of argv''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) return proc.wait() def must_mkdir(path): '''Create a directory, exit on failure''' try: os.mkdir(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) class Project(object): '''Base class for a project''' # Probject name, i.e. libseaprc/ccnet/seafile/seahub name = '' # A list of shell commands to configure/build the project build_commands = [] def __init__(self): self.version = self.get_version() self.src_tarball = os.path.join(conf[CONF_SRCDIR], '%s-%s.tar.gz' % (self.name, self.version)) # project dir, like /seafile-1.2.2/ self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) def get_version(self): # libsearpc and ccnet can have different versions from seafile. raise NotImplementedError def get_source_commit_id(self): '''By convetion, we record the commit id of the source code in the file "/latest_commit" ''' latest_commit_file = os.path.join(self.projdir, 'latest_commit') with open(latest_commit_file, 'r') as fp: commit_id = fp.read().strip('\n\r\t ') return commit_id def append_cflags(self, macros): cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) prepend_env_value('DEB_CPPFLAGS_APPEND', cflags, seperator=' ') def uncompress(self): '''Uncompress the source from the tarball''' info('Uncompressing %s' % self.name) if run('tar xf %s' % self.src_tarball) < 0: error('failed to uncompress source of %s' % self.name) def before_build(self): '''Hook method to do project-specific stuff before running build commands''' pass def build(self): '''Build the source''' self.before_build() info('Building %s' % self.name) for cmd in self.build_commands: if run(cmd, cwd=self.projdir) != 0: error('error when running command:\n\t%s\n' % cmd) class Libsearpc(Project): name = 'libsearpc' def get_version(self): return conf[CONF_LIBSEARPC_VERSION] class Ccnet(Project): name = 'ccnet' def get_version(self): return conf[CONF_CCNET_VERSION] def before_build(self): macros = {} # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class SeafileClient(Project): name = 'seafile-client' def get_version(self): return conf[CONF_SEAFILE_CLIENT_VERSION] def before_build(self): pass class Seafile(Project): name = 'seafile' def __init__(self): Project.__init__(self) self.build_commands = [ 'dpkg-buildpackage -B -nc -uc -us', ] def get_version(self): return conf[CONF_SEAFILE_VERSION] def before_build(self): macros = {} # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) def check_targz_src(proj, version, srcdir): src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) if not os.path.exists(src_tarball): error('%s not exists' % src_tarball) def validate_args(usage, options): required_args = [ CONF_VERSION, CONF_LIBSEARPC_VERSION, CONF_CCNET_VERSION, CONF_SEAFILE_VERSION, CONF_SEAFILE_CLIENT_VERSION, CONF_SRCDIR, ] # fist check required args for optname in required_args: if getattr(options, optname, None) == None: error('%s must be specified' % optname, usage=usage) def get_option(optname): return getattr(options, optname) # [ version ] def check_project_version(version): '''A valid version must be like 1.2.2, 1.3''' if not re.match('^[0-9]+(\.([0-9])+)+$', version): error('%s is not a valid version' % version, usage=usage) version = get_option(CONF_VERSION) libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) ccnet_version = get_option(CONF_CCNET_VERSION) seafile_version = get_option(CONF_SEAFILE_VERSION) seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) check_project_version(version) check_project_version(libsearpc_version) check_project_version(ccnet_version) check_project_version(seafile_version) # [ srcdir ] srcdir = get_option(CONF_SRCDIR) check_targz_src('libsearpc', libsearpc_version, srcdir) check_targz_src('ccnet', ccnet_version, srcdir) check_targz_src('seafile', seafile_version, srcdir) check_targz_src('seafile-client', seafile_client_version, srcdir) # [ builddir ] builddir = get_option(CONF_BUILDDIR) if not os.path.exists(builddir): error('%s does not exist' % builddir, usage=usage) builddir = os.path.join(builddir, 'seafile-deb-build') # [ outputdir ] outputdir = get_option(CONF_OUTPUTDIR) if outputdir: if not os.path.exists(outputdir): error('outputdir %s does not exist' % outputdir, usage=usage) else: outputdir = os.getcwd() # [ keep ] keep = get_option(CONF_KEEP) # [ no strip] nostrip = get_option(CONF_NO_STRIP) conf[CONF_VERSION] = version conf[CONF_LIBSEARPC_VERSION] = libsearpc_version conf[CONF_CCNET_VERSION] = ccnet_version conf[CONF_SEAFILE_VERSION] = seafile_version conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version conf[CONF_BUILDDIR] = builddir conf[CONF_SRCDIR] = srcdir conf[CONF_OUTPUTDIR] = outputdir conf[CONF_KEEP] = True conf[CONF_NO_STRIP] = nostrip prepare_builddir(builddir) show_build_info() def show_build_info(): '''Print all conf information. Confirm before continue.''' info('------------------------------------------') info('Seafile debian package: BUILD INFO') info('------------------------------------------') info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) info('ccnet: %s' % conf[CONF_CCNET_VERSION]) info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) info('builddir: %s' % conf[CONF_BUILDDIR]) info('outputdir: %s' % conf[CONF_OUTPUTDIR]) info('source dir: %s' % conf[CONF_SRCDIR]) info('strip symbols: %s' % (not conf[CONF_NO_STRIP])) info('clean on exit: %s' % (not conf[CONF_KEEP])) info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') dummy = raw_input() def prepare_builddir(builddir): must_mkdir(builddir) if not conf[CONF_KEEP]: def remove_builddir(): '''Remove the builddir when exit''' info('remove builddir before exit') shutil.rmtree(builddir, ignore_errors=True) atexit.register(remove_builddir) os.chdir(builddir) def parse_args(): parser = optparse.OptionParser() def long_opt(opt): return '--' + opt parser.add_option(long_opt(CONF_VERSION), dest=CONF_VERSION, nargs=1, help='the version to build. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), dest=CONF_LIBSEARPC_VERSION, nargs=1, help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_CCNET_VERSION), dest=CONF_CCNET_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_VERSION), dest=CONF_SEAFILE_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), dest=CONF_SEAFILE_CLIENT_VERSION, nargs=1, help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_BUILDDIR), dest=CONF_BUILDDIR, nargs=1, help='the directory to build the source. Defaults to /tmp', default=tempfile.gettempdir()) parser.add_option(long_opt(CONF_OUTPUTDIR), dest=CONF_OUTPUTDIR, nargs=1, help='the output directory to put the generated server tarball. Defaults to the current directory.', default=os.getcwd()) parser.add_option(long_opt(CONF_SRCDIR), dest=CONF_SRCDIR, nargs=1, help='''Source tarballs must be placed in this directory.''') parser.add_option(long_opt(CONF_KEEP), dest=CONF_KEEP, action='store_true', help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') parser.add_option(long_opt(CONF_NO_STRIP), dest=CONF_NO_STRIP, action='store_true', help='''do not strip debug symbols''') usage = parser.format_help() options, remain = parser.parse_args() if remain: error(usage=usage) validate_args(usage, options) def setup_build_env(): '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' prefix = os.path.join(Seafile().projdir, 'debian', 'seafile', 'usr') prepend_env_value('DEB_CPPFLAGS_APPEND', '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], seperator=' ') if conf[CONF_NO_STRIP]: prepend_env_value('DEB_CPPFLAGS_APPEND', '-g -O0', seperator=' ') os.environ['SEAFILE_NOSTRIP'] = 'true' os.environ['DEB_CFLAGS_SET'] = '' os.environ['DEB_CXXFLAGS_SET'] = '' prepend_env_value('PATH', os.path.join(prefix, 'bin')) prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib', 'pkgconfig')) os.environ['LIBSEARPC_SOURCE_DIR'] = Libsearpc().projdir os.environ['CCNET_SOURCE_DIR'] = Ccnet().projdir os.environ['SEAFILE_CLIENT_SOURCE_DIR'] = SeafileClient().projdir def move_deb(): builddir = conf[CONF_BUILDDIR] deb_name = glob.glob('*.deb')[0] src_deb = os.path.join(builddir, deb_name) dst_deb = os.path.join(conf[CONF_OUTPUTDIR], deb_name) # move deb to outputdir try: shutil.move(src_deb, dst_deb) except Exception, e: error('failed to copy %s to %s: %s' % (src_deb, dst_deb, e)) print '---------------------------------------------' print 'The build is successfully. Output is:\t%s' % dst_deb print '---------------------------------------------' def main(): parse_args() setup_build_env() libsearpc = Libsearpc() ccnet = Ccnet() seafile = Seafile() seafile_client = SeafileClient() libsearpc.uncompress() ccnet.uncompress() seafile.uncompress() seafile_client.uncompress() libsearpc.build() ccnet.build() seafile.build() seafile_client.build() move_deb() if __name__ == '__main__': main() seafile-6.1.5/scripts/build/build-mac.py000077500000000000000000001075011323477647300201570ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This script builds the seafile mac client. ''' import atexit import logging import commands from contextlib import contextmanager import glob import multiprocessing import optparse import os from os.path import abspath, basename, dirname, join, exists, expanduser import re import shutil import subprocess import sys import tempfile FINAL_APP = 'Seafile Client.app' FSPLUGIN_APPEX_NAME = 'Seafile FinderSync.appex' CERT_ID = '1E9F00CBCF84C2BE8BE2A99A65F30BD5EB4D1E70' if 'SEAFILE_BUILD_SLAVE' not in os.environ: import fabric from fabric.api import execute, env, settings, run as fabric_run from fabric.operations import put as put_file, get as get_file # fabric login configs env.user = 'vagrant' env.password = 'vagrant' env.use_ssh_config = True #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) #################### ### Global variables #################### # command line configuartion conf = {} # key names in the conf dictionary. # pylint: disable=bad-whitespace CONF_CLEAN = 'clean' CONF_MODE = 'mode' CONF_VERSION = 'version' CONF_SEAFILE_VERSION = 'seafile_version' CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' CONF_LIBSEARPC_VERSION = 'libsearpc_version' CONF_CCNET_VERSION = 'ccnet_version' CONF_SRCDIR = 'srcdir' CONF_KEEP = 'keep' CONF_BUILDDIR = 'builddir' CONF_OUTPUTDIR = 'outputdir' CONF_THIRDPARTDIR = 'thirdpartdir' CONF_NO_STRIP = 'nostrip' CONF_SLAVE_HOST = 'slave_host' CONF_BRAND = 'brand' CONF_LOCAL = 'local' # pylint: enable=bad-whitespace NUM_CPU = multiprocessing.cpu_count() PID = os.getpid() SLAVE_WORKDIR = expanduser('~/tmp/seafile-mac-build-slave') SLAVE_SRCDIR = join(SLAVE_WORKDIR, 'srcs') SLAVE_BUILDDIR = join(SLAVE_WORKDIR, 'build') SLAVE_BUILD_SCRIPT = join(SLAVE_WORKDIR, 'build-mac.py') #################### ### Common helper functions #################### def highlight(content, is_error=False): '''Add ANSI color to content to get it highlighted on terminal''' if is_error: return '\x1b[1;31m%s\x1b[m' % content else: return '\x1b[1;32m%s\x1b[m' % content def info(msg): logging.info(highlight('[INFO][{}] ').format(conf.get(CONF_MODE, '')) + msg) @contextmanager def cd(path): oldpwd = os.getcwd() os.chdir(path) try: yield finally: os.chdir(oldpwd) def exist_in_path(prog): '''Test whether prog exists in system path''' return bool(find_in_path(prog)) def prepend_env_value(name, value, seperator=':'): '''append a new value to a list''' try: current_value = os.environ[name] except KeyError: current_value = '' new_value = value if current_value: new_value += seperator + current_value os.environ[name] = new_value def find_in_path(prog): '''Find a file in system path''' dirs = os.environ['PATH'].split(':') for d in dirs: if d == '': continue path = join(d, prog) if exists(path): return path return None def error(msg=None, usage=None): if msg: print highlight('[ERROR] ') + msg if usage: print usage sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' info('running %s, cwd=%s' % (' '.join(['"{}"'.format(a) for a in argv]), cwd or os.getcwd())) with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Like run_argv but specify a command line string instead of argv''' info('running %s, cwd=%s' % (cmdline, cwd or os.getcwd())) with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) return proc.wait() def must_run(cmdline, *a, **kw): ret = run(cmdline, *a, **kw) if ret != 0: error('failed to run %s' % cmdline) def check_remove(path): """ Remove the file/dir specified by `path`, if exists. """ path = abspath(path) assert path.count('/') >= 2 if exists(path): is_dir = os.path.isdir(path) info('removing {} {}'.format('dir' if is_dir else 'file', path)) if is_dir: shutil.rmtree(path) else: os.unlink(path) def must_mkdir(path): '''Create a directory, exit on failure''' try: if not exists(path): os.mkdir(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) def must_copytree(src, dst): '''Copy src tree to dst, exit on failure''' try: shutil.copytree(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) class Project(object): '''Base class for a project''' # Probject name, i.e. libseaprc/ccnet/seafile/ name = '' # A list of shell commands to configure/build the project build_commands = [] def __init__(self): # the path to pass to --prefix=/ self.prefix = join(conf[CONF_BUILDDIR], 'usr') self.version = self.get_version() self.src_tarball = join(conf[CONF_SRCDIR], '%s-%s.tar.gz' % (self.name, self.version)) # project dir, like /seafile-1.2.2/ self.projdir = join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) def get_version(self): # libsearpc and ccnet can have different versions from seafile. raise NotImplementedError def get_source_commit_id(self): '''By convetion, we record the commit id of the source code in the file "/latest_commit" ''' latest_commit_file = join(self.projdir, 'latest_commit') with open(latest_commit_file, 'r') as fp: commit_id = fp.read().strip('\n\r\t ') return commit_id def append_cflags(self, macros): cflags = ' '.join(['-D%s=%s' % (k, macros[k]) for k in macros]) prepend_env_value('CPPFLAGS', cflags, seperator=' ') def uncompress(self): '''Uncompress the source from the tarball''' info('Uncompressing %s' % self.name) if run('tar xf %s' % self.src_tarball) < 0: error('failed to uncompress source of %s' % self.name) def before_build(self): '''Hook method to do project-specific stuff before running build commands''' pass def build(self): '''Build the source''' self.before_build() info('Building %s' % self.name) for cmd in self.build_commands: if run(cmd, cwd=self.projdir) != 0: error('error when running command:\n\t%s\n' % cmd) def concurrent_make(): return 'make -j%s' % NUM_CPU class Libsearpc(Project): name = 'libsearpc' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-compile-demo' % self.prefix, concurrent_make(), 'make install' ] def get_version(self): return conf[CONF_LIBSEARPC_VERSION] class Ccnet(Project): name = 'ccnet' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-compile-demo' % self.prefix, concurrent_make(), 'make install' ] def get_version(self): return conf[CONF_CCNET_VERSION] def before_build(self): macros = {} # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class Seafile(Project): name = 'seafile' def __init__(self): Project.__init__(self) self.build_commands = [ './configure --prefix=%s --disable-fuse' % self.prefix, concurrent_make(), 'make install' ] def get_version(self): return conf[CONF_SEAFILE_VERSION] def update_cli_version(self): '''Substitute the version number in seaf-cli''' cli_py = join(self.projdir, 'app', 'seaf-cli') with open(cli_py, 'r') as fp: lines = fp.readlines() ret = [] for line in lines: old = '''SEAF_CLI_VERSION = ""''' new = '''SEAF_CLI_VERSION = "%s"''' % conf[CONF_VERSION] line = line.replace(old, new) ret.append(line) with open(cli_py, 'w') as fp: fp.writelines(ret) def before_build(self): self.update_cli_version() macros = {} # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class SeafileClient(Project): name = 'seafile-client' def __init__(self): Project.__init__(self) cmake_defines = { 'CMAKE_OSX_ARCHITECTURES': 'x86_64', 'CMAKE_OSX_DEPLOYMENT_TARGET': '10.7', 'CMAKE_BUILD_TYPE': 'Release', 'BUILD_SHIBBOLETH_SUPPORT': 'ON', 'BUILD_SPARKLE_SUPPORT': 'ON', } cmake_defines_formatted = ' '.join(['-D{}={}'.format(k, v) for k, v in cmake_defines.iteritems()]) self.build_commands = [ 'rm -f CMakeCache.txt', 'cmake -G Xcode {}'.format(cmake_defines_formatted), 'xcodebuild -target seafile-applet -configuration Release -jobs {}'.format(NUM_CPU), 'rm -rf seafile-applet.app', 'cp -r Release/seafile-applet.app seafile-applet.app', 'mkdir -p seafile-applet.app/Contents/Frameworks', 'macdeployqt seafile-applet.app', ] def get_version(self): return conf[CONF_SEAFILE_CLIENT_VERSION] def before_build(self): pass class SeafileDMGLayout(Seafile): def __init__(self): Seafile.__init__(self) self.build_commands = [ ] class SeafileFinderSyncPlugin(SeafileClient): def __init__(self): SeafileClient.__init__(self) self.build_commands = [ 'fsplugin/build.sh' ] def check_targz_src(proj, version, srcdir): src_tarball = join(srcdir, '%s-%s.tar.gz' % (proj, version)) if not exists(src_tarball): error('%s not exists' % src_tarball) def validate_args(usage, options): required_args = [ CONF_VERSION, CONF_LIBSEARPC_VERSION, CONF_CCNET_VERSION, CONF_SEAFILE_VERSION, CONF_SEAFILE_CLIENT_VERSION, CONF_SRCDIR, ] # fist check required args for optname in required_args: if getattr(options, optname, None) is None: error('%s must be specified' % optname, usage=usage) def get_option(optname): return getattr(options, optname) # [ version ] def check_project_version(version): '''A valid version must be like 1.2.2, 1.3''' if not re.match(r'^[0-9](\.[0-9])+$', version): error('%s is not a valid version' % version, usage=usage) mode = get_option(CONF_MODE).lower() assert mode in ('master', 'slave') version = get_option(CONF_VERSION) seafile_version = get_option(CONF_SEAFILE_VERSION) seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) ccnet_version = get_option(CONF_CCNET_VERSION) check_project_version(version) check_project_version(libsearpc_version) check_project_version(ccnet_version) check_project_version(seafile_version) check_project_version(seafile_client_version) # [ srcdir ] srcdir = get_option(CONF_SRCDIR) check_targz_src('libsearpc', libsearpc_version, srcdir) check_targz_src('ccnet', ccnet_version, srcdir) check_targz_src('seafile', seafile_version, srcdir) # [ keep ] keep = get_option(CONF_KEEP) # [ local ] build_local = get_option(CONF_LOCAL) # [ builddir ] builddir = get_option(CONF_BUILDDIR) if not exists(builddir): error('%s does not exist' % builddir, usage=usage) # TODO: remove this # if mode == 'master': # builddir = expanduser('~/tmp') # if not exists(builddir): # must_mkdir(builddir) builddir = join(builddir, 'seafile-mac-build') if not keep: check_remove(builddir) must_mkdir(builddir) # [ outputdir ] outputdir = get_option(CONF_OUTPUTDIR) if outputdir: if not exists(outputdir): error('outputdir %s does not exist' % outputdir, usage=usage) else: outputdir = os.getcwd() # [ no strip] nostrip = get_option(CONF_NO_STRIP) slave_host = get_option(CONF_SLAVE_HOST) brand = get_option(CONF_BRAND) conf[CONF_MODE] = mode conf[CONF_LOCAL] = build_local conf[CONF_VERSION] = version conf[CONF_LIBSEARPC_VERSION] = libsearpc_version conf[CONF_SEAFILE_VERSION] = seafile_version conf[CONF_CCNET_VERSION] = ccnet_version conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version conf[CONF_BUILDDIR] = builddir conf[CONF_SRCDIR] = srcdir conf[CONF_OUTPUTDIR] = outputdir conf[CONF_KEEP] = keep conf[CONF_NO_STRIP] = nostrip conf[CONF_SLAVE_HOST] = slave_host conf[CONF_BRAND] = brand # TODO: remove this # conf[CONF_SLAVE_HOST] = 'lion' # conf[CONF_SLAVE_HOST] = 'sierra' prepare_builddir(builddir) # show_build_info() def show_build_info(): '''Print all conf information. Confirm before continue.''' info('------------------------------------------') info('Seafile command line client %s: BUILD INFO' % conf[CONF_VERSION]) info('------------------------------------------') info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) info('ccnet: %s' % conf[CONF_CCNET_VERSION]) info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) info('builddir: %s' % conf[CONF_BUILDDIR]) info('outputdir: %s' % conf[CONF_OUTPUTDIR]) info('source dir: %s' % conf[CONF_SRCDIR]) info('strip symbols: %s' % (not conf[CONF_NO_STRIP])) info('clean on exit: %s' % (not conf[CONF_KEEP])) info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') dummy = raw_input() def prepare_builddir(builddir): must_mkdir(builddir) # if not conf[CONF_KEEP]: # def remove_builddir(): # '''Remove the builddir when exit''' # info('remove builddir before exit') # shutil.rmtree(builddir, ignore_errors=True) # atexit.register(remove_builddir) os.chdir(builddir) must_mkdir(join(builddir, 'usr')) def parse_args(): parser = optparse.OptionParser() def long_opt(opt): return '--' + opt parser.add_option(long_opt(CONF_MODE), dest=CONF_MODE, default='master', help='''The mode: master or slave. Master is osx 10.12, while slave is used when running on osx 10.7 lion. Master would ssh on to slave to compile the source code.''') parser.add_option(long_opt(CONF_VERSION), dest=CONF_VERSION, nargs=1, help='the version to build. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_VERSION), dest=CONF_SEAFILE_VERSION, nargs=1, help='the version of seafile as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), dest=CONF_LIBSEARPC_VERSION, nargs=1, help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_CCNET_VERSION), dest=CONF_CCNET_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), dest=CONF_SEAFILE_CLIENT_VERSION, nargs=1, help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_BUILDDIR), dest=CONF_BUILDDIR, nargs=1, help='the directory to build the source. Defaults to /tmp', default=tempfile.gettempdir()) parser.add_option(long_opt(CONF_OUTPUTDIR), dest=CONF_OUTPUTDIR, nargs=1, help='the output directory to put the generated tarball. Defaults to the current directory.', default=os.getcwd()) parser.add_option(long_opt(CONF_SRCDIR), dest=CONF_SRCDIR, nargs=1, help='''Source tarballs must be placed in this directory.''') parser.add_option(long_opt(CONF_KEEP), dest=CONF_KEEP, action='store_true', help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') parser.add_option(long_opt(CONF_NO_STRIP), dest=CONF_NO_STRIP, action='store_true', help='''do not strip debug symbols''') parser.add_option(long_opt(CONF_SLAVE_HOST), dest=CONF_SLAVE_HOST, default='lion', help='the hostname of the lower version osx slave') parser.add_option(long_opt(CONF_BRAND), dest=CONF_BRAND, help='the brand') parser.add_option(long_opt(CONF_LOCAL), dest=CONF_LOCAL, action='store_true', help='build locally instead of using an old 10.7 vm') usage = parser.format_help() options, remain = parser.parse_args() if remain: error(usage=usage) validate_args(usage, options) def setup_build_env(): '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' # os.environ.update({ # }) prefix = join(conf[CONF_BUILDDIR], 'usr') prepend_env_value('CFLAGS', '-Wall -O2 -g -DNDEBUG -I/opt/local/include -mmacosx-version-min=10.7', seperator=' ') prepend_env_value('CXXFLAGS', '-Wall -O2 -g -DNDEBUG -I/opt/local/include -mmacosx-version-min=10.7', seperator=' ') prepend_env_value('CPPFLAGS', '-I%s' % join(prefix, 'include'), seperator=' ') prepend_env_value('CPPFLAGS', '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], seperator=' ') if conf[CONF_NO_STRIP]: prepend_env_value('CPPFLAGS', '-g -O0', seperator=' ') prepend_env_value('LDFLAGS', '-L%s' % join(prefix, 'lib'), seperator=' ') prepend_env_value('LDFLAGS', '-L%s' % join(prefix, 'lib64'), seperator=' ') prepend_env_value('LDFLAGS', '-L/opt/local/lib -Wl,-headerpad_max_install_names -mmacosx-version-min=10.7', seperator=' ') prepend_env_value('PATH', join(prefix, 'bin')) prepend_env_value('PKG_CONFIG_PATH', join(prefix, 'lib', 'pkgconfig')) prepend_env_value('PKG_CONFIG_PATH', join(prefix, 'lib64', 'pkgconfig')) path_pattern = re.compile(r'^\s+(\S+)\s+\(compatibility.*') def get_dependent_libs(executable): def is_syslib(lib): if lib.startswith('/usr/lib'): return True if lib.startswith('/System/'): return True return False otool_output = commands.getoutput('otool -L %s' % executable) libs = set() for line in otool_output.splitlines(): m = path_pattern.match(line) if not m: continue path = m.group(1) if not is_syslib(path): libs.add(path) return libs def copy_shared_libs(): '''copy shared c libs, such as libevent, glib''' builddir = conf[CONF_BUILDDIR] frameworks_dir = join(SeafileClient().projdir, 'seafile-applet.app/Contents/Frameworks') must_mkdir(frameworks_dir) seafile_path = join(builddir, 'usr/bin/seaf-daemon') ccnet_path = join(builddir, 'usr/bin/ccnet') libs = set() libs.update(get_dependent_libs(ccnet_path)) libs.update(get_dependent_libs(seafile_path)) for lib in libs: dst_file = join(frameworks_dir, basename(lib)) if exists(dst_file): continue info('Copying %s' % lib) shutil.copy(lib, frameworks_dir) change_rpaths() def change_rpaths(): """ Chagne the rpath of the referenced dylibs so the app can be relocated anywhere in the user's system. See: - https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac - https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html """ contents_dir = join(SeafileClient().projdir, 'seafile-applet.app/Contents') frameworks_dir = join(contents_dir, 'Frameworks') resources_dir = join(contents_dir, 'Resources') macos_dir = join(contents_dir, 'MacOS') seafile_applet = join(macos_dir, 'seafile-applet') binaries = [ seafile_applet, join(resources_dir, 'ccnet'), join(resources_dir, 'seaf-daemon') ] RPATH_RE = re.compile(r'^path\s+(\S+)\s+\(offset .*$') def get_rpaths(fn): rpaths = [] output = commands.getoutput('otool -l {} | grep -A2 RPATH || true'.format(fn)) # The output is like # cmd LC_RPATH # cmdsize 24 # path /usr/local (offset 12) # -- # cmd LC_RPATH # cmdsize 48 # path @executable_path/../Frameworks (offset 12) for line in output.splitlines(): m = RPATH_RE.match(line.strip()) if m: rpaths.append(m.group(1)) return rpaths def has_rpath(fn, path): return path in get_rpaths(fn) def add_frameworks_dir_to_rpath(fn, executable=True): relpath = 'executable_path' if executable else 'loader_path' relative_frameworks_dir = '@{}/../Frameworks'.format(relpath) if not has_rpath(fn, relative_frameworks_dir): must_run('install_name_tool -add_rpath {} {}' .format(relative_frameworks_dir, fn)) def remove_local_rpaths(fn): local_paths = ['/usr/local/lib', '/opt/local/lib'] for path in local_paths: if has_rpath(fn, path): must_run('install_name_tool -delete_rpath {} {}'.format(path, fn)) def change_deps_rpath(fn): deps = get_dependent_libs(fn) for dep in deps: bn = basename(dep) if 'framework' in bn or bn.startswith('Qt') or bn == 'Sparkle': continue must_run('install_name_tool -change {} @rpath/{} {}'.format(dep, basename(dep), fn)) for binary in binaries: add_frameworks_dir_to_rpath(binary) remove_local_rpaths(binary) change_deps_rpath(binary) libs = os.listdir(frameworks_dir) for lib_name in libs: lib = join(frameworks_dir, lib_name) if os.path.isdir(lib): continue must_run('install_name_tool -id @rpath/{} {}'.format(basename(lib), lib)) add_frameworks_dir_to_rpath(lib, executable=False) change_deps_rpath(lib) remove_local_rpaths(lib) DROPDMG = '/Applications/DropDMG.app/Contents/Frameworks/DropDMGFramework.framework/Versions/A/dropdmg' def gen_dmg(): output_dmg = 'app-{}.dmg'.format(conf[CONF_VERSION]) parentdir = 'app-{}'.format(conf[CONF_VERSION]) appdir = join(parentdir, 'seafile-applet.app') app_plugins_dir = join(appdir, 'Contents/PlugIns') layout = SeafileDMGLayout() layout.uncompress() layout_folder = join(layout.projdir, 'dmg/seafileLayout') args = [ DROPDMG, parentdir, '--format', 'bzip2', '--layout-folder', layout_folder, '--volume-name', conf[CONF_BRAND] or 'Seafile Client', ] with cd(conf[CONF_BUILDDIR]): check_remove(parentdir) check_remove(output_dmg) must_mkdir(parentdir) must_run('tar xf seafile-applet.app.tar.gz -C {}'.format(parentdir)) # Remove the Qt Bearer plugin because it would run a background thread # to scan wifi networks. See # https://trello.com/c/j28eOIo1/359-explicitly-exclude-qt-bearer-plugins-for-the-windows-and-mac-packages # for details. must_run('rm -rf "{}"'.format(join(app_plugins_dir, 'bearer'))) # fsplugin must be copied before we sign the final .app dir copy_fsplugin(app_plugins_dir) sign_files(appdir) # Rename the .app dir to 'Seafile Client.app', and create the shortcut # to '/Applications' so the user can drag into it when opening the DMG. brand = conf.get(CONF_BRAND, '') if brand: final_app = '{}.app'.format(brand) else: final_app = FINAL_APP must_run('mv {}/seafile-applet.app "{}/{}"'.format(parentdir, parentdir, final_app)) must_run('ln -sf /Applications {}/'.format(parentdir)) # Open DropDMG manually, or dropdmg command line may fail. run(''' osascript -e 'tell application "DropDMG" to quit' || true ''') run(''' osascript -e 'open application "DropDMG"' || true ''') run(''' osascript -e 'activate application "DropDMG"' || true ''') # Sometimes DropDmg would fail if there are two many Finder windows. run(''' osascript -e 'tell application "Finder" to close every window' ''') if run_argv(args) != 0: error('failed to run {}'.format(args)) def sign_in_parallel(files_to_sign): import threading import Queue queue = Queue.Queue() POISON_PILL = '' class SignThread(threading.Thread): def __init__(self, index): threading.Thread.__init__(self) self.index = index def run(self): info('sign thread {} started'.format(self.index)) while True: try: fn = queue.get(timeout=1) except Queue.Empty: continue else: if fn == POISON_PILL: break else: do_sign(fn) info('sign thread {} stopped'.format(self.index)) TOTAL_THREADS = max(NUM_CPU / 2, 1) threads = [] for i in xrange(TOTAL_THREADS): t = SignThread(i) t.start() threads.append(t) for fn in files_to_sign: queue.put(fn) for _ in xrange(TOTAL_THREADS): queue.put(POISON_PILL) for i in xrange(TOTAL_THREADS): threads[i].join() def sign_files(appdir): webengine_app = join( appdir, 'Contents/Frameworks/QtWebEngineCore.framework/Versions/5/Helpers/QtWebEngineProcess.app' ) # The webengine app must be signed first, otherwise the sign of # QtWebengineCore.framework would fail. if exists(webengine_app): do_sign(webengine_app) patterns = [ 'Contents/Frameworks/*.framework', 'Contents/PlugIns/*/*.dylib', 'Contents/Frameworks/*.dylib', 'Contents/Resources/ccnet', 'Contents/Resources/seaf-daemon', ] files_to_sign = [] for p in patterns: files_to_sign.extend(glob.glob(join(appdir, p))) info('{} files to sign'.format(len(files_to_sign))) sign_in_parallel(files_to_sign) # for fn in files_to_sign: # do_sign(fn) do_sign(appdir) # do_sign(appdir, extra_args=['--deep']) _keychain_unlocked = False def unlock_keychain(): """ Unlock the keychain when we're using ssh instead of using the terminal from GUI. See http://stackoverflow.com/a/20208104/1467959 """ global _keychain_unlocked if not _keychain_unlocked: _keychain_unlocked = True run('security -v unlock-keychain -p vagrant || true') def do_sign(path, extra_args=None): unlock_keychain() args = [ 'codesign', '--verbose=4', '--verify', # '--no-strict', '--force', '--preserve-metadata=entitlements', '-s', CERT_ID, ] extra_args = extra_args or [] if extra_args: args.extend(extra_args) args.append(path) if run_argv(args) != 0: error('failed to sign {}'.format(path)) def send_file_to_slave(src, dst): info('putting file {} => {}'.format(src, dst)) with settings(host_string=conf[CONF_SLAVE_HOST]): put_file(local_path=src, remote_path=dst) def get_file_from_slave(src, dst): host = conf[CONF_SLAVE_HOST] info('getting file {}:{} => {}'.format(host, src, dst)) with settings(host_string=host): get_file(src, dst) def send_project_tarball(project): info('sending tarball of {}'.format(project.name)) src = project.src_tarball dst = join(SLAVE_SRCDIR, basename(src)) send_file_to_slave(src, dst) def slave_run(cmd, **kw): info('running cmd: ' + cmd) kw['host'] = conf[CONF_SLAVE_HOST] cmd = '. ~/.bash_profile; export SEAFILE_BUILD_SLAVE=1; ' + cmd execute(fabric_run, cmd, **kw) def prepare_dirs_on_slave(): info('creating work directory on the slave') slave_run('mkdir -p {}'.format(SLAVE_SRCDIR)) slave_run('mkdir -p {}'.format(SLAVE_BUILDDIR)) def send_sources_to_slave(): info('sending sources to the slave') prepare_dirs_on_slave() send_file_to_slave(abspath(__file__), SLAVE_BUILD_SCRIPT) projects = [ Libsearpc(), Ccnet(), Seafile(), SeafileClient(), ] for p in projects: send_project_tarball(p) def build_on_slave(): args = [ 'python', SLAVE_BUILD_SCRIPT, '--mode=slave', '--version={}'.format(conf[CONF_VERSION]), '--libsearpc_version={}'.format(conf[CONF_LIBSEARPC_VERSION]), '--ccnet_version={}'.format(conf[CONF_CCNET_VERSION]), '--seafile_version={}'.format(conf[CONF_SEAFILE_VERSION]), '--seafile_client_version={}'.format(conf[CONF_SEAFILE_CLIENT_VERSION]), '--srcdir={}'.format(SLAVE_SRCDIR), '--builddir={}' .format(SLAVE_BUILDDIR), ] info('packaging on the slave') slave_run(' '.join(args)) def get_app_tgz_from_slave(): fn = 'seafile-applet.app.tar.gz' src = join(SLAVE_BUILDDIR, 'seafile-mac-build', fn) dst = join(conf[CONF_BUILDDIR], fn) get_file_from_slave(src, dst) def copy_dmg(): brand = conf[CONF_BRAND] or 'seafile-client' branded_dmg = '{}-{}.dmg'.format(brand, conf[CONF_VERSION]) src_dmg = os.path.join(conf[CONF_BUILDDIR], 'app-{}.dmg'.format(conf[CONF_VERSION])) dst_dmg = os.path.join(conf[CONF_OUTPUTDIR], branded_dmg) # move msi to outputdir must_copy(src_dmg, dst_dmg) print '---------------------------------------------' print 'The build is successfully. Output is:' print '>>\t%s' % dst_dmg print '---------------------------------------------' def build_and_sign_fsplugin(): """ Build and sign the fsplugin. The final output would be "${buildder}/Seafile FinderSync.appex" """ fsplugin = SeafileFinderSyncPlugin() fsplugin.uncompress() fsplugin.build() with cd(fsplugin.projdir): appex_src = 'fsplugin/{}'.format(FSPLUGIN_APPEX_NAME) appex_dst = join(conf[CONF_BUILDDIR], basename(appex_src)) check_remove(appex_dst) must_copytree(appex_src, appex_dst) entitlements_src = 'fsplugin/seafile-fsplugin.entitlements' entitlements_dst = join(conf[CONF_BUILDDIR], basename(entitlements_src)) check_remove(entitlements_dst) must_copy(entitlements_src, entitlements_dst) do_sign( appex_dst, extra_args=['--entitlements', entitlements_dst] ) def copy_fsplugin(plugins_dir): src = join(conf[CONF_BUILDDIR], FSPLUGIN_APPEX_NAME) dst = join(plugins_dir, FSPLUGIN_APPEX_NAME) check_remove(dst) must_copytree(src, dst) def copy_sparkle_framework(): src = '/usr/local/Sparkle.framework' dst = join(SeafileClient().projdir, 'seafile-applet.app/Contents/Frameworks', basename(src)) check_remove(dst) # Here we use the `cp` command instead of shutil to do the copy, because `cp # -P` would keep symlinks as is. must_run('cp -R -P "{}" "{}"'.format(src, dst)) def build_projects(): libsearpc = Libsearpc() ccnet = Ccnet() seafile = Seafile() seafile_client = SeafileClient() libsearpc.uncompress() libsearpc.build() ccnet.uncompress() ccnet.build() seafile.uncompress() seafile.build() seafile_client.uncompress() seafile_client.build() copy_sparkle_framework() copy_shared_libs() def local_workflow(): build_projects() generate_app_tar_gz() build_and_sign_fsplugin() gen_dmg() copy_dmg() def master_workflow(): send_sources_to_slave() build_on_slave() get_app_tgz_from_slave() build_and_sign_fsplugin() gen_dmg() copy_dmg() def slave_workflow(): build_projects() generate_app_tar_gz() def generate_app_tar_gz(): # output_app_tgz = join(conf[CONF_BUILDDIR], '..', 'seafile-applet.app.tar.gz') output_app_tgz = join(conf[CONF_BUILDDIR], 'seafile-applet.app.tar.gz') with cd(SeafileClient().projdir): run('tar czf {} seafile-applet.app'.format(output_app_tgz)) def setup_logging(level=logging.INFO): kw = { 'format': '[%(asctime)s][%(module)s]: %(message)s', 'datefmt': '%m/%d/%Y %H:%M:%S', 'level': level, 'stream': sys.stdout } logging.basicConfig(**kw) logging.getLogger('requests.packages.urllib3.connectionpool').setLevel( logging.WARNING) def main(): setup_logging() parse_args() info('{} script started'.format(abspath(__file__))) info('NUM_CPU = {}'.format(NUM_CPU)) setup_build_env() if conf[CONF_LOCAL]: local_workflow() elif conf[CONF_MODE] == 'master': info('entering master workflow') master_workflow() else: info('entering slave workflow') slave_workflow() if __name__ == '__main__': main() seafile-6.1.5/scripts/build/build-msi.py000077500000000000000000001007651323477647300202140ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This scirpt builds the seafile windows msi installer. Some notes: 1. The working directory is always the 'builddir'. 'os.chdir' is only called to change to the 'builddir'. We make use of the 'cwd' argument in 'subprocess.Popen' to run a command in a specific directory. 2. When invoking commands like 'tar', we must convert the path to posix path with the function to_mingw_path. E.g., 'c:\\seafile' should be converted to '/c/seafile'. ''' import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) import multiprocessing import os import glob import shutil import re import subprocess import optparse import atexit import csv error_exit = False #################### ### Global variables #################### # command line configuartion conf = {} # key names in the conf dictionary. CONF_VERSION = 'version' CONF_LIBSEARPC_VERSION = 'libsearpc_version' CONF_CCNET_VERSION = 'ccnet_version' CONF_SEAFILE_VERSION = 'seafile_version' CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' CONF_SRCDIR = 'srcdir' CONF_KEEP = 'keep' CONF_BUILDDIR = 'builddir' CONF_OUTPUTDIR = 'outputdir' CONF_DEBUG = 'debug' CONF_ONLY_CHINESE = 'onlychinese' CONF_QT_ROOT = 'qt_root' CONF_EXTRA_LIBS_DIR = 'extra_libs_dir' CONF_QT5 = 'qt5' CONF_BRAND = 'brand' CONF_CERTFILE = 'certfile' CONF_NO_STRIP = 'nostrip' #################### ### Common helper functions #################### def to_mingw_path(path): if len(path) < 2 or path[1] != ':' : return path.replace('\\', '/') drive = path[0] return '/%s%s' % (drive.lower(), path[2:].replace('\\', '/')) def to_win_path(path): if len(path) < 2 or path[1] == ':' : return path.replace('/', '\\') drive = path[1] return '%s:%s' % (drive.lower(), path[2:].replace('/', '\\')) def highlight(content, is_error=False): '''Add ANSI color to content to get it highlighted on terminal''' dummy = is_error return content # if is_error: # return '\x1b[1;31m%s\x1b[m' % content # else: # return '\x1b[1;32m%s\x1b[m' % content def info(msg): print highlight('[INFO] ') + msg def find_in_path(prog): '''Test whether prog exists in system path''' dirs = os.environ['PATH'].split(';') for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return path return None def prepend_env_value(name, value, seperator=':'): '''prepend a new value to a list''' try: current_value = os.environ[name] except KeyError: current_value = '' new_value = value if current_value: new_value += seperator + current_value os.environ[name] = new_value def error(msg=None, usage=None): if msg: print highlight('[ERROR] ') + msg if usage: print usage sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Like run_argv but specify a command line string instead of argv''' info('running %s, cwd=%s' % (cmdline, cwd if cwd else os.getcwd())) with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) ret = proc.wait() if 'depend' not in cmdline and ret != 0: global error_exit error_exit = True return ret def must_mkdir(path): '''Create a directory, exit on failure''' try: os.makedirs(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) def must_copytree(src, dst): '''Copy dir src to dst, exit on failure''' try: shutil.copytree(src, dst) except Exception, e: error('failed to copy dir %s to %s: %s' % (src, dst, e)) def must_move(src, dst): '''Move src to dst, exit on failure''' try: shutil.move(src, dst) except Exception, e: error('failed to move %s to %s: %s' % (src, dst, e)) class Project(object): '''Base class for a project''' # Probject name, i.e. libseaprc/ccnet/seafile/seahub name = '' # A list of shell commands to configure/build the project build_commands = [] def __init__(self): self.prefix = os.path.join(conf[CONF_BUILDDIR], 'usr') self.version = self.get_version() self.src_tarball = os.path.join(conf[CONF_SRCDIR], '%s-%s.tar.gz' % (self.name, self.version)) # project dir, like /seafile-1.2.2/ self.projdir = os.path.join(conf[CONF_BUILDDIR], '%s-%s' % (self.name, self.version)) def get_version(self): # libsearpc and ccnet can have different versions from seafile. raise NotImplementedError def get_source_commit_id(self): '''By convetion, we record the commit id of the source code in the file "/latest_commit" ''' latest_commit_file = os.path.join(self.projdir, 'latest_commit') with open(latest_commit_file, 'r') as fp: commit_id = fp.read().strip('\n\r\t ') return commit_id def append_cflags(self, macros): cflags = ' '.join([ '-D%s=%s' % (k, macros[k]) for k in macros ]) prepend_env_value('CPPFLAGS', cflags, seperator=' ') def uncompress(self): '''Uncompress the source from the tarball''' info('Uncompressing %s' % self.name) tarball = to_mingw_path(self.src_tarball) if run('tar xf %s' % tarball) != 0: error('failed to uncompress source of %s' % self.name) def before_build(self): '''Hook method to do project-specific stuff before running build commands''' pass def build(self): '''Build the source''' self.before_build() info('Building %s' % self.name) dump_env() for cmd in self.build_commands: if run(cmd, cwd=self.projdir) != 0: error('error when running command:\n\t%s\n' % cmd) def get_make_path(): return find_in_path('make.exe') def concurrent_make(): return '%s -j%s' % (get_make_path(), multiprocessing.cpu_count()) class Libsearpc(Project): name = 'libsearpc' def __init__(self): Project.__init__(self) self.build_commands = [ 'sh ./configure --prefix=%s --disable-compile-demo' % to_mingw_path(self.prefix), concurrent_make(), '%s install' % get_make_path(), ] def get_version(self): return conf[CONF_LIBSEARPC_VERSION] class Ccnet(Project): name = 'ccnet' def __init__(self): Project.__init__(self) self.build_commands = [ 'sh ./configure --prefix=%s --disable-compile-demo' % to_mingw_path(self.prefix), concurrent_make(), '%s install' % get_make_path(), ] def get_version(self): return conf[CONF_CCNET_VERSION] def before_build(self): macros = {} # SET CCNET_SOURCE_COMMIT_ID, so it can be printed in the log macros['CCNET_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class Seafile(Project): name = 'seafile' def __init__(self): Project.__init__(self) enable_breakpad = '--enable-breakpad' self.build_commands = [ 'sh ./configure %s --prefix=%s' % (enable_breakpad, to_mingw_path(self.prefix)), concurrent_make(), '%s install' % get_make_path(), ] def get_version(self): return conf[CONF_SEAFILE_VERSION] def before_build(self): macros = {} # SET SEAFILE_SOURCE_COMMIT_ID, so it can be printed in the log macros['SEAFILE_SOURCE_COMMIT_ID'] = '\\"%s\\"' % self.get_source_commit_id() self.append_cflags(macros) class SeafileClient(Project): name = 'seafile-client' def __init__(self): Project.__init__(self) ninja = find_in_path('ninja.exe') seafile_prefix = Seafile().prefix generator = 'Ninja' if ninja else 'MSYS Makefiles' build_type = 'Debug' if conf[CONF_DEBUG] else 'Release' flags = { 'BUILD_SPARKLE_SUPPORT': 'ON', 'USE_QT5': 'ON' if conf[CONF_QT5] else 'OFF', 'BUILD_SHIBBOLETH_SUPPORT': 'ON', 'CMAKE_BUILD_TYPE': build_type, 'CMAKE_INSTALL_PREFIX': to_mingw_path(self.prefix), # ninja invokes cmd.exe which doesn't support msys/mingw path # change the value but don't override CMAKE_EXE_LINKER_FLAGS, # which is in use 'CMAKE_EXE_LINKER_FLAGS_%s' % build_type.upper(): '-L%s' % (os.path.join(seafile_prefix, 'lib') if ninja else to_mingw_path(os.path.join(seafile_prefix, 'lib'))), } flags_str = ' '.join(['-D%s=%s' % (k, v) for k, v in flags.iteritems()]) make = ninja or concurrent_make() self.build_commands = [ 'cmake -G "%s" %s .' % (generator, flags_str), make, '%s install' % make, "bash extensions/build.sh", ] def get_version(self): return conf[CONF_SEAFILE_CLIENT_VERSION] def before_build(self): shutil.copy(os.path.join(conf[CONF_EXTRA_LIBS_DIR], 'winsparkle.lib'), self.projdir) def check_targz_src(proj, version, srcdir): src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) if not os.path.exists(src_tarball): error('%s not exists' % src_tarball) def validate_args(usage, options): required_args = [ CONF_VERSION, CONF_LIBSEARPC_VERSION, CONF_CCNET_VERSION, CONF_SEAFILE_VERSION, CONF_SEAFILE_CLIENT_VERSION, CONF_SRCDIR, CONF_QT_ROOT, CONF_EXTRA_LIBS_DIR, ] # fist check required args for optname in required_args: if getattr(options, optname, None) == None: error('%s must be specified' % optname, usage=usage) def get_option(optname): return getattr(options, optname) # [ version ] def check_project_version(version): '''A valid version must be like 1.2.2, 1.3''' if not re.match('^[0-9]+(\.([0-9])+)+$', version): error('%s is not a valid version' % version, usage=usage) version = get_option(CONF_VERSION) libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) ccnet_version = get_option(CONF_CCNET_VERSION) seafile_version = get_option(CONF_SEAFILE_VERSION) seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) check_project_version(version) check_project_version(libsearpc_version) check_project_version(ccnet_version) check_project_version(seafile_version) check_project_version(seafile_client_version) # [ srcdir ] srcdir = to_win_path(get_option(CONF_SRCDIR)) check_targz_src('libsearpc', libsearpc_version, srcdir) check_targz_src('ccnet', ccnet_version, srcdir) check_targz_src('seafile', seafile_version, srcdir) check_targz_src('seafile-client', seafile_client_version, srcdir) # [ builddir ] builddir = to_win_path(get_option(CONF_BUILDDIR)) if not os.path.exists(builddir): error('%s does not exist' % builddir, usage=usage) builddir = os.path.join(builddir, 'seafile-msi-build') # [ outputdir ] outputdir = to_win_path(get_option(CONF_OUTPUTDIR)) if not os.path.exists(outputdir): error('outputdir %s does not exist' % outputdir, usage=usage) # [ keep ] keep = get_option(CONF_KEEP) # [ no strip] debug = get_option(CONF_DEBUG) # [ no strip] nostrip = get_option(CONF_NO_STRIP) # [only chinese] onlychinese = get_option(CONF_ONLY_CHINESE) # [ qt root] qt_root = get_option(CONF_QT_ROOT) def check_qt_root(qt_root): if not os.path.exists(os.path.join(qt_root, 'plugins')): error('%s is not a valid qt root' % qt_root) check_qt_root(qt_root) # [ sparkle dir] extra_libs_dir = get_option(CONF_EXTRA_LIBS_DIR) def check_extra_libs_dir(extra_libs_dir): for fn in ['winsparkle.lib']: if not os.path.exists(os.path.join(extra_libs_dir, fn)): error('%s is missing in %s' % (fn, extra_libs_dir)) check_extra_libs_dir(extra_libs_dir) # [qt5] qt5 = get_option(CONF_QT5) brand = get_option(CONF_BRAND) cert = get_option(CONF_CERTFILE) if cert is not None: if not os.path.exists(cert): error('cert file "{}" does not exist'.format(cert)) conf[CONF_VERSION] = version conf[CONF_LIBSEARPC_VERSION] = libsearpc_version conf[CONF_CCNET_VERSION] = ccnet_version conf[CONF_SEAFILE_VERSION] = seafile_version conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version conf[CONF_BUILDDIR] = builddir conf[CONF_SRCDIR] = srcdir conf[CONF_OUTPUTDIR] = outputdir conf[CONF_KEEP] = True conf[CONF_DEBUG] = debug or nostrip conf[CONF_NO_STRIP] = debug or nostrip conf[CONF_ONLY_CHINESE] = onlychinese conf[CONF_QT_ROOT] = qt_root conf[CONF_EXTRA_LIBS_DIR] = extra_libs_dir conf[CONF_QT5] = qt5 conf[CONF_BRAND] = brand conf[CONF_CERTFILE] = cert prepare_builddir(builddir) show_build_info() def show_build_info(): '''Print all conf information. Confirm before continue.''' info('------------------------------------------') info('Seafile msi installer: BUILD INFO') info('------------------------------------------') info('seafile: %s' % conf[CONF_VERSION]) info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) info('ccnet: %s' % conf[CONF_CCNET_VERSION]) info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) info('qt-root: %s' % conf[CONF_QT_ROOT]) info('builddir: %s' % conf[CONF_BUILDDIR]) info('outputdir: %s' % conf[CONF_OUTPUTDIR]) info('source dir: %s' % conf[CONF_SRCDIR]) info('debug: %s' % conf[CONF_DEBUG]) info('build english version: %s' % (not conf[CONF_ONLY_CHINESE])) info('clean on exit: %s' % (not conf[CONF_KEEP])) info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') dummy = raw_input() def prepare_builddir(builddir): must_mkdir(builddir) if not conf[CONF_KEEP]: def remove_builddir(): '''Remove the builddir when exit''' if not error_exit: info('remove builddir before exit') shutil.rmtree(builddir, ignore_errors=True) atexit.register(remove_builddir) os.chdir(builddir) def parse_args(): parser = optparse.OptionParser() def long_opt(opt): return '--' + opt parser.add_option(long_opt(CONF_VERSION), dest=CONF_VERSION, nargs=1, help='the version to build. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), dest=CONF_LIBSEARPC_VERSION, nargs=1, help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_CCNET_VERSION), dest=CONF_CCNET_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_VERSION), dest=CONF_SEAFILE_VERSION, nargs=1, help='the version of seafile as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), dest=CONF_SEAFILE_CLIENT_VERSION, nargs=1, help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_BUILDDIR), dest=CONF_BUILDDIR, nargs=1, help='the directory to build the source. Defaults to /c', default='c:\\') parser.add_option(long_opt(CONF_OUTPUTDIR), dest=CONF_OUTPUTDIR, nargs=1, help='the output directory to put the generated server tarball. Defaults to the current directory.', default=os.getcwd()) parser.add_option(long_opt(CONF_SRCDIR), dest=CONF_SRCDIR, nargs=1, help='''Source tarballs must be placed in this directory.''') parser.add_option(long_opt(CONF_QT_ROOT), dest=CONF_QT_ROOT, nargs=1, help='''qt root directory.''') parser.add_option(long_opt(CONF_EXTRA_LIBS_DIR), dest=CONF_EXTRA_LIBS_DIR, nargs=1, help='''where we can find winsparkle.lib''') parser.add_option(long_opt(CONF_KEEP), dest=CONF_KEEP, action='store_true', help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') parser.add_option(long_opt(CONF_DEBUG), dest=CONF_DEBUG, action='store_true', help='''compile in debug mode''') parser.add_option(long_opt(CONF_ONLY_CHINESE), dest=CONF_ONLY_CHINESE, action='store_true', help='''only build the Chinese version. By default both Chinese and English versions would be built.''') parser.add_option(long_opt(CONF_QT5), dest=CONF_QT5, action='store_true', help='''build seafile client with qt5''') parser.add_option(long_opt(CONF_BRAND), dest=CONF_BRAND, default='seafile', help='''brand name of the package''') parser.add_option(long_opt(CONF_CERTFILE), nargs=1, default=None, dest=CONF_CERTFILE, help='''The cert for signing the executables and the installer.''') parser.add_option(long_opt(CONF_NO_STRIP), dest=CONF_NO_STRIP, action='store_true', help='''do not strip the symbols.''') usage = parser.format_help() options, remain = parser.parse_args() if remain: error(usage=usage) validate_args(usage, options) def setup_build_env(): '''Setup environment variables, such as export PATH=$BUILDDDIR/bin:$PATH''' prefix = Seafile().prefix prepend_env_value('CPPFLAGS', '-I%s' % to_mingw_path(os.path.join(prefix, 'include')), seperator=' ') prepend_env_value('CPPFLAGS', '-DSEAFILE_CLIENT_VERSION=\\"%s\\"' % conf[CONF_VERSION], seperator=' ') prepend_env_value('CPPFLAGS', '-g -fno-omit-frame-pointer', seperator=' ') if conf[CONF_DEBUG]: prepend_env_value('CPPFLAGS', '-O0', seperator=' ') prepend_env_value('LDFLAGS', '-L%s' % to_mingw_path(os.path.join(prefix, 'lib')), seperator=' ') prepend_env_value('PATH', os.path.join(prefix, 'bin'), seperator=';') prepend_env_value('PKG_CONFIG_PATH', os.path.join(prefix, 'lib', 'pkgconfig'), seperator=';') # to_mingw_path(os.path.join(prefix, 'lib', 'pkgconfig'))) # specifiy the directory for wix temporary files wix_temp_dir = os.path.join(conf[CONF_BUILDDIR], 'wix-temp') os.environ['WIX_TEMP'] = wix_temp_dir must_mkdir(wix_temp_dir) def dependency_walk(applet): output = os.path.join(conf[CONF_BUILDDIR], 'depends.csv') cmd = 'depends.exe -c -f 1 -oc %s %s' % (output, applet) # See the manual of Dependency walker if run(cmd) > 0x100: error('failed to run dependency walker for %s' % applet) if not os.path.exists(output): error('failed to run dependency walker for %s' % applet) shared_libs = parse_depends_csv(output) return shared_libs def parse_depends_csv(path): '''parse the output of dependency walker''' libs = set() our_libs = ['libsearpc', 'libccnet', 'libseafile'] def should_ignore_lib(lib): lib = lib.lower() if not os.path.exists(lib): return True if lib.startswith('c:\\windows'): return True if lib.endswith('exe'): return True for name in our_libs: if name in lib: return True return False with open(path, 'r') as fp: reader = csv.reader(fp) for row in reader: if len(row) < 2: continue lib = row[1] if not should_ignore_lib(lib): libs.add(lib) return set(libs) def copy_shared_libs(exes): '''Copy shared libs need by seafile-applet.exe, such as libccnet, libseafile, etc. First we use Dependency walker to analyse seafile-applet.exe, and get an output file in csv format. Then we parse the csv file to get the list of shared libs. ''' shared_libs = set() for exectuable in exes: shared_libs.update(dependency_walk(exectuable)) pack_bin_dir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') for lib in shared_libs: must_copy(lib, pack_bin_dir) ssleay32 = find_in_path('ssleay32.dll') must_copy(ssleay32, pack_bin_dir) def copy_dll_exe(): prefix = Seafile().prefix destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') filelist = [ os.path.join(prefix, 'bin', 'libsearpc-1.dll'), os.path.join(prefix, 'bin', 'libccnet-0.dll'), os.path.join(prefix, 'bin', 'libseafile-0.dll'), os.path.join(prefix, 'bin', 'ccnet.exe'), os.path.join(prefix, 'bin', 'seaf-daemon.exe'), os.path.join(SeafileClient().projdir, 'seafile-applet.exe'), ] for name in filelist: must_copy(name, destdir) extdlls = [ os.path.join(SeafileClient().projdir, 'extensions', 'lib', 'seafile_shell_ext.dll'), os.path.join(SeafileClient().projdir, 'extensions', 'lib', 'seafile_shell_ext64.dll'), ] customdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'custom') for dll in extdlls: must_copy(dll, customdir) copy_shared_libs([ f for f in filelist if f.endswith('.exe') ]) copy_qt_plugins_imageformats() copy_qt_plugins_platforms() copy_qt_translations() def copy_qt_plugins_imageformats(): destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin', 'imageformats') must_mkdir(destdir) qt_plugins_srcdir = os.path.join(conf[CONF_QT_ROOT], 'plugins', 'imageformats') src = os.path.join(qt_plugins_srcdir, 'qico4.dll') if conf[CONF_QT5]: src = os.path.join(qt_plugins_srcdir, 'qico.dll') must_copy(src, destdir) src = os.path.join(qt_plugins_srcdir, 'qgif4.dll') if conf[CONF_QT5]: src = os.path.join(qt_plugins_srcdir, 'qgif.dll') must_copy(src, destdir) def copy_qt_plugins_platforms(): if not conf[CONF_QT5]: return destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin', 'platforms') must_mkdir(destdir) qt_plugins_srcdir = os.path.join(conf[CONF_QT_ROOT], 'plugins', 'platforms') src = os.path.join(qt_plugins_srcdir, 'qwindows.dll') must_copy(src, destdir) src = os.path.join(qt_plugins_srcdir, 'qminimal.dll') must_copy(src, destdir) def copy_qt_translations(): destdir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') qt_translation_dir = os.path.join(conf[CONF_QT_ROOT], 'translations') i18n_dir = os.path.join(SeafileClient().projdir, 'i18n') qm_pattern = os.path.join(i18n_dir, 'seafile_*.qm') qt_qms = set() def add_lang(lang): if not lang: return qt_qm = os.path.join(qt_translation_dir, 'qt_%s.qm' % lang) if os.path.exists(qt_qm): qt_qms.add(qt_qm) elif '_' in lang: add_lang(lang[:lang.index('_')]) for fn in glob.glob(qm_pattern): name = os.path.basename(fn) m = re.match(r'seafile_(.*)\.qm', name) lang = m.group(1) add_lang(lang) for src in qt_qms: must_copy(src, destdir) def prepare_msi(): pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') msi_dir = os.path.join(Seafile().projdir, 'msi') must_copytree(msi_dir, pack_dir) must_mkdir(os.path.join(pack_dir, 'bin')) if run('make', cwd=os.path.join(pack_dir, 'custom')) != 0: error('Error when compiling seafile msi custom dlls') copy_dll_exe() def sign_executables(): certfile = conf.get(CONF_CERTFILE) if certfile is None: info('exectuable signing is skipped since no cert is provided.') return pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') exectuables = glob.glob(os.path.join(pack_dir, 'bin', '*.exe')) for exe in exectuables: do_sign(certfile, exe) def sign_installers(): certfile = conf.get(CONF_CERTFILE) if certfile is None: info('msi signing is skipped since no cert is provided.') return pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') installers = glob.glob(os.path.join(pack_dir, '*.msi')) for fn in installers: name = conf[CONF_BRAND] if name == 'seafile': name = 'Seafile' do_sign(certfile, fn, desc='{} Installer'.format(name)) def do_sign(certfile, fn, desc=None): certfile = to_win_path(certfile) fn = to_win_path(fn) info('signing file {} using cert "{}"'.format(fn, certfile)) if desc: desc_flags = '-d "{}"'.format(desc) else: desc_flags = '' signcmd = 'signtool.exe sign -fd sha256 -t http://timestamp.digicert.com -f {} {} {}'.format(certfile, desc_flags, fn) if run(signcmd, cwd=os.path.dirname(fn)) != 0: error('Failed to sign file "{}"'.format(fn)) def strip_symbols(): bin_dir = os.path.join(conf[CONF_BUILDDIR], 'pack', 'bin') def do_strip(fn, stripcmd='strip'): run('%s "%s"' % (stripcmd, fn)) info('stripping: %s' % fn) for dll in glob.glob(os.path.join(bin_dir, '*.dll')): name = os.path.basename(dll).lower() if 'qt' in name: do_strip(dll) if name == 'seafile_shell_ext.dll': do_strip(dll) elif name == 'seafile_shell_ext64.dll': do_strip(dll, stripcmd='x86_64-w64-mingw32-strip') def edit_fragment_wxs(): '''In the main wxs file(seafile.wxs) we need to reference to the id of seafile-applet.exe, which is listed in fragment.wxs. Since fragments.wxs is auto generated, the id is sequentially generated, so we need to change the id of seafile-applet.exe manually. ''' file_path = os.path.join(conf[CONF_BUILDDIR], 'pack', 'fragment.wxs') new_lines = [] with open(file_path, 'r') as fp: for line in fp: if 'seafile-applet.exe' in line: # change the id of 'seafile-applet.exe' to 'seafileapplet.exe' new_line = re.sub('file_bin_[\d]+', 'seafileapplet.exe', line) new_lines.append(new_line) else: new_lines.append(line) content = '\r\n'.join(new_lines) with open(file_path, 'w') as fp: fp.write(content) def generate_breakpad_symbols(): seafiledir = Seafile().projdir script = os.path.join(seafiledir, 'scripts/breakpad.py') symbol_file = 'seaf-daemon.exe.sym-%s' % conf[CONF_VERSION] output = os.path.join(seafiledir, symbol_file) # generate the breakpad symbols if run('python %s --output %s' % (script, output)) != 0: error('Error when generating breakpad symbols') # move symbols to output directory dst_symbol_file = os.path.join(conf[CONF_OUTPUTDIR], symbol_file) must_copy(output, dst_symbol_file) def build_msi(): prepare_msi() generate_breakpad_symbols() if conf[CONF_DEBUG] or conf[CONF_NO_STRIP]: info('Would not strip exe/dll symbols since --debug or --nostrip is specified') else: strip_symbols() # Only sign the exectuables after stripping symbols. if need_sign(): sign_executables() pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') if run('make fragment.wxs', cwd=pack_dir) != 0: error('Error when make fragement.wxs') edit_fragment_wxs() if run('make', cwd=pack_dir) != 0: error('Error when make seafile.msi') def build_english_msi(): '''The extra work to build the English msi.''' pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') if run('make en', cwd=pack_dir) != 0: error('Error when make seafile-en.msi') def build_german_msi(): '''The extra work to build the German msi.''' pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') if run('make de', cwd=pack_dir) != 0: error('Error when make seafile-de.msi') def move_msi(): pack_dir = os.path.join(conf[CONF_BUILDDIR], 'pack') src_msi = os.path.join(pack_dir, 'seafile.msi') brand = conf[CONF_BRAND] dst_msi = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s.msi' % (brand, conf[CONF_VERSION])) # move msi to outputdir must_copy(src_msi, dst_msi) if not conf[CONF_ONLY_CHINESE]: src_msi_en = os.path.join(pack_dir, 'seafile-en.msi') dst_msi_en = os.path.join(conf[CONF_OUTPUTDIR], '%s-%s-en.msi' % (brand, conf[CONF_VERSION])) must_copy(src_msi_en, dst_msi_en) print '---------------------------------------------' print 'The build is successfully. Output is:' print '>>\t%s' % dst_msi if not conf[CONF_ONLY_CHINESE]: print '>>\t%s' % dst_msi_en # print '>>\t%s' % dst_msi_de print '---------------------------------------------' def check_tools(): tools = [ 'Paraffin', 'candle', 'light', 'depends', ] for prog in tools: if not find_in_path(prog + '.exe'): error('%s not found' % prog) def dump_env(): print 'Dumping environment variables:' for k, v in os.environ.iteritems(): print '%s: %s' % (k, v) def need_sign(): return conf[CONF_BRAND].lower() == 'seafile' def main(): dump_env() parse_args() setup_build_env() check_tools() libsearpc = Libsearpc() ccnet = Ccnet() seafile = Seafile() seafile_client = SeafileClient() libsearpc.uncompress() libsearpc.build() ccnet.uncompress() ccnet.build() seafile.uncompress() seafile.build() seafile_client.uncompress() seafile_client.build() build_msi() if not conf[CONF_ONLY_CHINESE]: build_english_msi() # build_german_msi() if need_sign(): sign_installers() move_msi() if __name__ == '__main__': main() seafile-6.1.5/scripts/build/gen-deb-src.py000077500000000000000000000324641323477647300204150ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This scirpt builds the seafile debian source tarball. In this tarball, libsearpc and ccnet is also included. ''' import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) import os import tempfile import glob import shutil import re import subprocess import optparse import atexit #################### ### Global variables #################### # command line configuartion conf = {} # key names in the conf dictionary. CONF_VERSION = 'version' CONF_LIBSEARPC_VERSION = 'libsearpc_version' CONF_CCNET_VERSION = 'ccnet_version' CONF_SEAFILE_VERSION = 'seafile_version' CONF_SEAFILE_CLIENT_VERSION = 'seafile_client_version' CONF_SRCDIR = 'srcdir' CONF_KEEP = 'keep' CONF_BUILDDIR = 'builddir' CONF_OUTPUTDIR = 'outputdir' #################### ### Common helper functions #################### def highlight(content, is_error=False): '''Add ANSI color to content to get it highlighted on terminal''' if is_error: return '\x1b[1;31m%s\x1b[m' % content else: return '\x1b[1;32m%s\x1b[m' % content def info(msg): print highlight('[INFO] ') + msg def exist_in_path(prog): '''Test whether prog exists in system path''' dirs = os.environ['PATH'].split(':') for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return True return False def error(msg=None, usage=None): if msg: print highlight('[ERROR] ') + msg if usage: print usage sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' info('running %s, cwd=%s' % (' '.join(argv), cwd if cwd else os.getcwd())) with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) return proc.wait() def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Like run_argv but specify a command line string instead of argv''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) return proc.wait() def must_mkdir(path): '''Create a directory, exit on failure''' try: os.mkdir(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) def check_targz_src(proj, version, srcdir): src_tarball = os.path.join(srcdir, '%s-%s.tar.gz' % (proj, version)) if not os.path.exists(src_tarball): error('%s not exists' % src_tarball) def remove_unused_files(): srcdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) web_sh_files = glob.glob(os.path.join(srcdir, 'web', '*.sh')) files = [ os.path.join(srcdir, 'web', 'pygettext.py'), ] files.extend(web_sh_files) for f in files: run('rm -f %s' % f) def gen_tarball(): output = os.path.join(conf[CONF_OUTPUTDIR], 'seafile-client-latest.tar.gz') dirname = 'seafile-%s' % conf[CONF_VERSION] ignored_patterns = [ # windows msvc dlls os.path.join(dirname, 'msi', 'bin*'), ] excludes_list = [ '--exclude=%s' % pattern for pattern in ignored_patterns ] argv = [ 'tar', 'czvf', output, dirname, ] argv.append(*excludes_list) if run_argv(argv) != 0: error('failed to gen %s' % output) print '---------------------------------------------' print 'The build is successfully. Output is:\t%s' % output print '---------------------------------------------' def uncompress_seafile(): src = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_SEAFILE_VERSION]) dst = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION]) if os.path.exists(src): error('dir %s already exists' % src) if os.path.exists(dst): error('dir %s already exists' % dst) tarball = os.path.join(conf[CONF_SRCDIR], 'seafile-%s.tar.gz' % conf[CONF_SEAFILE_VERSION]) argv = [ 'tar', 'xf', tarball, '-C', conf[CONF_BUILDDIR], ] if run_argv(argv) != 0: error('failed to uncompress seafile') if conf[CONF_VERSION] != conf[CONF_SEAFILE_VERSION]: shutil.move(src, dst) def uncompress_libsearpc(): tarball = os.path.join(conf[CONF_SRCDIR], 'libsearpc-%s.tar.gz' % conf[CONF_LIBSEARPC_VERSION]) dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'libsearpc') must_mkdir(dst_dir) argv = [ 'tar', 'xf', tarball, '--strip-components=1', '-C', dst_dir, ] if run_argv(argv) != 0: error('failed to uncompress libsearpc') def uncompress_ccnet(): tarball = os.path.join(conf[CONF_SRCDIR], 'ccnet-%s.tar.gz' % conf[CONF_CCNET_VERSION]) dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'ccnet') must_mkdir(dst_dir) argv = [ 'tar', 'xf', tarball, '--strip-components=1', '-C', dst_dir, ] if run_argv(argv) != 0: error('failed to uncompress ccnet') def uncompress_seafile_client(): tarball = os.path.join(conf[CONF_SRCDIR], 'seafile-client-%s.tar.gz' % conf[CONF_SEAFILE_CLIENT_VERSION]) dst_dir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'seafile-client') must_mkdir(dst_dir) argv = [ 'tar', 'xf', tarball, '--strip-components=1', '-C', dst_dir, ] if run_argv(argv) != 0: error('failed to uncompress ccnet') def remove_debian_subdir(): debian_subdir = os.path.join(conf[CONF_BUILDDIR], 'seafile-%s' % conf[CONF_VERSION], 'debian') argv = [ 'rm', '-rf', debian_subdir ] if run_argv(argv) != 0: error('failed to uncompress ccnet') def parse_args(): parser = optparse.OptionParser() def long_opt(opt): return '--' + opt parser.add_option(long_opt(CONF_VERSION), dest=CONF_VERSION, nargs=1, help='the version of seafile source. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_VERSION), dest=CONF_SEAFILE_VERSION, nargs=1, help='the version of seafile. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_LIBSEARPC_VERSION), dest=CONF_LIBSEARPC_VERSION, nargs=1, help='the version of libsearpc as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_CCNET_VERSION), dest=CONF_CCNET_VERSION, nargs=1, help='the version of ccnet as specified in its "configure.ac". Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_SEAFILE_CLIENT_VERSION), dest=CONF_SEAFILE_CLIENT_VERSION, nargs=1, help='the version of seafile-client. Must be digits delimited by dots, like 1.3.0') parser.add_option(long_opt(CONF_BUILDDIR), dest=CONF_BUILDDIR, nargs=1, help='the directory to build the source. Defaults to /tmp', default=tempfile.gettempdir()) parser.add_option(long_opt(CONF_OUTPUTDIR), dest=CONF_OUTPUTDIR, nargs=1, help='the output directory to put the generated server tarball. Defaults to the current directory.', default=os.getcwd()) parser.add_option(long_opt(CONF_SRCDIR), dest=CONF_SRCDIR, nargs=1, help='''Source tarballs must be placed in this directory.''') parser.add_option(long_opt(CONF_KEEP), dest=CONF_KEEP, action='store_true', help='''keep the build directory after the script exits. By default, the script would delete the build directory at exit.''') usage = parser.format_help() options, remain = parser.parse_args() if remain: error(usage=usage) validate_args(usage, options) def validate_args(usage, options): required_args = [ CONF_VERSION, CONF_SEAFILE_VERSION, CONF_LIBSEARPC_VERSION, CONF_CCNET_VERSION, CONF_SEAFILE_CLIENT_VERSION, CONF_SRCDIR, ] # fist check required args for optname in required_args: if getattr(options, optname, None) == None: error('%s must be specified' % optname, usage=usage) def get_option(optname): return getattr(options, optname) # [ version ] def check_project_version(version): '''A valid version must be like 1.2.2, 1.3''' if not re.match('^[0-9](\.[0-9])+$', version): error('%s is not a valid version' % version, usage=usage) version = get_option(CONF_VERSION) libsearpc_version = get_option(CONF_LIBSEARPC_VERSION) ccnet_version = get_option(CONF_CCNET_VERSION) seafile_version = get_option(CONF_SEAFILE_VERSION) seafile_client_version = get_option(CONF_SEAFILE_CLIENT_VERSION) check_project_version(version) check_project_version(libsearpc_version) check_project_version(ccnet_version) check_project_version(seafile_version) check_project_version(seafile_client_version) # [ srcdir ] srcdir = get_option(CONF_SRCDIR) check_targz_src('libsearpc', libsearpc_version, srcdir) check_targz_src('ccnet', ccnet_version, srcdir) check_targz_src('seafile', seafile_version, srcdir) check_targz_src('seafile-client', seafile_client_version, srcdir) # [ builddir ] builddir = get_option(CONF_BUILDDIR) if not os.path.exists(builddir): error('%s does not exist' % builddir, usage=usage) builddir = os.path.join(builddir, 'seafile-deb-src') # [ outputdir ] outputdir = get_option(CONF_OUTPUTDIR) if not os.path.exists(outputdir): error('outputdir %s does not exist' % outputdir, usage=usage) # [ keep ] keep = get_option(CONF_KEEP) conf[CONF_VERSION] = version conf[CONF_LIBSEARPC_VERSION] = libsearpc_version conf[CONF_CCNET_VERSION] = ccnet_version conf[CONF_SEAFILE_VERSION] = seafile_version conf[CONF_SEAFILE_CLIENT_VERSION] = seafile_client_version conf[CONF_BUILDDIR] = builddir conf[CONF_SRCDIR] = srcdir conf[CONF_OUTPUTDIR] = outputdir conf[CONF_KEEP] = keep prepare_builddir(builddir) show_build_info() def prepare_builddir(builddir): must_mkdir(builddir) if not conf[CONF_KEEP]: def remove_builddir(): '''Remove the builddir when exit''' info('remove builddir before exit') shutil.rmtree(builddir, ignore_errors=True) atexit.register(remove_builddir) os.chdir(builddir) def show_build_info(): '''Print all conf information. Confirm before continue.''' info('------------------------------------------') info('Seafile debian source tarball %s:' % conf[CONF_VERSION]) info('------------------------------------------') info('seafile: %s' % conf[CONF_SEAFILE_VERSION]) info('seafile-client: %s' % conf[CONF_SEAFILE_CLIENT_VERSION]) info('ccnet: %s' % conf[CONF_CCNET_VERSION]) info('libsearpc: %s' % conf[CONF_LIBSEARPC_VERSION]) info('builddir: %s' % conf[CONF_BUILDDIR]) info('outputdir: %s' % conf[CONF_OUTPUTDIR]) info('source dir: %s' % conf[CONF_SRCDIR]) info('clean on exit: %s' % (not conf[CONF_KEEP])) info('------------------------------------------') info('press any key to continue ') info('------------------------------------------') dummy = raw_input() def main(): parse_args() uncompress_seafile() uncompress_libsearpc() uncompress_ccnet() uncompress_seafile_client() remove_debian_subdir() remove_unused_files() gen_tarball() if __name__ == '__main__': main()seafile-6.1.5/scripts/seaf-cli-wrapper.sh000077500000000000000000000033071323477647300203450ustar00rootroot00000000000000#!/bin/bash # This is a wrapper shell script for the real seaf-cli command. # It prepares necessary environment variables and exec the real script. # seafile cli client requires python 2.6 or 2.7 function check_python_executable() { if [[ "$PYTHON" != "" && -x $PYTHON ]]; then return 0 fi if which python2.7 2>/dev/null 1>&2; then PYTHON=python2.7 elif which python27 2>/dev/null 1>&2; then PYTHON=python27 elif which python2.6 2>/dev/null 1>&2; then PYTHON=python2.6 elif which python26 2>/dev/null 1>&2; then PYTHON=python26 else echo echo "Can't find a python executable of version 2.6 or above in PATH" echo "Install python 2.6+ before continue." echo "Or if you installed it in a non-standard PATH, set the PYTHON enviroment varirable to it" echo exit 1 fi } check_python_executable # seafile cli client requires the argparse module if ! $PYTHON -c 'import argparse' 2>/dev/null 1>&2; then echo echo "Python argparse module is required" echo "see [https://pypi.python.org/pypi/argparse]" echo exit 1 fi SCRIPT=$(readlink -f "$0") INSTALLPATH=$(dirname "${SCRIPT}") SEAFILE_BIN_DIR=${INSTALLPATH}/bin SEAFILE_LIB_DIR=${INSTALLPATH}/lib:${INSTALLPATH}/lib64 SEAFILE_PYTHON_PATH=${INSTALLPATH}/lib/python2.6/site-packages:${INSTALLPATH}/lib64/python2.6/site-packages:${INSTALLPATH}/lib/python2.7/site-packages:${INSTALLPATH}/lib64/python2.7/site-packages SEAF_CLI=${SEAFILE_BIN_DIR}/seaf-cli.py PATH=${SEAFILE_BIN_DIR}:${PATH} \ PYTHONPATH=${SEAFILE_PYTHON_PATH}:${PYTHONPATH} \ SEAFILE_LD_LIBRARY_PATH=${SEAFILE_LIB_DIR}:${LD_LIBRARY_PATH} \ exec $PYTHON ${SEAF_CLI} "$@" seafile-6.1.5/setupwin.py000066400000000000000000000155201323477647300154060ustar00rootroot00000000000000#!/usr/bin/env python # coding: UTF-8 '''This scirpt is used to bundle all needed files into the destdir to faciliate windows development. ''' import sys #################### ### Requires Python 2.6+ #################### if sys.version_info[0] == 3: print 'Python 3 not supported yet. Quit now.' sys.exit(1) if sys.version_info[1] < 6: print 'Python 2.6 or above is required. Quit now.' sys.exit(1) import os import glob import shutil import subprocess import tempfile import csv from distutils.core import setup as dist_setup import py2exe def usage(): print '''\ Usage: %s ''' #################### ### Common helper functions #################### def to_mingw_path(path): if len(path) < 2 or path[1] != ':' : return path.replace('\\', '/') drive = path[0] return '/%s%s' % (drive.lower(), path[2:].replace('\\', '/')) def to_win_path(path): if len(path) < 2 or path[1] == ':' : return path.replace('/', '\\') drive = path[1] return '%s:%s' % (drive.lower(), path[2:].replace('/', '\\')) def info(msg): print '[INFO] ' + msg def error(msg=None, usage=None): if msg: print '[ERROR] ' + msg if usage: print usage sys.exit(1) def which(prog): '''Return the path of the file , if exists in PATH''' dirs = os.environ['PATH'].split(';') for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return path return None def run(cmdline, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' info('running %s, cwd=%s' % (cmdline, cwd if cwd else os.getcwd())) with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(cmdline, cwd=cwd, stdout=stdout, stderr=stderr, env=env, shell=True) return proc.wait() def rmtree(path): '''Remove a directory, ignore errors''' try: shutil.rmtree(path) except: pass def must_mkdir(path): '''Create a directory, exit on failure''' try: os.mkdir(path) except OSError, e: error('failed to create directory %s:%s' % (path, e)) def must_copy(src, dst): '''Copy src to dst, exit on failure''' try: info('copying %s --> %s' % (src, dst)) shutil.copy(src, dst) except Exception, e: error('failed to copy %s to %s: %s' % (src, dst, e)) def must_copytree(src, dst): '''Copy dir src to dst, exit on failure''' try: info('copying directory %s --> %s' % (src, dst)) shutil.copytree(src, dst) except Exception, e: error('failed to copy dir %s to %s: %s' % (src, dst, e)) def must_move(src, dst): '''Move src to dst, exit on failure''' try: info('moving %s --> %s' % (src, dst)) shutil.move(src, dst) except Exception, e: error('failed to move %s to %s: %s' % (src, dst, e)) def web_py2exe(): webdir = os.path.join(seafile_srcdir, 'web') dist_dir = os.path.join(webdir, 'dist') build_dir = os.path.join(webdir, 'build') rmtree(dist_dir) rmtree(build_dir) os.chdir(webdir) original_argv = sys.argv sys.argv = [sys.argv[0], 'py2exe'] sys.path.insert(0, webdir) targetname = 'seafile-web' targetfile = targetname + '.py' must_copy('main.py', targetfile) packages=["mako.cache", "utils"] ex_files=[] option = {"py2exe": {"includes" :[targetname], "packages" : packages, "bundle_files" : 3}} try: dist_setup(name=targetname, options = option, windows=[{"script":targetfile}], data_files=ex_files) except Exception as e: error('Error when calling py2exe: %s' % e) for name in glob.glob('dist/*'): must_copy(name, bin_dir) must_copytree('i18n', os.path.join(bin_dir, 'i18n')) must_copytree('static', os.path.join(bin_dir, 'static')) must_copytree('templates', os.path.join(bin_dir, 'templates')) rmtree(dist_dir) rmtree(build_dir) sys.path.pop(0) sys.argv = original_argv os.chdir(seafile_srcdir) def parse_depends_csv(path): '''parse the output of dependency walker''' libs = [] def should_ingore_lib(lib): if not os.path.exists(lib): return True if lib.lower().startswith('c:\\windows'): return True return False with open(path, 'r') as fp: reader = csv.reader(fp) for row in reader: if len(row) < 2: continue lib = row[1] if not should_ingore_lib(lib): libs.append(lib) return libs def copy_shared_libs(): '''Copy shared libs need by libccnet, such as libevent, libsqlite, etc. First we use Dependency walker to analyse libccnet-0.dll, and get an output file in csv format. Then we parse the csv file to get the list of shared libs. ''' tempdir = tempfile.gettempdir() output = os.path.join(tempdir, 'depends.csv') applet = os.path.join(seafile_srcdir, 'gui', 'win', 'seafile-applet.exe') cmd = 'depends.exe -c -f 1 -oc %s %s' % (output, applet) # See the manual of Dependency walker if run(cmd) > 0x100: error('failed to run dependency walker for libccnet') if not os.path.exists(output): error('failed to run dependency walker for libccnet') shared_libs = parse_depends_csv(output) for lib in shared_libs: must_copy(lib, bin_dir) libsqlite3 = which('libsqlite3-0.dll') must_copy(libsqlite3, bin_dir) def copy_dll_exe(): filelist = [ 'libsearpc-1.dll', 'libsearpc-json-glib-0.dll', 'libccnet-0.dll', 'libseafile-0.dll', 'ccnet.exe', 'seaf-daemon.exe', ] filelist = [ which(f) for f in filelist ] applet = os.path.join(seafile_srcdir, 'gui', 'win', 'seafile-applet.exe') filelist.append(applet) for name in filelist: must_copy(name, bin_dir) copy_shared_libs() def main(): if not os.path.exists(destdir): must_mkdir(destdir) if not os.path.exists(bin_dir): must_mkdir(bin_dir) web_py2exe() copy_dll_exe() if __name__ == '__main__': if len(sys.argv) != 2: usage() exit(1) seafile_srcdir = os.getcwd() destdir = to_win_path(sys.argv[1]) bin_dir = os.path.join(destdir, 'bin') main() seafile-6.1.5/tests/000077500000000000000000000000001323477647300143155ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/000077500000000000000000000000001323477647300172145ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/README.md000066400000000000000000000006501323477647300204740ustar00rootroot00000000000000## Prerequisite pip install -r requirements.txt ## Run 1. cp run.sh.template run.sh && cp test.conf.template test.conf 2. modify PYTHONPATH, PATH in run.sh * note you must copy seafile related site_packages to test machine and point the path in PYTHONPATH * note you must point seaf-daemon, ccnet file path in PATH 3. modify server_url, user, password in test.conf 4. start seahub server 5. execute ./run.sh test seafile-6.1.5/tests/sync-auto-test/__init__.py000066400000000000000000000000001323477647300213130ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/cli1/000077500000000000000000000000001323477647300200445ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/cli1/ccnet.conf000066400000000000000000000001661323477647300220120ustar00rootroot00000000000000[General] USER_NAME = anonymous ID = dbf3688a7fbddea62ad894b795c4184bfe7bd9f8 NAME = anonymous [Client] PORT = 13419 seafile-6.1.5/tests/sync-auto-test/cli1/mykey.peer000066400000000000000000000032131323477647300220560ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEoQIBAAKCAQEAv6CFpIy8zAhm3kLNbvJUro+6VmVpJSBQFtnjmei+8qvM+C3Q uyyln41h+I64nZ3ZbJDCxfckk9c2Gh+qlF17N1ntxphq27UcrO4cGgDwmJ0BUuMd G7mqeNRV03Si9VTAr0z4vvHR4su5XAihWvbdtA+1r2/WJmW2bJxswmaq2JMWHuCK 1+JrFeMFUyxVyKTF77wflu0q6AqqjzyQk9Z03zY+KTRcwDuKHp1tlY3nD8XgliKc HA0Rd56CvHZM36cO6C6G5Q9xVk+DfzD6yfBCOlMsbQOeD2mxVtnfNWKU+vrgDK8i khWN7QcB6Scxs53/O4Hhm6a3E3bIZ9OElZEKSQIBIwKCAQAxRojD6azkAikUlNW9 cYN9WCiZ35AQ3Gxdpb4u5BPYAEqmN6qzyabug3D2xZ0v2CH3WGyZTi36IWWu8jMt dx+vJcDMqtmmNeLNYcy2OsGGVEIrQbcHIR01A2aG1NlySP5Y9okbKD1I8o6/5PZK l0BS33fcp7q5apyflfAUu1CA1OuEmHOQKW5ZgEhtadAfRrZuFVOXtG8gGe/xt/Jw QaRnj3fsWC/IAyaXlfLKGe9jrWxmSjiHL7sZPO3rLVNoAEyOPaKN7dzR4AaJI1Ve 2jztM4HctQ43sGyw0gpID/OqVRAryiWm0UWj0cbHBt2JlhxvvOOHssT429+ol1Ce O3tXAoGBAOL3E1IrtnFf8aDbCZBgA96wAEXbtISZfehjww8q30oN5DAUv4WBKJx+ Jy505/SnGlMoZheJYmAAligu/rOOVrm9wzkpapj2xrOV4aPuw0qi3tpy2bQiNKAF 3No6g1/PxDmNX9y2gWb0qKP1F4NiZ5ZD2z4/bbARgNPealGiBxTLAoGBANgkJwV7 itrLqS5c3JwLcXch2rEX7L1DfTl/dURfFFYiJB9Ecznf6jsaEqtkCDMBeuff8Tb2 uC8xVEuJHKpLFkfk0PIFeZoS6LZ+qXyjMZjgj5HYvyRp+L/2r8CNS9bqJLzxdgjE nzSXvMq1Ld8BQ/phjy6FZV5WnuQWOTJTTU67AoGAE3RDfBJgGFiuT52+/b8WRkmZ n5Z9L+/mOH2UYGLCrpN59X4fC3F4gnE2jvQT4cUuJGKMaGrci+LLCsIzFrRt1WgJ a0yxXZF+vu+W/2w8n/9U7icZ+X9GVtvuW9khNBkfcqW3wnYLF3QOdHQX9VGT2a4L el01SZsZq8KbZhUzzpUCgYEAxZ1lgVsCnCfrIxMS18/ythBS6w6PTfSPv4p52Bxq XWELFUXlsUHANgk1pAOvuZr0BzMlrpht4gE3IH1cCWk48UY7YO8QF9bGIzH6C43k NACDQ4RW/Lio6gYdB9GkbLjRIcbSUSjMEtPfz0aQVtyV7Dvwn4/nprWYlgWwowpV T0sCgYADpCjBMC9YGiigSh0ss0qqCxS6i76LJikd+HZPeEAVCIO6ljBUkDQspv/m 2NhefJ/fM/Jpm9koGZqXVwv+Hh3qCAuuY3c28Fehd/e1ATJA6RbS9W8oBwNLgMM0 TfD83Ye1wWe5m4ab1/2034Nxp33gn/Uhf6OBdgCr5fEUmrqTXw== -----END RSA PRIVATE KEY----- seafile-6.1.5/tests/sync-auto-test/cli2/000077500000000000000000000000001323477647300200455ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/cli2/ccnet.conf000066400000000000000000000001661323477647300220130ustar00rootroot00000000000000[General] USER_NAME = anonymous ID = 5525c22aebbc9e115e5a5872e525821c08b20ec3 NAME = anonymous [Client] PORT = 13420 seafile-6.1.5/tests/sync-auto-test/cli2/mykey.peer000066400000000000000000000032131323477647300220570ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAxTsfwh1gLycQgmDM22Y6gonR2EYlz/T3157IyxOipjeEZZVZ n2FECRH/j4NFTdCAiZ4DxPIQsYLlbJ6j1lvS8HlVcBtVWbM4Ibs4PPtIqT9MJyYK QXkJKG4igiV08wVO/88vrsnQ9IcCbmbMP3y+J9U7aJtp2C+kZGy8jDGd9Ewvi/IO PmiuWj27GXI1hnLWN4yzqPXnIUbak7SAbo0pPHldkVmi+mp+eHrfsQiSTko9pvST 3VVjwYSAn1SLICkEvo8+rsSDkC+ol66M+ObOemSUdh0IWllKt6JSHwf9bFmLG+Mz UnZ/zDYJjS/Uow2sxbLRQP8FVi4mX+XenbMHcwIBIwKCAQAWimoHjlQipWD49R65 /Q4ASkPeM+cQc8SNq78tJtDCigCAo1qzIQ8W+r4fB7AmJnUXCr6aKksM+QRG7Y8R LxDLBo1r5d3eXaAD2uHbFWdjzLg+/Qh8gtx5pi/UXA1dmjTqCQzDhMdsZzN6VOQk g0junAbKIGPeMVSdw0i/kKRWbuf9W/hUBGm+eep9bzov6hmgB9s52y4lhFO4kFjP Kezp5BDZ5bhpgoo06JGMBGUQ+nsLt917f2CelHh35snPGbthZ7o6f3S0XPxCXhKG 20jfChmgXU7msd/2YPUuw/YlaH1lpdiq5DmvQaNvIfgwH9XRmOxRLB2hvzCK3UCO Qf9rAoGBAOgLZ4n/ZwLSI/s5tc2UGLjadHOjAfZsnal/fl0rxWNUhwRMsBxv745c NUabLpR3g+xxjHSrmhQwxSyLOaQxgs76dmpANetzS82bph/QY+VVQDBVezuY1P0r /4H5oQ6X+1/f+s6SIWlzuBm5w1AESL+qzkxrFOvlL+d/SV30tSaNAoGBANmXpcdf 2w5FbvwWLyrPGb0k04HLthzsY1SFRxouGOzpZsXSD3jvRLbNUp+Ms4mCNpyO3005 IMIlLDX694EahQ4vzTbus1rytju3UUsMhCuFjAPlcVpe7+Xf0m7MNEUNC+ICfTzp CB2a/5nHA0j5rl4w6nEPqBYptVYhjIvMPGX/AoGAVjAfJKCxO4/hepHHLxnACiVB MkPcKFQ6j2neemC3B6MNk+H4RROiHu8MeU+U9VD2fGSwgxsqmcj4x2bphiEEs0cW CjUbV3P3lYL0j3lJrPPHYmjkoRuCT2gdEwTyraYqKuzK3wMTuXQfzwp7vqKBa8MZ bNdQ6edpkH+8KjZR6b8CgYEAxvEMmQcurfZW19nEuWzkVSj75GJ6nhn0aoh7haZ9 MGBd9rFtO15qtcMJtnIDO+TEN14N/XYPUmshG2kczc8akKC7n/Au9BEbpE/VS+4v ssM+L3Kwx6dBvDpZ/uaWMID06+UEyfmhBR//oooRoc5WR30uHjozR3aXKi1NTJ15 DMsCgYEAmGa3xJUt+Yzd6zxR0dhYRJeWzH95m6op/KwBwMmohSOiRPDx9B4FPkkp Di6j8gRz6TZ42qtXwY7X/tTF1oywY+dM7xOO6XKwntCRstAEly8uaVPtsB/xbl6l M4U37zo7tGmVxK31rMjV6/Zn2iRnqKNo6QpcBK4X0hg3scopRdg= -----END RSA PRIVATE KEY----- seafile-6.1.5/tests/sync-auto-test/requirements.txt000066400000000000000000000000051323477647300224730ustar00rootroot00000000000000nose seafile-6.1.5/tests/sync-auto-test/run.sh.template000077500000000000000000000014061323477647300221720ustar00rootroot00000000000000#!/bin/bash export PYTHONPATH= export PATH= OS=`uname -s` rm_sync_data() { rm -rf $1/ccnet.sock $1/seafile.ini $1/$1/logs $1/misc $1/seafile $1/seafile-data } run_test() { nosetests -v -s test_cases/test_simple.py test_cases/test_release.py if [ ${OS} != "Linux" -a ${OS} != "Darwin" ]; then rm_sync_data cli1 rm_sync_data cli2 fi } case $1 in "test") run_test sleep 10 export ENCRYPTED_REPO=true run_test;; "clean") if [ ${OS} = "Linux" -o ${OS} = "Darwin" ]; then pkill -f "ccnet --daemon -c $(pwd)/cli1" pkill -f "ccnet --daemon -c $(pwd)/cli2" fi rm -rf worktree1 worktree2 rm_sync_data cli1 rm_sync_data cli2;; esac seafile-6.1.5/tests/sync-auto-test/seaf_op.py000066400000000000000000000235531323477647300212120ustar00rootroot00000000000000''' seaf-cli is command line interface for seafile client. Subcommands: init: create config files for seafile client start: start and run seafile client as daemon stop: stop seafile client list: list local liraries status: show syncing status download: download a library from seafile server sync: synchronize an existing folder with a library in seafile server desync: desynchronize a library with seafile server create: create a new library Detail ====== Seafile client stores all its configure information in a config dir. The default location is `~/.ccnet`. All the commands below accept an option `-c `. init ---- Initialize seafile client. This command initializes the config dir. It also creates sub-directories `seafile-data` and `seafile` under `parent-dir`. `seafile-data` is used to store internal data, while `seafile` is used as the default location put downloaded libraries. seaf-cli init [-c ] -d start ----- Start seafile client. This command start `ccnet` and `seaf-daemon`, `ccnet` is the network part of seafile client, `seaf-daemon` manages the files. seaf-cli start [-c ] stop ---- Stop seafile client. seaf-cli stop [-c ] Download -------- Download a library from seafile server seaf-cli download -l -s -d -u -p sync ---- Synchronize a library with an existing folder. seaf-cli sync -l -s -d -u -p desync ------ Desynchronize a library from seafile server seaf-cli desync -d create ------ Create a new library seaf-cli create -s -n -u -p -t [-e ] ''' import os import json import subprocess import sys import time import urllib import urllib2 import httplib from urlparse import urlparse import ccnet import seafile def _check_seafile(): ''' Check ccnet and seafile have been installed ''' sep = ':' if os.name != 'nt' else ';' dirs = os.environ['PATH'].split(sep) def exist_in_path(prog): ''' Check whether 'prog' exists in system path ''' for d in dirs: if d == '': continue path = os.path.join(d, prog) if os.path.exists(path): return True progs = [ 'ccnet', 'seaf-daemon' ] for prog in progs: if os.name == 'nt': prog += '.exe' if not exist_in_path(prog): print "%s not found in PATH. Have you installed seafile?" % prog sys.exit(1) def run_argv(argv, cwd=None, env=None, suppress_stdout=False, suppress_stderr=False, wait=True): '''Run a program and wait it to finish, and return its exit code. The standard output of this program is supressed. ''' with open(os.devnull, 'w') as devnull: if suppress_stdout: stdout = devnull else: stdout = sys.stdout if suppress_stderr: stderr = devnull else: stderr = sys.stderr proc = subprocess.Popen(argv, cwd=cwd, stdout=stdout, stderr=stderr, env=env) if wait: return proc.wait() return 0 def get_env(): env = dict(os.environ) ld_library_path = os.environ.get('SEAFILE_LD_LIBRARY_PATH', '') if ld_library_path: env['LD_LIBRARY_PATH'] = ld_library_path return env class NoRedirect(urllib2.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, hdrs, newurl): pass def urlopen(url, data=None, headers=None, follow_redirect=True): if data: data = urllib.urlencode(data) headers = headers or {} req = urllib2.Request(url, data=data, headers=headers) if follow_redirect: resp = urllib2.urlopen(req) else: try: opener = urllib2.build_opener(NoRedirect()) resp = opener.open(req) except urllib2.HTTPError: return None return resp.read() def get_token(url, username, password): data = { 'username': username, 'password': password, } token_json = urlopen("%s/api2/auth-token/" % url, data=data) tmp = json.loads(token_json) token = tmp['token'] return token def get_repo_downlod_info(url, token): headers = { 'Authorization': 'Token %s' % token } repo_info = urlopen(url, headers=headers) return json.loads(repo_info) def seaf_init(conf_dir): ''' initialize config directorys''' _check_seafile() seafile_ini = os.path.join(conf_dir, "seafile.ini") seafile_data = os.path.join(conf_dir, "seafile-data") fp = open(seafile_ini, 'w') fp.write(seafile_data) fp.close() print 'Init ccnet config success.' def seaf_start_all(conf_dir): ''' start ccnet and seafile daemon ''' seaf_start_ccnet(conf_dir) # wait ccnet process time.sleep(1) seaf_start_seafile(conf_dir) print 'Start ccnet, seafile daemon success.' def seaf_start_ccnet(conf_dir): ''' start ccnet daemon ''' cmd = [ "ccnet", "--daemon", "-c", conf_dir ] wait = False if os.name == 'nt' else True if run_argv(cmd, env=get_env(), suppress_stdout=True, wait=wait) != 0: print 'Failed to start ccnet daemon.' sys.exit(1) def seaf_start_seafile(conf_dir): ''' start seafile daemon ''' cmd = [ "seaf-daemon", "--daemon", "-c", conf_dir, "-d", os.path.join(conf_dir, 'seafile-data'), "-w", os.path.join(conf_dir, 'seafile') ] wait = False if os.name == 'nt' else True if run_argv(cmd, env=get_env(), suppress_stdout=True, wait=wait) != 0: print 'Failed to start seafile daemon' sys.exit(1) def seaf_stop(conf_dir): '''stop seafile daemon ''' pool = ccnet.ClientPool(conf_dir) client = pool.get_client() try: client.send_cmd("shutdown") except: # ignore NetworkError("Failed to read from socket") pass print 'Stop ccnet, seafile daemon success.' def get_base_url(url): parse_result = urlparse(url) scheme = parse_result.scheme netloc = parse_result.netloc if scheme and netloc: return '%s://%s' % (scheme, netloc) return None def get_netloc(url): parse_result = urlparse(url) return parse_result.netloc def seaf_sync(conf_dir, server_url, repo_id, worktree, username, passwd): ''' synchronize a library from seafile server ''' pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) token = get_token(server_url, username, passwd) tmp = get_repo_downlod_info("%s/api2/repos/%s/download-info/" % (server_url, repo_id), token) encrypted = tmp['encrypted'] magic = tmp.get('magic', None) enc_version = tmp.get('enc_version', None) random_key = tmp.get('random_key', None) clone_token = tmp['token'] relay_id = tmp['relay_id'] relay_addr = tmp['relay_addr'] relay_port = str(tmp['relay_port']) email = tmp['email'] repo_name = tmp['repo_name'] version = tmp.get('repo_version', 0) more_info = None base_url = get_base_url(server_url) if base_url: more_info = json.dumps({'server_url': base_url}) if encrypted == 1: repo_passwd = 's123' else: repo_passwd = None seafile_rpc.clone(repo_id, version, relay_id, repo_name.encode('utf-8'), worktree, clone_token, repo_passwd, magic, relay_addr, relay_port, email, random_key, enc_version, more_info) print 'Synchronize repo test success.' def seaf_desync(conf_dir, repo_path): '''Desynchronize a library from seafile server''' pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) repos = seafile_rpc.get_repo_list(-1, -1) repo = None for r in repos: if r.worktree.replace('/', '\\') == repo_path.decode('utf-8').replace('/', '\\'): repo = r break if repo: print "Desynchronize repo test success." seafile_rpc.remove_repo(repo.id) else: print "%s is not a library worktree" % repo_path def seaf_create(conf_dir, server_url, username, passwd, enc_repo): '''Create a library''' # curl -d 'username=&password=' http://127.0.0.1:8000/api2/auth-token token = get_token(server_url, username, passwd) headers = { 'Authorization': 'Token %s' % token } data = { 'name': 'test', 'desc': 'test', } if enc_repo: data['passwd'] = 's123' repo_info_json = urlopen("%s/api2/repos/" % server_url, data=data, headers=headers) repo_info = json.loads(repo_info_json) if enc_repo: print 'Create encrypted repo test success.' else: print 'Create non encrypted repo test success.' return repo_info['repo_id'] def seaf_delete(conf_dir, server_url, username, passwd, repo_id): '''Delete a library''' token = get_token(server_url, username, passwd) headers = { 'Authorization': 'Token %s' % token } conn = httplib.HTTPConnection(get_netloc(server_url)) conn.request('DELETE', '/api2/repos/%s/' % repo_id, None, headers) resp = conn.getresponse() if resp.status == 200: print 'Delete repo test success.' else: print 'Delete repo test failed: %s.' % resp.reason def seaf_get_repo(conf_dir, repo_id): pool = ccnet.ClientPool(conf_dir) seafile_rpc = seafile.RpcClient(pool, req_pool=False) return seafile_rpc.seafile_get_repo(repo_id) seafile-6.1.5/tests/sync-auto-test/setting.py000066400000000000000000000013761323477647300212520ustar00rootroot00000000000000#coding: utf-8 import os import ConfigParser class Setting(): def __init__(self): self.server_url = None self.user = None self.password = None def parse_config(self): config_path = None if os.environ.has_key('TEST_CONFIFG'): config_path = os.environ['TEST_CONFIG'] else: config_path = os.path.join(os.getcwd(), 'test.conf') if not os.path.exists(config_path): raise Exception("Test config %s doesn't exist" % config_path) parser = ConfigParser.ConfigParser() parser.read(config_path) self.server_url = parser.get('test', 'server_url') self.user = parser.get('test', 'user') self.password = parser.get('test', 'password') seafile-6.1.5/tests/sync-auto-test/test.conf.template000066400000000000000000000000461323477647300226540ustar00rootroot00000000000000[test] server_url = user = password = seafile-6.1.5/tests/sync-auto-test/test_cases/000077500000000000000000000000001323477647300213515ustar00rootroot00000000000000seafile-6.1.5/tests/sync-auto-test/test_cases/__init__.py000066400000000000000000000010421323477647300234570ustar00rootroot00000000000000from util import TestUtil import time test_util = TestUtil() def setup(): # init sync related stuff test_util.init_conf() test_util.start_daemon() time.sleep(2) test_util.create_repo() test_util.sync_repo() time.sleep(5) print '\n----------------------------------------------------------------------' def teardown(): # clean sync related stuf print '----------------------------------------------------------------------\n' test_util.desync_repo() test_util.stop_daemon() test_util.clean() seafile-6.1.5/tests/sync-auto-test/test_cases/test_release.py000066400000000000000000000156211323477647300244070ustar00rootroot00000000000000#coding: utf-8 import os import time import glob from threading import Thread from seaf_op import get_token, urlopen from . import test_util ''' Test add-delete-add sequence. ''' def test_add_delete_add(): test_util.set_test_root('test_add_delete_add') test_util.mkfile(1, 'test/1.txt', 'aaaaaaaa') test_util.rmdir(1, 'test') test_util.mkfile(1, 'test/1.txt', 'aaaaaaaa') test_util.verify_result() ''' Rename test: echo 111 > 1.txt; sleep 3; mv 1.txt 2.txt echo 222 > 3.txt; sleep 3; mv 2.txt 3.txt echo test > test.txt mkdir test; echo 444 > 4.txt; sleep 3; mv *.txt test mkdir test2; mv test test2 mv test2/test . echo 555 >> test/4.txt; mv test test2 mv test2 test3 ''' def test_rename(): test_util.set_test_root('test_rename') test_util.mkfile(1, '1.txt', '111') time.sleep(3) test_util.move(1, '1.txt', '2.txt') time.sleep(3) test_util.mkfile(1, '3.txt', '222') time.sleep(3) test_util.move(1, '2.txt', '3.txt') time.sleep(3) test_util.mkfile(1, 'test.txt', 'test') time.sleep(3) test_util.mkdir(1, 'test') test_util.mkfile(1, '4.txt', '444') time.sleep(3) test_util.batchmove(1, '*.txt', 'test') time.sleep(3) test_util.mkdir(1, 'test2') test_util.move(1, 'test', 'test2') time.sleep(3) test_util.move(1, 'test2/test', '') time.sleep(3) test_util.modfile(1, 'test/4.txt', '555') test_util.move(1, 'test', 'test2') time.sleep(3) test_util.move(1, 'test2', 'test3') test_util.verify_result() ''' Create and update test: echo 111 > test/1.txt echo 222 >> test/1.txt copy a dir with multiple levels into test dir create an empty dir add file into an empty folder ''' def test_create_update(): test_util.set_test_root('test_create_update') test_util.mkdir(1, 'test') test_util.mkfile(1, 'test/1.txt', '111') time.sleep(3) test_util.modfile(1, 'test/1.txt', '222') time.sleep(3) test_util.mkdir(1, '1/2/3/4/5') test_util.mkfile(1, '1/1.txt', '111') test_util.mkfile(1, '1/2/2.txt', '222') test_util.copy(1, '1', 'test/1') time.sleep(3) test_util.mkdir(1, 'empty') time.sleep(3) test_util.mkfile(1, 'empty/test.md', 'dddddddddddddddddddddd') test_util.verify_result() ''' Delete test: echo 222 > 2.txt rm 2.txt delete a dir with multiple levels delete all files under a dir, make it empty. delete empty dir ''' def test_delete(): test_util.set_test_root('test_delete') test_util.mkfile(1, '2.txt', '2222') time.sleep(3) test_util.rmfile(1, '2.txt') test_util.mkdir(1, '1/2/3/4/5') test_util.mkfile(1, '1/1.txt', '111') test_util.mkfile(1, '1/2/2.txt', '222') test_util.copy(1, '1', 'test/1') time.sleep(3) test_util.rmdir(1, '1') time.sleep(3) test_util.rmdir(1, 'test/1') time.sleep(3) test_util.rmdir(1, 'test') test_util.verify_result() ''' Case rename test: rename a dir from 'test' to 'TEST' disalbe auto sync; rename the dir from 'TEST' to 'test'; enable auto sync. ''' def test_case_rename(): test_util.set_test_root('test_case_rename') test_util.mkdir(1, 'test') test_util.mkfile(1, 'a.txt', 'aaaa') time.sleep(3) test_util.move(1, 'test', 'TEST') test_util.verify_result() test_util.desync_cli1() test_util.move(1, 'TEST', 'test') test_util.sync_cli1() test_util.verify_result() ''' A test set for downloads. The updates are done on cli1 and downloaded on cli2. Note that these tests are different from upload tests. In upload tests, we deliberately combine multiple operations into one test; in download tests, we must ensure each operation be carried out individually on cli2. ''' # Create a new file def test_download_1(): test_util.set_test_root('test_download') test_util.mkfile(1, '1.txt', '11111') test_util.verify_result() # Update a file def test_download_2(): test_util.set_test_root('test_download') test_util.modfile(1, '1.txt', '22222') test_util.verify_result() # Create empty dir def test_download_3(): test_util.set_test_root('test_download') test_util.mkdir(1, 'dir1') test_util.verify_result() # Rename a file def test_download_4(): test_util.set_test_root('test_download') test_util.move(1, '1.txt', '2.txt') test_util.verify_result() # Rename empty dir def test_download_5(): test_util.set_test_root('test_download') test_util.move(1, 'dir1', 'dir2') test_util.verify_result() # Create file in empty dir def test_download_6(): test_util.set_test_root('test_download') test_util.mkfile(1, 'dir2/1.txt', '1111111') test_util.verify_result() # Rename a non-empty dir def test_download_7(): test_util.set_test_root('test_download') test_util.move(1, 'dir2', 'dir3') test_util.verify_result() # Remove all files in a non-empty dir def test_download_8(): test_util.set_test_root('test_download') test_util.rmfile(1, 'dir3/1.txt') test_util.verify_result() # Move a non-empty dir into an empty dir def test_download_9(): test_util.set_test_root('test_download') test_util.mkfile(1, 'dir4/2.txt', '2222222') test_util.verify_result() test_util.move(1, 'dir4', 'dir3') test_util.verify_result() # Delete file def test_download_10(): test_util.set_test_root('test_download') test_util.rmfile(1, '2.txt') test_util.verify_result() # Delete a non-empty dir def test_download_11(): test_util.set_test_root('test_download') test_util.rmdir(1, 'dir3/dir4') test_util.verify_result() # Delete empty dir def test_download_12(): test_util.set_test_root('test_download') test_util.rmdir(1, 'dir3') test_util.verify_result() ''' Test cases for download case rename ''' def test_download_case_rename_1(): test_util.set_test_root('test_download_case_rename') test_util.mkfile(1, 'abc/test/test.txt', 'testtset') test_util.verify_result() test_util.move(1, 'abc/test', 'abc/TEST') test_util.move(1, 'abc', 'ABC') test_util.verify_result() def test_download_case_rename_2(): test_util.set_test_root('test_download_case_rename') test_util.mkfile(1, 'a.txt', 'aaaaaaaaaaaaaaaaaaa') test_util.mkfile(1, 'test/b.txt', 'bbbbbbbbbb') test_util.verify_result() test_util.move(1, 'test', 'TEST') test_util.move(1, 'a.txt', 'TEST') test_util.verify_result() '''create cur.md, wait for synced then concurrent modify cur.md ''' # def mod_file(worktree, fname): # test_util.modfile(worktree, fname, test_util.getpath(worktree, fname)) # def test_concurrent_mod(): # test_util.mkfile(1, 'cur.md', 'curcurcurrrrrrrrrrrrrrrrrrrrr') # test_util.verify_result() # thread1 = Thread(target=mod_file, args=(1, 'cur.md')) # thread2 = Thread(target=mod_file, args=(2, 'cur.md')) # thread1.start() # thread2.start() # test_util.verify_result() # files = glob.glob(test_util.getpath(1, 'cur*.md')) # assert len(files) == 2, 'Should generate conflict file' seafile-6.1.5/tests/sync-auto-test/test_cases/test_simple.py000066400000000000000000000034421323477647300242560ustar00rootroot00000000000000#coding: utf-8 import os import time from . import test_util def test_add_file(): test_util.mkfile(1, 'a.md', 'add a file') test_util.verify_result() def test_add_file_t(): test_util.mkfile(2, 'l/m/n/test.md', 'add l/m/n/test.md') test_util.verify_result() def test_add_dir(): test_util.mkdir(1, 'ad') test_util.verify_result() def test_add_dir_t(): test_util.mkdir(2, 'tt/ee/st') test_util.verify_result() def test_modify_file(): test_util.modfile(1, 'a.md', 'modify a.md') test_util.verify_result() def test_rm_file(): test_util.rmfile(1, 'a.md') test_util.verify_result() def test_rm_dir(): test_util.rmdir(1, 'ad') test_util.verify_result() def test_rename_file(): test_util.mkfile(2, 'b.md', 'add b.md') time.sleep(1) test_util.move(2, 'b.md', 'b_bak.md') test_util.verify_result() def test_rename_dir(): test_util.mkdir(2, 'ab') time.sleep(1) test_util.move(2, 'ab', 'ab_bak') test_util.verify_result() def test_each(): test_util.mkdir(1, 'abc1') test_util.mkfile(1, 'abc1/c.md', 'add abc1/c.md') time.sleep(1) test_util.mkdir(2, 'bcd1') test_util.mkfile(2, 'bcd1/d.md', 'add bcd1/d.md') test_util.verify_result() def test_unsync_resync(): test_util.desync_cli1() test_util.rmdir(1, 'abc1') test_util.modfile(1, 'bcd1/d.md', 'modify bcd1/d.md to test unsync resync') test_util.sync_cli1() test_util.verify_result() if not os.path.exists(test_util.getpath(1, 'abc1')): assert False, 'dir abc1 should be recreated when resync' if len(os.listdir(test_util.getpath(1, 'bcd1'))) != 2: assert False, 'should generate conflict file for bcd1/d.md when resync' def test_modify_timestamp(): test_util.touch(1, 'bcd1/d.md') test_util.verify_result() seafile-6.1.5/tests/sync-auto-test/util.py000066400000000000000000000212151323477647300205440ustar00rootroot00000000000000#coding: utf-8 import os import shutil import time import subprocess import glob from setting import Setting import seaf_op def call_process(params): with open(os.devnull, 'w') as fd: ret = subprocess.check_output(params, stderr=fd) return ret class TestUtil(): def __init__(self): self.setting = Setting() self.cli1_dir = os.path.join(os.getcwd(), 'cli1') self.cli2_dir = os.path.join(os.getcwd(), 'cli2') self.worktree1 = os.path.join(os.getcwd(), 'worktree1') self.worktree2 = os.path.join(os.getcwd(), 'worktree2') self.enc_repo = False try: self.enc_repo = bool(os.environ['ENCRYPTED_REPO']) except Exception: pass self.repo_id = None self.test_root = '' def set_test_root(self, root): self.test_root = root @staticmethod def clean_sync_data(conf): try: os.remove(os.path.join(conf, 'ccnet.sock')) os.remove(os.path.join(conf, 'seafile.ini')) shutil.rmtree(os.path.join(conf, 'logs')) shutil.rmtree(os.path.join(conf, 'misc')) shutil.rmtree(os.path.join(conf, 'seafile')) shutil.rmtree(os.path.join(conf, 'seafile-data')) except Exception: pass def init_conf(self): self.setting.parse_config() if not os.path.exists(self.cli1_dir) or not os.path.exists(self.cli2_dir): raise Exception('ccnet conf dir is missing') if os.name != 'nt': TestUtil.clean_sync_data(self.cli1_dir) TestUtil.clean_sync_data(self.cli2_dir) if os.path.exists(self.worktree1): shutil.rmtree(self.worktree1) if os.path.exists(self.worktree2): shutil.rmtree(self.worktree2) os.mkdir(self.worktree1) os.mkdir(self.worktree2) seaf_op.seaf_init(self.cli1_dir) seaf_op.seaf_init(self.cli2_dir) def start_daemon(self): seaf_op.seaf_start_all(self.cli1_dir) seaf_op.seaf_start_all(self.cli2_dir) def create_repo(self): self.repo_id = seaf_op.seaf_create(self.cli1_dir, self.setting.server_url, self.setting.user, self.setting.password, self.enc_repo) def sync_cli1(self): seaf_op.seaf_sync(self.cli1_dir, self.setting.server_url, self.repo_id, self.worktree1, self.setting.user, self.setting.password) def sync_cli2(self): seaf_op.seaf_sync(self.cli2_dir, self.setting.server_url, self.repo_id, self.worktree2, self.setting.user, self.setting.password) def sync_repo(self): self.sync_cli1() self.sync_cli2() def desync_cli1(self): seaf_op.seaf_desync(self.cli1_dir, self.worktree1) def desync_cli2(self): seaf_op.seaf_desync(self.cli2_dir, self.worktree2) def desync_repo(self): self.desync_cli1() self.desync_cli2() # delete test repo seaf_op.seaf_delete(self.cli1_dir, self.setting.server_url, self.setting.user, self.setting.password, self.repo_id) def stop_daemon(self): seaf_op.seaf_stop(self.cli1_dir) seaf_op.seaf_stop(self.cli2_dir) def clean(self): try: if os.name != 'nt': TestUtil.clean_sync_data(self.cli1_dir) TestUtil.clean_sync_data(self.cli2_dir) shutil.rmtree(self.worktree1) shutil.rmtree(self.worktree2) except Exception: pass def wait_sync(self): while True: time.sleep(5) repo1 = seaf_op.seaf_get_repo(self.cli1_dir, self.repo_id) if repo1 is None: continue repo2 = seaf_op.seaf_get_repo(self.cli2_dir, self.repo_id) if repo2 is None: continue if repo1.head_cmmt_id == repo2.head_cmmt_id: break @staticmethod def verify_by_rsync(dir1, dir2): ret = call_process(['rsync', '-acrin', dir1, dir2]) if ret: for d in ret.split('\n'): # omit empty str if not d: continue # omit directory has almost same result except st_mod items = d.split(' ') dattr = items[0] name = items[1] # Output format difference between rsync versions: # rsync 3.1.1 : '.d..t.......' # rsync 3.0.9 : '.d..t......' # On Windows, file timestamp may have 1 second difference # between two clients after sync. That's caused by the # precision lose when converting Windows timestamp to # Unix timestamp. So we don't check timestamp difference # for files either. if not all([c in ('f', 'd', 't', '.') for c in dattr]): assert False, 'Sync with two client have different result: %s %s' % (dattr, name) def verify_result(self, callable=None): self.wait_sync() if callable: callable(self.worktree1, self.worktree2) else: dir1 = './worktree1/' dir2 = './worktree2/' TestUtil.verify_by_rsync(dir1, dir2) TestUtil.verify_by_rsync(dir2, dir1) # worktree: 1(worktree1), 2(worktree2) def mkdir(self, worktree, path): if worktree == 1: os.makedirs(os.path.join(self.worktree1, self.test_root, path)) elif worktree == 2: os.makedirs(os.path.join(self.worktree2, self.test_root, path)) def rmdir(self, worktree, path): if worktree == 1: shutil.rmtree(os.path.join(self.worktree1, self.test_root, path)) elif worktree == 2: shutil.rmtree(os.path.join(self.worktree2, self.test_root, path)) def mkfile(self, worktree, fpath, con=''): if worktree == 1: pdir = self.worktree1 elif worktree == 2: pdir = self.worktree2 else: return abs_path = os.path.join(pdir, self.test_root, fpath) dirname = os.path.dirname(abs_path) if not os.path.exists(dirname): os.makedirs(dirname) with open(abs_path, 'w') as fd: fd.write(con) def rmfile(self, worktree, fpath): if worktree == 1: os.remove(os.path.join(self.worktree1, self.test_root, fpath)) elif worktree == 2: os.remove(os.path.join(self.worktree2, self.test_root, fpath)) def modfile(self, worktree, fpath, con=''): if worktree == 1: pdir = self.worktree1 elif worktree == 2: pdir = self.worktree2 else: return abs_path = os.path.join(pdir, self.test_root, fpath) with open(abs_path, 'a') as fd: fd.write(con) def move(self, worktree, org_path, dest_path): if worktree == 1: shutil.move(os.path.join(self.worktree1, self.test_root, org_path), os.path.join(self.worktree1, self.test_root, dest_path)) elif worktree == 2: shutil.move(os.path.join(self.worktree2, self.test_root, org_path), os.path.join(self.worktree2, self.test_root, dest_path)) def batchmove(self, worktree, regex, dest_path): if worktree == 1: pdir = self.worktree1 elif worktree == 2: pdir = self.worktree2 else: return files = glob.glob(os.path.join(pdir, self.test_root, regex)) dest = os.path.join(pdir, self.test_root, dest_path) for f in files: shutil.move(f, dest) def copy(self, worktree, org_path, dest_path): if worktree == 1: shutil.copytree(os.path.join(self.worktree1, self.test_root, org_path), os.path.join(self.worktree1, self.test_root, dest_path)) elif worktree == 2: shutil.copytree(os.path.join(self.worktree2, self.test_root, org_path), os.path.join(self.worktree2, self.test_root, dest_path)) def touch(self, worktree, path, time=None): if worktree == 1: os.utime(os.path.join(self.worktree1, self.test_root, path), time) if worktree == 2: os.utime(os.path.join(self.worktree2, self.test_root, path), time) def getpath(self, worktree, path): if worktree == 1: return os.path.join(self.worktree1, self.test_root, path) elif worktree == 2: return os.path.join(self.worktree2, self.test_root, path) raise Exception('Invalid worktree') seafile-6.1.5/updateversion.sh000077500000000000000000000011341323477647300164010ustar00rootroot00000000000000#! /bin/sh if [ $# != "2" ]; then echo "$0 " exit fi old_ver=$1 new_ver=$2 if test "$(uname)" = "Darwin"; then sed -i '' -e "s|$old_ver|$new_ver|" web/setup_mac.py sed -i '' -e "s|VERSION=$old_ver|VERSION=$new_ver|" setupmac.sh sed -i '' -e "s|$old_ver|$new_ver|" gui/mac/seafile/seafile/*.plist else sed -i "s|$old_ver|$new_ver|" web/setup_mac.py sed -i "s|VERSION=$old_ver|VERSION=$new_ver|" setupmac.sh sed -i "s|$old_ver|$new_ver|" gui/mac/seafile/seafile/*.plist fi