diff --git a/Cargo.toml b/Cargo.toml index 1d38d1c..6127547 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,16 +10,6 @@ crossterm = "0.29" regex = "1.11" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.141" -serde_yaml = "0.9" notify = "8.1.0" get_if_addrs = "0.5" -actix-web = "4" -actix-files = "0.6" -tokio = { version = "1", features = ["full"] } -clap = { version = "4.4", features = ["derive"] } -log = { version = "0.4", features = ["std"] } -daemonize = "0.5.0" -num-rational = "0.4" -num-traits = "0.2" - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f288702..0000000 --- a/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. 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 -them 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 prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. 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. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey 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; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - 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. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -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. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - 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 -state 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program 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, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU 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. But first, please read -. diff --git a/README.md b/README.md index 5f94e52..beea897 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,14 @@ -ο»Ώ# Fetch | Hachi (alpha) +ο»Ώ# πŸ•°οΈ NTP Timeturner (alpha) -**An LTC-driven NTP server for Raspberry Pi, built with broadcast precision** +**An LTC-driven NTP server for Raspberry Pi, built with broadcast precision and a hint of magic.** -Hachi synchronises timecode-locked systems by decoding incoming LTC (Linear Time Code) and broadcasting it as NTP/PTP β€” with the dedication our namesake would insist upon. - -Created by Chris Frankland-Wright and Chaos Rogers +Inspired by the TimeTurner in the Harry Potter series, this project synchronises timecode-locked systems by decoding incoming LTC (Linear Time Code) and broadcasting it as NTP β€” with precision as Hermione would insist upon. --- ## πŸ“¦ Hardware Requirements -- Raspberry Pi 5 2GB (Dev Platform) but should be supported by Pi v3 (or better) +- Raspberry Pi 5 (Dev Platform) but should be supported by Pi v3 (or better) - Debian Bookworm (64-bit recommended) - Teensy 4.0 - https://thepihut.com/products/teensy-4-0-headers - Audio Adapter Board for Teensy 4.0 (Rev D) - https://thepihut.com/products/audio-adapter-board-for-teensy-4-0 @@ -24,103 +22,27 @@ Created by Chris Frankland-Wright and Chaos Rogers - Reads SMPTE LTC from Audio Interface (3.5mm TRS but adaptable to BNC/XLR) - Converts LTC into NTP-synced time - Broadcasts time via local NTP server -- Supports configurable time offsets (hours, minutes, seconds, frames or milliseconds) +- Supports configurable time offsets (hours, minutes, seconds, milliseconds) - Systemd service support for headless operation -- Web-based UI for monitoring and control when running as a daemon +- Optional splash screen branding at boot --- -## πŸ–₯️ Web Interface & API +## πŸš€ Installation (to update) -When running as a background daemon, Hachi provides a web interface for monitoring and configuration. -- **Access**: The web UI is available at `http://:8080`. -- **Functionality**: You can view the real-time sync status, see logs, and change all configuration options directly from your browser. -- **API**: A JSON API is also exposed for programmatic access. See `docs/api.md` for full details. - ---- - -## πŸ› οΈ Known Issues - -- Supported Frame Rates: 24/25fps -- Non Supported Frame Rates: 23.98/30/59.94/60 -- Fractional framerates have drift or wrong wall clock sync issues - ---- - -## πŸš€ Installation - -The `setup.sh` script compiles and installs the Hachi application. You can run it by cloning the repository with `git` or by using the `curl` command below for a git-free installation. - -### Prerequisites - -- **Internet Connection**: To download dependencies. -- **Curl and Unzip**: The script requires `curl` to download files and `unzip` for the git-free method. The setup script will attempt to install these if they are missing. - -### Running the Installer (Recommended) - -This command downloads the latest version, unpacks it, and runs the setup script. Paste it into your Raspberry Pi terminal: +For Rust install you can do +```bash +cargo install --git https://github.com/cjfranko/NTP-Timeturner +``` +Clone and run the installer: ```bash -curl -L https://github.com/cjfranko/NTP-Timeturner/archive/refs/heads/main.zip -o NTP-Timeturner.zip && \ -unzip NTP-Timeturner.zip && \ -cd NTP-Timeturner-main && \ -chmod +x setup.sh && \ +wget https://raw.githubusercontent.com/cjfranko/NTP-Timeturner/master/setup.sh +chmod +x setup.sh ./setup.sh ``` -### What the Script Does - -The installation script automates the following steps: - -1. **Installs Dependencies**: Installs `git`, `curl`, `unzip`, and necessary build tools. -2. **Compiles the Binary**: Runs `cargo build --release` to create an optimised executable. -3. **Creates Directories**: Creates `/opt/timeturner` to store the application files. -4. **Installs Files**: - - The compiled binary is copied to `/opt/timeturner/timeturner`. - - The web interface assets from the `static/` directory are copied to `/opt/timeturner/static`. - - A symbolic link is created from `/usr/local/bin/timeturner` to the binary, allowing it to be run from any location. -5. **Sets up Systemd Service**: - - Copies the `timeturner.service` file to `/etc/systemd/system/`. - - Enables the service to start automatically on system boot. - -After installation is complete, the script will provide instructions to start the service manually or to run the application in its interactive terminal mode. - -```bash -The working directory is /opt/timeturner. -Default 'config.yml' installed to /opt/timeturner. - -To start the service, run: - sudo systemctl start timeturner.service - -To view live logs, run: - journalctl -u timeturner.service -f - -To run the interactive TUI instead, simply run from the project directory: - cargo run -Or from anywhere after installation: - timeturner -``` - ---- - -## πŸ”„ Updating - -If you installed Hachi by cloning the repository with `git`, you can use the `update.sh` script to easily update to the latest version. - -**Note**: This script will not work if you used the `curl` one-line command for installation, as that method does not create a Git repository. - -To run the update script, navigate to the `NTP-Timeturner-main` directory and run: -```bash -chmod +x update.sh && ./update.sh -``` - -The update script automates the following: -1. Pulls the latest code from the `main` branch on GitHub. -2. Rebuilds the application binary. -3. Copies the new binary to `/opt/timeturner/`. -4. Restarts the `timeturner` service to apply the changes. - --- ## πŸ•°οΈ Chrony NTP ```bash @@ -129,10 +51,10 @@ chronyc tracking | NTP Tracking sudo nano /etc/chrony/chrony.conf | Default Chrony Conf File Add to top: -# Serve the system clock as a reference at stratumβ€―1 +# Serve the system clock as a reference at stratumβ€―10 server 127.127.1.0 allow 127.0.0.0/8 -local stratum 1 +local stratum 10 Add to bottom: # Allow LAN clients diff --git a/SECURITY.MD b/SECURITY.MD deleted file mode 100644 index 14b8058..0000000 --- a/SECURITY.MD +++ /dev/null @@ -1,9 +0,0 @@ -Reporting Security Issues - -The TimeTurner team and community take security bugs in TimeTurner seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. - -To report a security issue, please use the GitHub Security Advisory "Report a Vulnerability" tab. - -The TimeTurner team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. - -Report security bugs in third-party modules to the person or team maintaining the module. diff --git a/config.json b/config.json new file mode 100644 index 0000000..5ba71c3 --- /dev/null +++ b/config.json @@ -0,0 +1,3 @@ +{ + "hardware_offset_ms": 20 +} diff --git a/config.yml b/config.yml deleted file mode 100644 index bc552ee..0000000 --- a/config.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Hardware offset in milliseconds for correcting capture latency. -hardwareOffsetMs: 55 - -# Enable automatic clock synchronization. -# When enabled, the system will perform an initial full sync, then periodically -# nudge the clock to keep it aligned with the LTC source. -autoSyncEnabled: true - -# Default nudge in milliseconds for adjtimex control. -defaultNudgeMs: 2 - -# Time-turning offsets. All values are added to the incoming LTC time. -# These can be positive or negative. -timeturnerOffset: - hours: 0 - minutes: 0 - seconds: 0 - frames: 0 - milliseconds: 0 diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index 6657028..0000000 --- a/docs/api.md +++ /dev/null @@ -1,196 +0,0 @@ -# NTP Timeturner API - -This document describes the HTTP API for the NTP Timeturner application. - -## Endpoints - -### Status and Logs - -- **`GET /api/status`** - - Retrieves the real-time status of the LTC reader and system clock synchronization. The `ltc_timecode` field uses `:` as a separator for non-drop-frame timecode, and `;` for drop-frame timecode between seconds and frames (e.g., `10:20:30;00`). - - **Possible values for status fields:** - - `ltc_status`: `"LOCK"`, `"FREE"`, or `"(waiting)"` - - `sync_status`: `"IN SYNC"`, `"CLOCK AHEAD"`, `"CLOCK BEHIND"`, `"TIMETURNING"` - - `jitter_status`: `"GOOD"`, `"AVERAGE"`, `"BAD"` - - **Example Response:** - ```json - { - "ltc_status": "LOCK", - "ltc_timecode": "10:20:30;00", - "frame_rate": "25.00fps", - "system_clock": "10:20:30.005", - "system_date": "2025-07-30", - "timecode_delta_ms": 5, - "timecode_delta_frames": 0, - "sync_status": "IN SYNC", - "jitter_status": "GOOD", - "lock_ratio": 99.5, - "ntp_active": true, - "interfaces": ["192.168.1.100"], - "hardware_offset_ms": 20 - } - ``` - -- **`GET /api/logs`** - - Retrieves the last 100 log entries from the application. - - **Example Response:** - ```json - [ - "2025-08-07 10:00:00 [INFO] Starting TimeTurner daemon...", - "2025-08-07 10:00:01 [INFO] Found serial port: /dev/ttyACM0" - ] - ``` - -### System Clock Control - -- **`POST /api/sync`** - - Triggers a manual synchronization of the system clock to the current LTC timecode. This requires the application to have `sudo` privileges to execute the `date` command. - - **Request Body:** None - - **Success Response (200 OK):** - ```json - { - "status": "success", - "message": "Sync command issued." - } - ``` - - **Error Response (400 Bad Request):** - ```json - { - "status": "error", - "message": "No LTC timecode available to sync to." - } - ``` - **Error Response (500 Internal Server Error):** - ```json - { - "status": "error", - "message": "Sync command failed." - } - ``` - -- **`POST /api/nudge_clock`** - - Nudges the system clock by a specified number of microseconds. This requires `sudo` privileges to run `adjtimex`. - - **Example Request:** - ```json - { - "microseconds": -2000 - } - ``` - **Success Response (200 OK):** - ```json - { - "status": "success", - "message": "Clock nudge command issued." - } - ``` - **Error Response (500 Internal Server Error):** - ```json - { - "status": "error", - "message": "Clock nudge command failed." - } - ``` - - -- **`POST /api/set_date`** - - Sets the system date. This is useful as LTC does not contain date information. Requires `sudo` privileges. - - **Example Request:** - ```json - { - "date": "2025-07-30" - } - ``` - - **Success Response (200 OK):** - ```json - { - "status": "success", - "message": "Date update command issued." - } - ``` - - **Error Response (500 Internal Server Error):** - ```json - { - "status": "error", - "message": "Date update command failed." - } - ``` - -### Configuration - -- **`GET /api/config`** - - Retrieves the current application configuration from `config.yml`. - - **Example Response (200 OK):** - ```json - { - "hardwareOffsetMs": 20, - "timeturnerOffset": { - "hours": 0, - "minutes": 0, - "seconds": 0, - "frames": 0, - "milliseconds": 0 - }, - "defaultNudgeMs": 2, - "autoSyncEnabled": false - } - ``` - -- **`POST /api/config`** - - Updates the application configuration. The new configuration is persisted to `config.yml` and takes effect immediately. - - **Example Request:** - ```json - { - "hardwareOffsetMs": 55, - "timeturnerOffset": { - "hours": 1, - "minutes": 2, - "seconds": 3, - "frames": 4, - "milliseconds": 5 - }, - "defaultNudgeMs": 2, - "autoSyncEnabled": true - } - ``` - - **Success Response (200 OK):** (Returns the updated configuration) - ```json - { - "hardwareOffsetMs": 55, - "timeturnerOffset": { - "hours": 1, - "minutes": 2, - "seconds": 3, - "frames": 4, - "milliseconds": 5 - }, - "defaultNudgeMs": 2, - "autoSyncEnabled": true - } - ``` - **Error Response (500 Internal Server Error):** - ```json - { - "status": "error", - "message": "Failed to write config.yml" - } - ``` diff --git a/firmware/ltc_audiohat_lock.ino b/firmware/ltc_audiohat_lock.ino deleted file mode 100644 index 4218dd9..0000000 --- a/firmware/ltc_audiohat_lock.ino +++ /dev/null @@ -1,180 +0,0 @@ -/* Linear Timecode for Audio Library for Teensy 3.x / 4.x - Copyright (c) 2019, Frank BΓΆsing, f.boesing (at) gmx.de - - Development of this audio library was funded by PJRC.COM, LLC by sales of - Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop - open source software by purchasing Teensy or other PJRC products. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice, development funding notice, and this permission - notice shall be included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* - - https://forum.pjrc.com/threads/41584-Audio-Library-for-Linear-Timecode-(LTC) - - LTC example audio at: https://www.youtube.com/watch?v=uzje8fDyrgg - - Adapted by Chris Frankland-Wright 2025 for Teensy Audio Shield Input with autodetect FPS for the NTP-TimeTurner Project - -*/ - -#include -#include -#include "analyze_ltc.h" - -// β€”β€” Configuration β€”β€” -// 0.0 β†’ auto-detect; or force 24.0, 25.0, 29.97 -const float FORCE_FPS = 0.0f; -// frame-delay compensation (in frames) -const int FRAME_OFFSET = 4; -// how many frame-periods to wait before declaring β€œlost” -const float LOSS_THRESHOLD_FRAMES = 1.5f; -// Blink periods (ms) for NO_LTC, ACTIVE, LOST -const unsigned long BLINK_PERIOD[3] = { 2000, 100, 500 }; - -AudioInputI2S i2s1; -AudioAnalyzeLTC ltc1; -AudioControlSGTL5000 sgtl5000; -AudioConnection patchCord(i2s1, 0, ltc1, 0); - -enum State { NO_LTC = 0, LTC_ACTIVE, LTC_LOST }; -State ltcState = NO_LTC; -bool ledOn = false; -unsigned long lastDecode = 0; -unsigned long lastBlink = 0; - -// auto-detect vars -float currentFps = 25.0f; -float periodMs = 0; -const float SMOOTH_ALPHA = 0.1f; -unsigned long lastDetectTs = 0; - -// free-run tracking -long freeAbsFrame = 0; -unsigned long lastFreeRun = 0; - -void setup() { - Serial.begin(115200); - // while (!Serial); - AudioMemory(12); - sgtl5000.enable(); - sgtl5000.inputSelect(AUDIO_INPUT_LINEIN); - pinMode(LED_BUILTIN, OUTPUT); -} - -void loop() { - unsigned long now = millis(); - // compute dynamic framePeriod (ms) from last known fps - unsigned long framePeriod = (unsigned long)(1000.0f/currentFps + 0.5f); - - if (ltc1.available()) { - // β€”β€” LOCKED β€”β€” read a frame - ltcframe_t frame = ltc1.read(); - int h = ltc1.hour(&frame), - m = ltc1.minute(&frame), - s = ltc1.second(&frame), - f = ltc1.frame(&frame); - - // β€”β€” FPS detect or force β€”β€” - if (FORCE_FPS > 0.0f) { - currentFps = FORCE_FPS; - } else { - if (lastDetectTs) { - float dt = now - lastDetectTs; - periodMs = periodMs==0 ? dt : (SMOOTH_ALPHA*dt + (1-SMOOTH_ALPHA)*periodMs); - float measured = 1000.0f/periodMs; - const float choices[3] = {24.0f,25.0f,29.97f}; - float bestD=1e6, pick=25.0f; - for (auto c: choices) { - float d = fabs(measured - c); - if (d < bestD) { bestD = d; pick = c; } - } - currentFps = pick; - } - lastDetectTs = now; - } - - // β€”β€” pack + offset + wrap β€”β€” - int nominal = (currentFps>29.5f)?30:int(currentFps+0.5f); - long dayFrames = 24L*3600L*nominal; - long absF = ((long)h*3600 + m*60 + s)*nominal + f + FRAME_OFFSET; - absF = (absF % dayFrames + dayFrames) % dayFrames; - - // save for free-run - freeAbsFrame = absF; - lastFreeRun = now; - - // unpack for display - long totSec = absF/nominal; - int outF = absF % nominal; - int outS = totSec % 60; - long totMin = totSec/60; - int outM = totMin % 60; - int outH = (totMin/60)%24; - - // dynamic drop-frame from bit 10 - bool isDF = ltc1.bit10(&frame); - char sep = isDF ? ';' : ':'; - - // print locked - Serial.printf("[LOCK] %02d:%02d:%02d%c%02d | %.2ffps\r\n", - outH,outM,outS,sep,outF,currentFps); - - // update state - ltcState = LTC_ACTIVE; - lastDecode = now; - } - else { - // β€”β€” NOT LOCKED β€”β€” check if we should switch to free-run - if (ltcState == LTC_ACTIVE) { - // only switch after losing more than LOSS_THRESHOLD_FRAMES - float elapsedFrames = float(now - lastDecode) / float(framePeriod); - if (elapsedFrames >= LOSS_THRESHOLD_FRAMES) { - ltcState = LTC_LOST; - // free-run will begin below - } - } - } - - // β€”β€” FREE-RUN β€”β€” when lost - if (ltcState == LTC_LOST) { - if ((now - lastFreeRun) >= framePeriod) { - freeAbsFrame = (freeAbsFrame + 1) % (24L*3600L*(int)(currentFps+0.5f)); - lastFreeRun += framePeriod; - - long totSec = freeAbsFrame/((int)(currentFps+0.5f)); - int outF = freeAbsFrame % (int)(currentFps+0.5f); - int outS = totSec % 60; - long totMin = totSec/60; - int outM = totMin % 60; - int outH = (totMin/60)%24; - - Serial.printf("[FREE] %02d:%02d:%02d:%02d | %.2ffps\r\n", - outH,outM,outS,outF,currentFps); - } - } - - // β€”β€” LED heartbeat β€”β€” non-blocking - unsigned long period = BLINK_PERIOD[ltcState]; - if (now - lastBlink >= period/2) { - ledOn = !ledOn; - digitalWrite(LED_BUILTIN, ledOn); - lastBlink = now; - } -} diff --git a/firmware/ltc_audiohat_lock.ino_v2.hex b/firmware/ltc_audiohat_lock.ino_v2.hex deleted file mode 100644 index 2b636bd..0000000 --- a/firmware/ltc_audiohat_lock.ino_v2.hex +++ /dev/null @@ -1,5895 +0,0 @@ -:0200000460009A -:100000004643464200000156000000000103030081 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000000000000000000000000000000C0 -:1000400000000000010408000000000000000000A3 -:100050000000200000000000000000000000000080 -:100060000000000000000000000000000000000090 -:100070000000000000000000000000000000000080 -:10008000EB04180A063204260000000000000000FD -:10009000050404240000000000000000000000002F -:1000A0000000000000000000000000000000000050 -:1000B0000604000000000000000000000000000036 -:1000C0000000000000000000000000000000000030 -:1000D00020041808000000000000000000000000DC -:1000E0000000000000000000000000000000000010 -:1000F0000000000000000000000000000000000000 -:10010000D8041808000000000000000000000000F3 -:100110000204180804200000000000000000000095 -:1001200000000000000000000000000000000000CF -:10013000600400000000000000000000000000005B -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000000000000000000000000000008F -:10017000000000000000000000000000000000007F -:10018000000000000000000000000000000000006F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000100000010000001000000000000001D -:1001D000000001000000000000000000000000001E -:1001E000000000000000000000000000000000000F -:1001F00000000000000000000000000000000000FF -:10020000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -:10021000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE -:10022000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE -:10023000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE -:10024000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE -:10025000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE -:10026000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E -:10027000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E -:10028000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E -:10029000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E -:1002A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E -:1002B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E -:1002C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E -:1002D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E -:1002E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E -:1002F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E -:10030000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD -:10031000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED -:10032000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD -:10033000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:10035000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD -:10036000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D -:10037000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D -:10038000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D -:10039000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D -:1003A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D -:1003B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D -:1003C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D -:1003D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D -:1003E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D -:1003F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D -:10040000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC -:10041000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC -:10042000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC -:10043000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC -:10044000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC -:10045000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC -:10046000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C -:10047000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C -:10048000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C -:10049000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C -:1004A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C -:1004B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C -:1004C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C -:1004D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C -:1004E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C -:1004F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C -:10050000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB -:10051000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB -:10052000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB -:10053000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB -:10054000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB -:10055000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB -:10056000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B -:10057000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B -:10058000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B -:10059000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B -:1005A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B -:1005B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B -:1005C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B -:1005D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B -:1005E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1B -:1005F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B -:10060000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA -:10061000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA -:10062000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA -:10063000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA -:10064000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA -:10065000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA -:10066000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A -:10067000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8A -:10068000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A -:10069000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A -:1006A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A -:1006B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4A -:1006C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3A -:1006D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2A -:1006E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1A -:1006F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0A -:10070000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 -:10071000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9 -:10072000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 -:10073000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 -:10074000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 -:10075000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9 -:10076000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 -:10077000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89 -:10078000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79 -:10079000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF69 -:1007A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59 -:1007B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF49 -:1007C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF39 -:1007D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29 -:1007E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 -:1007F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 -:10080000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 -:10081000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8 -:10082000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8 -:10083000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8 -:10084000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8 -:10085000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 -:10086000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF98 -:10087000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 -:10088000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78 -:10089000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 -:1008A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 -:1008B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48 -:1008C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38 -:1008D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28 -:1008E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18 -:1008F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08 -:10090000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 -:10091000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 -:10092000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 -:10093000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 -:10094000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 -:10095000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 -:10096000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 -:10097000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 -:10098000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 -:10099000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 -:1009A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 -:1009B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 -:1009C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 -:1009D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 -:1009E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 -:1009F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 -:100A0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 -:100A1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 -:100A2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6 -:100A3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6 -:100A4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6 -:100A5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6 -:100A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96 -:100A7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF86 -:100A8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76 -:100A9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 -:100AA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56 -:100AB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF46 -:100AC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF36 -:100AD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF26 -:100AE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16 -:100AF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF06 -:100B0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -:100B1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -:100B2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 -:100B3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 -:100B4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5 -:100B5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5 -:100B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF95 -:100B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF85 -:100B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 -:100B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF65 -:100BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55 -:100BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45 -:100BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35 -:100BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 -:100BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 -:100BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 -:100C0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4 -:100C1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 -:100C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4 -:100C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4 -:100C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4 -:100C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4 -:100C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 -:100C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 -:100C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 -:100C9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 -:100CA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 -:100CB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 -:100CC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 -:100CD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24 -:100CE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF14 -:100CF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF04 -:100D0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3 -:100D1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3 -:100D2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3 -:100D3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3 -:100D4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3 -:100D5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3 -:100D6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF93 -:100D7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF83 -:100D8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF73 -:100D9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF63 -:100DA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF53 -:100DB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF43 -:100DC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF33 -:100DD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF23 -:100DE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF13 -:100DF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF03 -:100E0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:100E1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:100E2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:100E3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:100E4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 -:100E5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 -:100E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 -:100E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF82 -:100E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72 -:100E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF62 -:100EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 -:100EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 -:100EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 -:100ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:100EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:100EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:100F0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 -:100F1000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 -:100F2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 -:100F3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 -:100F4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 -:100F5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1 -:100F6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 -:100F7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 -:100F8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 -:100F9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 -:100FA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 -:100FB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 -:100FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 -:100FD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 -:100FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 -:100FF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 -:10100000D1002043491600600000000000000000ED -:10101000201000600010006000640160000000000B -:10102000000000600070010000000000FFFFFFFFF3 -:10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 -:10104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 -:10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 -:10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 -:10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 -:10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 -:10109000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 -:1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 -:1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 -:1010C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 -:1010D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 -:1010E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 -:1010F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 -:10110000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF -:10111000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF -:10112000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF -:10113000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF -:10114000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF -:10115000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F -:10116000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F -:10117000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F -:10118000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F -:10119000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F -:1011A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F -:1011B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F -:1011C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F -:1011D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F -:1011E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F -:1011F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -:10120000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE -:10121000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE -:10122000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE -:10123000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBE -:10124000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAE -:10125000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E -:10126000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E -:10127000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E -:10128000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E -:10129000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E -:1012A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E -:1012B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3E -:1012C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E -:1012D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E -:1012E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0E -:1012F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE -:10130000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED -:10131000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD -:10132000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD -:10133000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:10134000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD -:10135000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D -:10136000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D -:10137000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D -:10138000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6D -:10139000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D -:1013A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4D -:1013B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3D -:1013C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2D -:1013D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1D -:1013E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D -:1013F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD -:10140000814205D051F8043B40F8043B8242F9D8B0 -:10141000704700BF044A05494FF0000342F8043BFF -:101420009142FBD8704700BFC01E0020402C002016 -:101430002DE98848BFF34F8F00BF00BF00BF00BF3A -:1014400000F07AFA674B0822C3F8542100BF00BFAE -:1014500000BF00BF00BF00BF00BF00BF00BF00BF94 -:1014600000BF00BF00BF00BF00BF00BF5E4A5F49B2 -:101470005F48FFF7C5FF5F4A5F496048FFF7C0FF5D -:101480005F4CFFF7C7FF4FF470004FF0E0210023DF -:101490005C4AC1F8880D44F823200133B02BFAD1FF -:1014A000594B8021594A03F8011B9342FBD14FF05D -:1014B000E0254C4E4FF08039DFF880B1DFF880A195 -:1014C0004FF0FF31C5F8084D0027C6F80491C6F863 -:1014D00000B1C6F8F490C6F8F0A0D5F8243DDFF8C6 -:1014E000648143F4E0234A4AC5F8243DD8F81C300F -:1014F00023F07F0343F04003C8F81C30D8F82430B1 -:1015000023F07F0343F04003C8F824309166D1668E -:101510001167516700F018FA3E4B3F49A3633F4BF8 -:10152000E36363236B610323AF612B613C4BC5F81D -:10153000203DD5F8FC3D43F08073C5F8FC3D394BA8 -:101540001A6842F001021A605B680B6000F084FACE -:10155000C6F804913448C6F800B1C6F8F490C6F84D -:10156000F0A000F019FCD8F86C10304B304A41F470 -:101570004051C8F86C101F60C3F80871C3F81871A7 -:10158000C3F82871C3F83871936BDB0708D442F6AF -:101590001563284951651365936B43F00103936309 -:1015A000234A254C936843F00113936000F0B8FB85 -:1015B00000F0E6FB00F07EFA00F0C0F92368132B80 -:1015C000FCD900F00FFB2368B3F5967FFBD300F046 -:1015D000B9F900F0B5F900F0F3FB00F0E1FB30BF22 -:1015E000FDE700BF00800D4048230100402000605F -:1015F00000000000C01E00208C430160000000209D -:10160000001C002015AB000000E400E0A0E400E0B6 -:1016100000C00A4065A00000C02B002069A00000A7 -:1016200000002020001000E00046C32300400840D6 -:1016300000400D400000C056C42B00201B10182095 -:101640000C0D111300C00F40054B4FF42A01054A41 -:1016500005485A641864054A99639546FFF7E8FE01 -:1016600000C00A40BFAAAAAA0700200000800620E6 -:101670001BB9124B1B6F9B041ED400F03F000F4B95 -:1016800022F0604221F0604140F489101867C3F8ED -:101690008010C3F890201A6F22F480521A671A6FD4 -:1016A000002AFCDAD3F87011054A0A40C3F8702109 -:1016B0001A6F22F480321A67704700BF00800D4015 -:1016C000FF7F7FFF43690A4A03EB011010B4037ADE -:1016D000084C02EB0313D3E901321460C2681A60AC -:1016E00003690BB142691A605DF8044B704700BF93 -:1016F000E40B002061F801004369027E03EB021253 -:1017000092F808C08C451CD01A7AFF2A19D0914251 -:1017100010B5044616D01A7EFF2A06D00121D3E95F -:10172000002312681A4201D1217610BD064B052212 -:10173000204603EB0C135B681A60FFF7C3FF2176AA -:10174000F3E770470021EAE7E40B002043690A4A07 -:1017500003EB011010B490F82830084C02EB03138F -:10176000D3E901321460C26A1A60036B0BB1426B99 -:101770001A605DF8044B7047E40B002061F801002B -:101780004369427E03EB021292F828C08C451ED0BA -:1017900093F82820FF2A1AD0914210B5044617D09A -:1017A00093F83820FF2A06D00121D3E900231268DC -:1017B0001A4201D1617610BD064B0522204603EB8B -:1017C0000C135B681A60FFF7C1FF6176F3E770479F -:1017D0000021EAE7E40B0020164942698B6B23F4F1 -:1017E0007C0343F4802370B58B630446124DD2E929 -:1017F00000130A681A4303690A60022200211A6171 -:101800000E4A19619A6401225A629D624FF4303582 -:10181000DD624FF001159E6C1E6519629D651A61AF -:10182000017EFFF74FFF617E2046BDE87040FFF765 -:101830008DBF00BF00C00F40B80B05053B3728190E -:10184000B1F5607FF0B50E468DB028BF4FF46076DD -:101850000F46054672B62E4B0024702218602146B2 -:101860002C4B2D481C8000F0AFFACFB121462A48FE -:101870004FF0010C4A0901F01F03013150F82240DA -:101880000CFA03F38E4243EA040340F82230F1D805 -:10189000284600234380013300F582709E42F9D828 -:1018A0001E4C257815B162B60DB0F0BD082000F0D1 -:1018B0006FFA1B4B80220646009302A90693194B30 -:1018C0000271056008A8029300F06EFA06A9164A94 -:1018D000304600F06DFA069B08A8DB689847009B2D -:1018E00002A8DB6898472378002BDCD10F4B104A05 -:1018F000C3F858210F49D0204FF0E023402281F84F -:101900004600C3F808210123237062B60DB0F0BD74 -:1019100040260020E82B002048260020F92B00203C -:1019200040090020BD9A00001B100100001C00208F -:10193000C99A000000E400E0704700BF704700BF94 -:10194000704700BF00BF704710B44FF0E023002184 -:1019500010243148C3F8941DC3F89C4D1124C3F8DA -:10196000A00D2E48C3F89C4D1224C3F8A00D2C489E -:10197000C3F89C4D2B4AC3F8A00D2B4C42F0150226 -:101980002A48C3F89C4DC3F8A00D294C2948C3F838 -:101990009C4DC3F8A00D284CC3F89C2D2748284A1D -:1019A000C3F8A04DC3F89C0DC3F8A02D02F5A022EA -:1019B000244C0C322448C3F89C4DC3F8A02D234A74 -:1019C000C3F89C0D224CC3F8A02D02F14062C3F86D -:1019D0009C4D2048C3F8A02D0C32C3F89C0DC3F8D1 -:1019E000A02D00BF00BF00BF00BF00BF0122C3F891 -:1019F000942DBFF34F8FBFF36F8FC3F8501FBFF30A -:101A00004F8FBFF36F8FD3F8142D5DF8044B42F462 -:101A10004032C3F8142D70473F000010250008071E -:101A200009001000402C00201300200021000207B4 -:101A300014000020250008130900001016002020C3 -:101A400027000B1317000040180000602F000B0741 -:101A5000190000701A000080F0B4154A40274FF4B6 -:101A600080314FF480564FF400554FF4404443F218 -:101A70004200136913F0020F0ED113F4005F0FD070 -:101A800013F4805F0ED0002BF3DA13F4803F0BD1F8 -:101A90005B060BD5F0BC7047946151619061E8E73B -:101AA0005561E6E75661E4E79161E2E75761E0E7F7 -:101AB00000800D403F4A03203F49F3EE095AD2F817 -:101AC00080304FF0000C9FED3D6A23F001039FED45 -:101AD0003C5A30B4C2F88030C2F89000D1F8E0101F -:101AE000384DCBB2384C39482B6007EE903A0B0D8D -:101AF000C1F30B21F8EEE77A06EE903A07EE101AE2 -:101B0000334BB8EEC77A2160F8EEE66A314937EE1A -:101B1000C66A37EEC55A76EEC76A77EEE57A26EEE4 -:101B2000266AC3ED006A25EE265AD2F8803067EEA9 -:101B3000A64AC0ED007AC6EE275A274885EE276AE6 -:101B4000C4EEA76A75EE875AFCEEE55A36EE076AD0 -:101B500015EE904ABCEEC66A43EA045376EE877AE5 -:101B6000C2F8803016EE103AD2F89041FCEEE77AD7 -:101B700001EA0341214317EE903AC2F89011C3F3F2 -:101B80000B03D2F890110B431449C2F89031D2F8EC -:101B9000803043F00203C2F88030114B80F840C01F -:101BA000C1F840314FF0E023012230BCC3F80821D6 -:101BB000704700BF00810D4000441F400000AA4252 -:101BC0000000B442A42B0020A02B0020A82B002052 -:101BD000AC2B00200000FF0F00E400E0001C002000 -:101BE00001AD0000314B40F6617210B5C3F8202101 -:101BF00040F2044400F0E0F82D4A2E49D2F880303B -:101C00002D4843F00303C2F880302C4BC1F86041EB -:101C100002681A4203D1D1F8A8319A071BD0254A8D -:101C20004FF00041244B5963D2F8403143F0020396 -:101C3000C2F84031D2F840319B07FBD44FF400305A -:101C40004FF0E0211C4B4FF00042C1F88C021920EC -:101C50009A6300F099F8184A4FF08040154C002123 -:101C600090630A20164B11604FF42072C4F8A8014B -:101C7000184600F0A9F84FF4800203464FF48100A3 -:101C800040F243111860C4F858311A640D4B0E4AE3 -:101C9000C4F84811C3F804224FF0E0224FF4003199 -:101CA0000123C2F80C11C4F8403110BD00800D4072 -:101CB00000C00F4000002E4000900D40001C1E0090 -:101CC00000000020001C0020E9AE000008B50E4B0B -:101CD0001B6E9B0700D4FBBE72B60C4B00200C4A57 -:101CE000C3F8400103F160430A49A3F55F2311647F -:101CF0009D46BFF34F8F4FF400130748074ADB6937 -:101D000002609B68984700BF00441F4000002E40BF -:101D100000C00A400300200000802020000012EBD9 -:101D2000104BA020104AD96E41F4403110B4D9664E -:101D300040F23764D96E41F44071D96654649064BE -:101D4000936C1B06FCD4094A40F23761A02351640E -:101D50009364936C13F08003FBD1054A13705DF814 -:101D6000044B704700C00F4000400C4000800C4006 -:101D7000002C0020F8B500BFF8BC08BC9E46704798 -:101D80005FF800F0FDA900005FF800F0EDA500008D -:101D90005FF800F015A900005FF800F0FDA2000058 -:101DA0005FF800F0D1A700005FF800F0319B000061 -:101DB0005FF800F03DA100005FF800F059B60000A8 -:101DC0005FF800F075CF00005FF800F0FDCC000078 -:101DD000450000006D04000041050000E909000015 -:101DE0002D0C0000450C00005D0C0000750C00007F -:101DF0008D0C0000A50C0000BD0C0000D50C0000EF -:101E0000ED0C0000050D0000F90D0000110E0000A2 -:101E1000290E0000410E0000590E0000710E000056 -:101E2000890E0000A10E0000D50E0000050F000075 -:101E30001D0F0000350F00004D0F0000650F000062 -:081E40001922000041A200007C -:101E480080C00F40000000031900000010000000CF -:101E5800E8841F4001000000FF000000FF000000B0 -:101E68000000000000000000180000001000000042 -:101E7800E4841F4001000000FF000000FF00000094 -:101E880000000000000000001F000000B19A0000E0 -:101E980070C00F40000C000011000000110000008D -:101EA800E0841F400200000024000000120000002F -:101EB800E0841F4001000000100000001100000035 -:101EC800DC841F4002000000250000001200000012 -:101ED800DC841F40010000001E000000A59A0000DD -:101EE80070C00F40C0000000120000001300000086 -:101EF800D0841F4001000000FF000000FF00000028 -:101F080000000000000000001300000013000000A3 -:101F1800CC841F4001000000FF000000FF0000000B -:101F280000000000000000001C000000999A00005A -:101F3800160355005300420020005300650072004C -:101F4800690061006C00000018035400650065001A -:101F58006E00730079006400750069006E006F0000 -:101F68000403090409026200030100C032080B00DF -:101F78000202020100090400000102020100052416 -:101F880000100105240101010424020605240600AD -:101F9800010705820310001009040100020A00006D -:101FA80000070503024000000705840240000009FD -:101FB80004020002FF6AFF000705810240000107D2 -:101FC800050102400001000009026200030100C08F -:101FD80032080B000202020100090400000102029B -:101FE8000100052400100105240101010424020652 -:101FF80005240600010705820310000509040100F5 -:10200800020A000000070503020002000705840217 -:102018000002000904020002FF6AC70007058102E6 -:102028000002010705010200020100000A06000281 -:08203800EF020140010000006D -:102040000000000000000000000000000000000090 -:102050000000000000000000000000000000000080 -:102060000548064B1B1AD90F01EBA301491002D0FA -:10207000034B03B118477047C01E0020C01E00204C -:102080000000000008B5054B1BB105490548AFF33A -:102090000080BDE80840FFF7E3BF00BF000000007C -:1020A000382B0020007001602DE9F843214D40F2EB -:1020B000EE28214C214FDFF890902E680BF0D2FED5 -:1020C0002378E3B13B78DB0719D52B68D9F80020DA -:1020D0009B1A0E2B13D91A4C0C211A4812F04CF9EA -:1020E000204600F08FFB55222021204600F09AFA6E -:1020F00090B901210D20BDE8F8430AF051BB2B68CF -:1021000022789B1B2AB1B3F5FA6FE4D80BF0AAFE34 -:10211000D4E74345FAD9DEE7E2882421204642F09D -:10212000040200F07FFA01210D20BDE8F8430AF017 -:1021300037BB00BFC42B00200A2C0020092C002034 -:10214000B42B002000002020D42B00202DE9F04FDC -:10215000BD4B8BB0BD4F1C6897ED007A72B6BC4A80 -:10216000137FDBB262B6002B00F0A58072B60023AD -:10217000D2E90A60137762B6C0F30163C6F3026165 -:10218000DFF82483C0F3034503EB8302C0F302238B -:1021900001EB810900F00F0C03EB8303C6F301216F -:1021A00005EB4205C6F3034E01EB8101D8F8002090 -:1021B0000CEB430C06F00F030EEB490E03EB41034F -:1021C000002A40F09D8097ED007ADFEDA27AC8F8F2 -:1021D0000040B4EEE77AF1EE10FA00F3C580F6EEB7 -:1021E000007A9D4877EE277AFDEEE77A17EE901A8F -:1021F00001FB00F0C6F38022CCEB0C1CB7EEC77AD3 -:102200003A324FEA8C0C01924FF4616202FB05CC2A -:10221000924DF44401FB0C33043393FBF0F200FBCA -:102220001233034493FBF0F200FB12338C4A8D48C7 -:102230008DED047B13608C4A146093FBF1F201FB7B -:102240001233029380FB0213D1171344C1EB6311C5 -:1022500080FB0103C8170B44C0EB6310C0EB0013F5 -:10226000A1EB8303C1EB0111A2EB81027F49009234 -:1022700085FB0025C217C2EBA50202EB4202A0EBD0 -:10228000C2027B480AF04CF87A4A01217A4B11705D -:102290001C607A4D32222B68E31A93422DD3784B7F -:1022A0000D20197881F0010119700AF03DFA2C60B7 -:1022B0000BB0BDE8F08F9FED736AF6EE006A6D4DCE -:1022C000C6EE077A2B78012B77EEA67AFCEEE77A3A -:1022D0004DD0022B40F0B380634A17EE900A13688A -:1022E000E11A814264D2684B2A7853F822205208BE -:1022F000624D2B68E31A9342D1D20BB0BDE8F08F48 -:10230000A21A07EE902A614A92ED007AF8EE677AF7 -:10231000B5EE407AF1EE10FA3FD1DFED5A6A0DF1D9 -:102320001C0AC2ED007AB3EE097AC6EEA75A584AE3 -:102330009FED586A0DF1280BD14607CA8AE80700BD -:10234000F9EC016A75EEE67AF0EEE77AF4EEC67A19 -:10235000F1EE10FA03D5B0EE667AB0EE676ACB45BF -:10236000EED187ED007A30E74B481E2142E7424B21 -:10237000F8EE676AB7EE086A1B68E31A07EE103AD0 -:10238000B8EE477AC7EE265AF4EEC65AF1EE10FAC6 -:10239000FFF67FAF02232B709EE79FED406ADFEDD3 -:1023A000406A27EE067AA7EEA67AF0EE477AB4E7FF -:1023B000F6EE005A97ED007A0344294FB7EEC76A4C -:1023C000254E37EE257A1360DFF898C0DFF88CE0F1 -:1023D000FDEEC77A334926488DED026B17EE902A41 -:1023E0003B6802FB06F6013393FBF6F806FB183355 -:1023F0003B6093FBF2F702FB1733FE1701938CFB54 -:1024000007233B44C6EB63168CFB063CF317B4442E -:10241000C3EB6C138EFB032EDA17C2EBAE0202EB9A -:102420004202A3EBC202C3EB0313A6EB8303C6EB8A -:102430000616A7EB8607009709F072FF53E7124ACA -:1024400052F82320520853E7C42B00208C1A002096 -:10245000F82000200000EC4180510100ABAAAA2A1C -:102460000C2B002089888888342B0020640E0020E3 -:1024700020110020022C00202C2B0020282B0020D3 -:10248000012C002000007A44A8040020642B0020C6 -:102490007003002000247449008D27006666663FA3 -:1024A000CDCCCC3D8C0E0020302B002070B5264DBD -:1024B0000021264A82B0264E2B68166011611181D8 -:1024C000D160002B3CD019465B69002BFBD14A61DF -:1024D0000024204B1D48136054615460947200F036 -:1024E0005FFB1D494FF480702B680A46CC608C61FD -:1024F00042F8186B08810A6123B31A465B69002B06 -:10250000FBD15161154A0024154B0A600A22154D72 -:102510004C614C608C720C771D601A72124809F085 -:10252000DFFB224609490C4B00940F4809F04CFC94 -:102530000E4A0F490C4802B0BDE870400BF0FEBCDB -:102540002A60C5E72960DDE744260020102B002023 -:10255000DC060020E8060020F8200020F406002019 -:10256000B42B002098070020502B0020FC140020E2 -:102570003D9E000010B5044609F016FD204610BD32 -:10258000024A034903480BF0D9BC00BFFC140020E9 -:1025900035050000C4270020002070470020704748 -:1025A000F8B50127027A1E4C0D46BA40C1F3072147 -:1025B0000646204684F8A52084F8307184F82F71EF -:1025C00009F02CF8E9B2204609F028F8002120464D -:1025D00009F0FCF808B10020F8BD3B460222317A30 -:1025E000204609F073F90128F5D994F8A22094F84F -:1025F000A300824210D2531CA118DBB2897E9842FC -:102600004FEA012184F8A23006D923440232987E91 -:1026100084F8A2200843F8BD4FF0FF30F8BD00BF9A -:1026200030110020F8B50127037A144C242903FA4D -:1026300007F30D4608BFC2801646C1F307212046A6 -:1026400084F8A53084F8307184F82F7108F0E6FF23 -:10265000E9B2204608F0E2FFC6F30721204608F061 -:10266000DDFF2046F1B208F0D9FF3946204609F0D7 -:10267000ADF8B0FA80F04009F8BD00BF301100207D -:102680002DE9F0414FF001080F461546302144F284 -:10269000600280F804800446FFF7C4FF064610B9C4 -:1026A0003046BDE8F0816C2226212046FFF7BAFFB4 -:1026B0004FF4F97228212046FFF7B4FF40F622724A -:1026C0002C212046FFF7AEFF44F246423C21204633 -:1026D000FFF7A8FF40F2371224212046FFF7A2FFA0 -:1026E000002F6BD0454B342120469F428CBF424681 -:1026F0000022FFF797FF07EE905A9FED417A3221B3 -:10270000B8EE676A07EE907A2046F8EE676AB5FB86 -:10271000F7F2C6EE267A02F01F0206EE902AF8EED5 -:10272000E66A77EEE67A67EE877AFCEEE77A17EEEE -:10273000903AC3F30A0343EAC222FFF773FF44F25D -:10274000FF5230212046FFF76DFF73220221204601 -:10275000FFF768FF4FF4C87009F068FF41F61D529B -:102760002E212046FFF75EFF072204212046FFF7B7 -:1027700059FFB02206212046FFF754FF10220A21FC -:102780002046FFF74FFF00220E212046FFF74AFFA9 -:1027900043F63C4210212046FFF744FF47F67F7284 -:1027A00022212046FFF73EFF362224212046FFF754 -:1027B00039FF012330466372BDE8F08144F2FF0225 -:1027C00030212046FFF72EFF732202212046FFF71B -:1027D00029FF4FF4C87009F029FF41F61D522E2140 -:1027E0002046FFF71FFF042220461146FFF71AFF7D -:1027F000302206212046FFF715FFBFE740660301A0 -:102800000000004510B50446084811F0B1FD052050 -:1028100009F00CFF06212046FFF7C2FE2046044ABD -:102820000021BDE81040FFF72BBF00BF3011002092 -:102830000040C40A10B50446D1B1012901D00020DE -:1028400010BD40F273122A21FFF7ECFE0028F6D0EB -:10285000882220212046FFF7E5FE0028EFD0E288FD -:102860002046242122F00402BDE81040FFF7DABE22 -:1028700055222021FFF7D6FE0028E0D0E28820462E -:10288000242142F00402BDE81040FFF7CBBE00BF98 -:102890009FED1F7ADFED1F7AE0EE077A38B5054627 -:1028A000FCEEE77A17EE904A14B3802C0CD8C4F1F2 -:1028B00080042B7944EA042453B922462846222175 -:1028C000BDE83840FFF7AEBE2B790024002BF4D0D2 -:1028D000EA8800232421284622F010022B71FFF7FA -:1028E000A1FE224628462221BDE83840FFF79ABEC5 -:1028F000012347F67F7222210371FFF793FEEA88D6 -:102900002846242142F01002BDE83840FFF78ABE75 -:1029100000000143EE7CFF3E30B482B00C4602ABB7 -:1029200003E90600C37C002B30D072B6C37CDA0703 -:1029300008D54FF0E0214569D1F880212A40826214 -:10294000C1F880219D0708D54FF0E0218569D1F8B5 -:1029500084212A40C262C1F88421590708D54FF06A -:10296000E021C569D1F888212A400263C1F8882195 -:102970001A0708D54FF0E021056AD1F88C212A40CA -:102980004263C1F88C21DB062FD462B683689C4277 -:1029900035D0224B84609B69214AC3F30111C3F3F4 -:1029A000826352F821100133B1FBF3F2CCB19442AF -:1029B00027D8B2FBF4F3B2FBF3F294422CD3B3F575 -:1029C000817F20D3174CC460036803220020019943 -:1029D00018615A6201221C6419661A6102B030BC87 -:1029E00070479942EFD3531CE9E74FF0E022416A68 -:1029F000D2F890310B408363C2F89031C5E7C468C8 -:102A0000E2E70024DFE7022BFBD9023B5A0814025D -:102A100044EA02441C43D6E71A46E4E700C00F40EC -:102A200050090020FF7F7F00024A034903480BF052 -:102A300085BA00BFFC1400203505000040270020A7 -:102A4000294A2A4B2A4910B5146810792269C87797 -:102A50009A420BD2274A1278002A41D04FF0E02246 -:102A6000402103F5807EC2F8081202E09E46A3F5DD -:102A700080732149214A0968106881B378B3204CDA -:102A80002288402A2BD802F1020C403201EB4C0183 -:102A9000228000EB4C001A46BFF34F8F03F1200455 -:102AA00003F5807CA44534BF4FF0010C4FF0080CB7 -:102AB0004FF0E02403EB4C1CC4F85C2F203262453D -:102AC000FAD1BFF34F8FBFF36F8F33F9042B21F887 -:102AD000022B9E4533F9022C20F8022BF5D810BDAD -:102AE00003F5807EC5E700BFC8260020400D2020EA -:102AF00000800E40FA2B0020C0260020C4260020B3 -:102B0000EA2B0020F8B5064609F03CF8C0B10446AF -:102B100009F038F8054680B172B61E4B1A887F2A34 -:102B200017D81D490A6872B362B6204609F080F8CA -:102B30002846BDE8F84009F07BB8204609F078F84F -:102B400072B6144B1A887F2A01D862B6F8BD0025E8 -:102B50002C4611480022114907681A8004600C684D -:102B60000D6062B63946304609F08AF8384609F0F9 -:102B70005FF830462146012209F082F82046BDE880 -:102B8000F84009F055B80C6004491A80086062B634 -:102B9000F8BD00BFEA2B0020C0260020C42600207C -:102BA00038B5234C01210625204609F0A3F9002061 -:102BB00000F0D4F802221F4903201F4BC1F87C010A -:102BC000C3F894211D4923681D4859609A609A8270 -:102BD0004FF480721B49186000201961DA82217954 -:102BE000DA839D83A5F20625174AD8609D6142F8D5 -:102BF00021001648164B42F82100164AC3F88820D7 -:102C000009F056F92379144C0121144A207003F17C -:102C10001000134C02EB5312E37603F01F039200F3 -:102C2000104C9940104B43F82040116038BD00BF54 -:102C3000C826002000801F4000841F4000000101C2 -:102C4000A2403840400C202000C00E4013000080FD -:102C50000040384001000092FA2B00204038003834 -:102C600000800E40010A0000001C0020024A0349B7 -:102C700003480BF063B900BFFC14002035050000C9 -:102C8000C8260020024A034903480BF057B900BF89 -:102C9000FC14002035050000E0260020024A03490C -:102CA00003480BF04BB900BFFC14002035050000B1 -:102CB00048270020024A034903480BF03FB900BFF0 -:102CC000FC1400203505000050270020024A03496B -:102CD00003480BF033B900BFFC1400203505000099 -:102CE00068270020024A034903480BF027B900BFB8 -:102CF000FC14002035050000D0260020024A0349BC -:102D000003480BF01BB900BFFC1400203505000080 -:102D1000E8260020024A034903480BF00FB900BF20 -:102D2000FC1400203505000058270020024A034902 -:102D300003480BF003B900BFFC1400203505000068 -:102D4000D8260020024A034903480BF0F7B800BF19 -:102D5000FC14002035050000F0260020F8B52D4CAD -:102D600005462D4AE36F43F44023E3679368002B45 -:102D700046DBD2F88830002B42DB002342F210728F -:102D80004FF40C611C2011F0E7FAE369234A23F4A5 -:102D90004063234943F40063E361A36A1A40214B73 -:102DA00042F0CE02A2624A68134043F400234B6013 -:102DB0002DB91D4B0322C3F82021C3F824211A4E3C -:102DC0000327154B0124C6F8287100254FF48030E5 -:102DD0001649174A174E1D66DC601E6158619961DD -:102DE000DA61C3F8E050C3F88C4004F1E064C3F842 -:102DF0009040C3F89400C3F89810C3F89C20F8BD25 -:102E0000002DFCD1084B0322C3F82021C3F8242154 -:102E1000F8BD00BF00C00F400040384000FEFFFF7B -:102E200000C00A40F8FFF7FF00801F401B1F010091 -:102E3000001F1F1F01000047024A034903480BF00F -:102E40007DB800BFFC14002035050000F8260020E6 -:102E5000024A034903480BF071B800BFFC1400207C -:102E60003505000030270020024A034903480BF0D3 -:102E700065B800BFFC140020350500007027002055 -:102E8000024A034903480BF059B800BFFC14002064 -:102E90003505000078270020024A034903480BF05B -:102EA0004DB800BFFC140020350500009827002015 -:102EB000024A034903480BF041B800BFFC1400204C -:102EC0003505000000270020024A034903480BF0A3 -:102ED00035B800BFFC140020350500008027002015 -:102EE000024A034903480BF029B800BFFC14002034 -:102EF00035050000A027002010B5054C04F108009E -:102F000009F052F82046BDE8104009F04DB800BF66 -:102F10000827002010B5084C0021204608F0EAFFE1 -:102F200004F10800002108F0E5FF044A04490020EC -:102F3000BDE810400BF002B808270020FC14002068 -:102F4000B90E0000024A034903480AF0F7BF00BF68 -:102F5000FC1400203505000060270020024A0349C8 -:102F600003480AF0EBBF00BFFC1400203505000049 -:102F700088270020024A034903480AF0DFBF00BF48 -:102F8000FC1400203505000090270020024A034968 -:102F900003480AF0D3BF00BFFC1400203505000031 -:102FA00018270020024A034903480AF0C7BF00BFA0 -:102FB000FC14002035050000382700200020704751 -:102FC000704700BF036D0BB101207047406D0038A2 -:102FD00018BF0120704700BF10B50446806D18B1BE -:102FE0000AF0BAFF0023A365236D2BB104F118008A -:102FF000BDE8104005F0B4BD636D002BF6D110BDE7 -:1030000010B50446806D00B110BD4FF480700AF019 -:103010009BFFA065B0B10022236D02703BB1014659 -:103020004FF48072184605F0EBF9A06D10BD636D8A -:10303000002BE9D001464FF48072184602F08EFE54 -:10304000A06D10BD014B1846A36510BDFF2B0020DD -:1030500038B5056D6DB10BB1002038BD114628465D -:1030600003F00AFF0028F7D02846BDE8384004F0F6 -:10307000A5B8446D002CEFD0204601F0C1FA00281D -:10308000EAD02046BDE8384002F034B98A79A2F18E -:1030900050031B0622D402F26C72F0B54B7985B056 -:1030A000046D01330D798E784F78DBB209784CB11D -:1030B000204601960095CDE90271042104F012F832 -:1030C00005B0F0BD406D0028FAD001960095CDE91D -:1030D0000271042102F052F805B0F0BD00207047E3 -:1030E00010B50446006D80B1037813F0700F00D165 -:1030F00010BD002103F0C0FE606D0028F8D0002252 -:103100000023BDE8104001F07BBA606D0028EFD0CD -:1031100090F8313013F0500FEAD000220023BDE8C0 -:10312000104001F06DBA00BF036D10B50C4682B0BF -:103130002BB30DF1060201A9184603F043FA38B388 -:10314000BDF80430BDF8062053EA020120D0C2F3D6 -:10315000451C02F01F00D20AC3F34311400084F85B -:1031600001C0A2705A0A013903F01F0302F5EA6296 -:103170002070012061712371A27102B010BD406DF9 -:1031800030B10DF1060201A901F0E0F80028D7D115 -:10319000002002B010BD00BF036D10B50C4682B018 -:1031A0002BB30DF1060201A9184603F0FBF938B361 -:1031B000BDF80430BDF8062053EA020120D0C2F366 -:1031C000451C02F01F00D20AC3F34311400084F8EB -:1031D00001C0A2705A0A013903F01F0302F5EA6226 -:1031E0002070012061712371A27102B010BD406D89 -:1031F00030B10DF1060201A901F096F80028D7D1EF -:10320000002002B010BD00BF0369D3B10E4810B456 -:103210001C68E46884420FD1186D18B15DF8044B46 -:1032200004F006B8586D18B15DF8044B02F0D4B83C -:1032300000205DF8044B7047184623465DF8044BA8 -:1032400018470020704700BFD1140000006990B1FA -:103250000368154A1B69934225D1036D63B1187841 -:1032600010F0080007D0D8695B69C01A48BF6FF03A -:103270000040704718467047436D002BFAD093F812 -:10328000310010F00800F6D0186919685A69401A20 -:103290005B6862EB0303B0F1004F73F10003EAD304 -:1032A0006FF0004070471847CD150000036963B107 -:1032B0001A68074992698A4208D1186D08B103F06B -:1032C0000BBF586D08B101F0E3BD704718461047B9 -:1032D00051140000036973B11A68084952698A429F -:1032E00007D1186D08B103F053BC586D18B101F047 -:1032F00071B9184610474FF0FF307047A91300000E -:10330000036D13B1586900217047436D13B1D3E9C0 -:103310000001704718461946704700BF036D13B18E -:10332000D86900217047436D13B1D3E90401704798 -:1033300018461946704700BFF0B595B000224FF40B -:103340007A74244F1831054604A88DF80C20009794 -:10335000CDE90124CDE9122205F06EFC129B002B71 -:103360002DD05C20002609F0F5FA019B044646604A -:10337000C36004A9029B183040F8083C9DF80C304B -:1033800000F8043C144B40F8183C144B40F8103C37 -:1033900005F0A4FB124B4FF47A72A7602B606368B0 -:1033A000A66501336E602E73AA602C6163600D4BBD -:1033B00004A8009305F0D4FB284615B0F0BD139B7C -:1033C000002BCED1064A2B732A602B61C5E901344C -:1033D000EDE700BFE007002004080020600800209F -:1033E000B4070020B8060020036D13B1184603F09F -:1033F000CFBB406D08B101F0EDB84FF0FF30704722 -:10340000836C13B1184603F0C3BBC06C08B101F064 -:10341000E1B84FF0FF307047036D33B11B7813F004 -:10342000700F14BF012000207047406D30B190F83C -:10343000313013F0500F14BF01200020704700BF3F -:10344000036D13B1184603F0CFBA406D08B100F018 -:10345000F1BF4FF0FF307047836C00B583B063B1AC -:1034600001220DF10701184603F0BEFA01280CD124 -:103470009DF8070003B05DF804FBC06C28B1012281 -:103480000DF1070100F0D6FFF0E74FF0FF30F1E754 -:10349000036D13B1184603F01FBE406D08B101F073 -:1034A000F7BC7047836C13B1184603F015BEC06CAF -:1034B00008B101F0EDBC7047036923B31968134AE2 -:1034C00010B58C6882B0944214D1186D48B10122B5 -:1034D0000DF1070103F088FA90B19DF8070002B0E2 -:1034E00010BD586D0028F8D001220DF1070100F041 -:1034F000A1FFF1E701220DF107011846A047EBE714 -:103500004FF0FF30EBE74FF0FF3070470114000041 -:10351000036D13B1184603F08BBE406D08B101F086 -:103520005BBF7047836C13B1184603F081BEC06C5B -:1035300008B101F051BF704700B5836C83B08DF8BE -:10354000071043B101220DF10701184603F070FE88 -:1035500003B05DF804FBC06C0028F9D001220DF126 -:10356000070101F039FF03B05DF804FB8A79A2F18D -:1035700050031B0622D402F26C72F0B54B7985B071 -:10358000046D01330D798E784F78DBB209784CB138 -:10359000204601960095CDE90271022103F0A2FDBB -:1035A00005B0F0BD406D0028FAD001960095CDE938 -:1035B0000271022101F0E2FD05B0F0BD002070476C -:1035C000836C53B1187810F008000DD0D8695B698E -:1035D000C01A48BF6FF000407047C36CA3B193F8A6 -:1035E000310010F0080000D17047186919685A6955 -:1035F000401A5B6862EB0303B0F1004F73F1000304 -:10360000F2D36FF0004070471846EDE7036D53B1F9 -:10361000187810F008000DD0D8695B69C01A48BF4F -:103620006FF000407047436DA3B193F8310010F084 -:10363000080000D17047186919685A69401A5B6818 -:1036400062EB0303B0F1004F73F10003F2D36FF0AC -:10365000004070471846EDE700B5006983B08DF86B -:10366000071060B10368104ADB68934215D1036DFF -:1036700043B101220DF10701184603F0D9FD03B053 -:103680005DF804FB406D0028F9D001220DF107011F -:1036900001F0A2FE03B05DF804FB01220DF1070169 -:1036A000984703B05DF804FBD114000038B5044618 -:1036B0000C4B806D236018B10AF04EFC0023A3650B -:1036C000236D04F118054BB1284605F049FA064B65 -:1036D0002846A36005F044FA204638BD636D002BF0 -:1036E000F2D1F4E704080020B806002038B50446FB -:1036F0000E4B806D236018B10AF02EFC0023A365E9 -:10370000236D04F118056BB1284605F029FA084B22 -:103710002846A36005F024FA20465C2109F01CF934 -:10372000204638BD636D002BEED1F0E70408002081 -:10373000B806002030B4029C11469C4634B1012CDE -:103740001CD0022C0ED0002030BC7047056DF5B1A6 -:103750004FF0FF33934274EB0C04F4D3284630BC93 -:1037600003F08ABB026D0AB3D36959184CF1000308 -:10377000002BE8D1104630BC03F07EBB026D62B175 -:10378000536959184CF10003002BDCD1F2E7406D6E -:103790000028D8D030BC00F033BF406D0028D2D014 -:1037A000D0E900238A184CEB0303F3E7406D0028AF -:1037B000C9D0D0E9042330BC8A184CEB030300F0D5 -:1037C0001FBF00BF70B5244B044605690360002D80 -:1037D00032D06E68013E6E6076BB2B681F4ADB6A92 -:1037E00093422FD1A86D10B10AF0B6FBAE652B6DD8 -:1037F00023B305F1180005F0B3F92569E5B12B688D -:10380000174A5B68934224D1164BA86D2B6018B100 -:103810000AF0A2FB0023AB652B6D05F11806A3B1DE -:10382000304605F09DF9104B3046AB6005F098F935 -:103830005C21284609F090F8204670BD6B6D002B86 -:10384000D7D1DAE728469847D7E76B6D002BE7D149 -:10385000E9E728469847EFE7B4070020990F0000F2 -:10386000AD16000004080020B806002070B5264BF5 -:10387000044605690360002D32D06E68013E6E601B -:1038800076BB2B68214ADB6A934233D1A86D10B115 -:103890000AF062FBAE652B6D43B305F1180005F02D -:1038A0005FF92569E5B12B68194A5B68934228D115 -:1038B000184BA86D2B6018B10AF04EFB0023AB65C6 -:1038C0002B6D05F11806C3B1304605F049F9124BCE -:1038D0003046AB6005F044F95C21284609F03CF81D -:1038E0002046142109F038F8204670BD6B6D002B7E -:1038F000D3D1D6E728469847D3E76B6D002BE3D1A9 -:10390000E5E728469847EBE7B4070020990F000049 -:10391000AD16000004080020B806002090F81CC076 -:103920004160BCF1020FC26001D18368184708F002 -:1039300055BB00BFF0B4046840F201251E46256166 -:10394000A3B121B311F8015B013B6566256FAF0799 -:1039500007D41546013E676F1AB105F8017B2A4668 -:1039600004686569ED07F1D5002BEAD16EB10368F3 -:10397000196F8907FAD41146013E5B6F002AF5D012 -:1039800001F8013B0A46002EF1D1F0BC704790F8D7 -:103990003C50D9E7324B334930B5D3E91154207943 -:1039A000C8771A6C95F804C081F81CC0087752B12A -:1039B000B2F5004F23D32C4911442A4A1964D0761A -:1039C00082F81BC030BD19680F24D86C8C6540F29A -:1039D0000134CA610C614FF47C544C6103210468CA -:1039E000246883F83D10214B9C4226D1037F42601E -:1039F000022BC26026D18368BDE8304018472D688D -:103A0000E98B090422D492B2EA832168EC8BA4B238 -:103A1000EC82CC8B240405D5CC8BC2F3080204F4D1 -:103A20007E442243CA83CA8B92B2CA8200210D4AC5 -:103A30001964D07682F81BC030BD23461146BDE81C -:103A400030401847BDE8304008F0C8BAE98BC2F3EF -:103A5000080E92B201F47E4141EA0E01E983D4E7F7 -:103A6000D010002000800E400180FFFFDD18000014 -:103A700043682DE9F04FD3E90041814D4FF0B80A7A -:103A800022684FF0020822EA01027E492260AA69F8 -:103A900011407D4A0A43AA6190F810E07B4A03EB8B -:103AA0000E0603EB8E0E317C02EB01118968C1F822 -:103AB00000A090F811C003EB0C0503EB8C0C95F8FB -:103AC000201002EB01118968C1F800A0817C03EB92 -:103AD000010903EB810199F830B002EB0B1BDBF815 -:103AE00008B0CBF800A0D4F800A05F684AEA070A43 -:103AF000C4F800A0347CDEF814E002EB041464681F -:103B0000C4F800E095F82040DCF824C002EB04146F -:103B10006468C4F800C0496B99F8304002EB0412A5 -:103B200052681160DA6B99F838101160DA69317EE9 -:103B3000DB6A116095F828201A600F220368C3F829 -:103B400010809A65C27C002A31D072B6C37CDC0733 -:103B500008D54FF0E0214469D1F8802122408262EB -:103B6000C1F88021990708D54FF0E0218469D1F888 -:103B700084212240C262C1F884215A0708D54FF03F -:103B8000E021C469D1F8882122400263C1F888216C -:103B90001F0708D54FF0E021046AD1F88C2122409C -:103BA0004263C1F88C21DE0655D462B60368384CF6 -:103BB0008268A24259D0324A846092693549C2F380 -:103BC0000116C2F38262344D51F826100132B1FB66 -:103BD000F2F2AA4231D80022C260002403211C6103 -:103BE0000724596201211A641C661961C37C13B34E -:103BF000DD0704D5816A4FF0E022C2F800119C076E -:103C000004D5C16A4FF0E022C2F80411590704D567 -:103C1000016B4FF0E022C2F808111A0704D5416B7E -:103C20004FF0E022C2F80C11DB0604D5826B4FF096 -:103C3000E023C3F81021BDE8F08F1849A1FB025121 -:103C4000090DB2FBF1F2A24288BF0131B1F5817FCB -:103C50000DD3134AC0E74FF0E022416AD2F8903109 -:103C60000B408363C2F890319FE7C268B5E7022931 -:103C7000B1D902394C08220242EA04420A43ABE7B6 -:103C800000C00F40CFFFFFE310000008E40B00204E -:103C900000093D0050090020FF083D0083DE1B4362 -:103CA000FF7F7F000BB1FFF745BE70474368D3E944 -:103CB00000120968114200D1704710B5026804462D -:103CC000002005211061227C1344187C08F068FD57 -:103CD000627C63680521134493F8200008F060FDBE -:103CE0006368A27C05211344BDE8104093F83000BE -:103CF00008F056BD704700BF012BF0B5054695B0E2 -:103D00003DD0022B40F2022001F104010CBF03461A -:103D10000023684605F03EF8129B002B38D05C204B -:103D2000002608F017FE214B04AF0446C0E9003618 -:103D3000019B3946183040F80C3C1D4B40F8103CB4 -:103D4000029B40F8083C9DF80C3000F8043C04F05D -:103D5000C5FE184B4FF47A72A665A360164B6E60D1 -:103D60002B6063682E730133AA602C616360134B70 -:103D70003846009304F0F4FE284615B0F0BD44F236 -:103D800002230431684605F005F8129B002BC6D1CA -:103D9000139B002BC3D14FF47A71074A04AF2B73E6 -:103DA0002A602B61C5E90131E1E700BF040800206A -:103DB00060080020E0070020B4070020B8060020BB -:103DC00010B5D0F884448EB00A4644B10023214691 -:103DD0006846009302F0B4FD80B90EB010BDD0F873 -:103DE000881441B1234668460C9400F0C7FE50B9D0 -:103DF00000200EB010BD08460EB010BD684602F09F -:103E0000F3FF0EB010BD684600F076FF0028EFD03B -:103E1000E3E700BF70B5D0F884548EB016465DB1AC -:103E200005F5896500230A4668462946009302F095 -:103E300005FD90B90EB070BDD0F888040028F9D007 -:103E400000F589640A462B46684621460C9500F029 -:103E500019FE48B900200EB070BD324629466846AA -:103E600002F0CCFE0EB070BD32462146684601F02D -:103E700097F80028EED0DDE710B5D0F884448EB076 -:103E80000A464CB10020012321460090684602F00A -:103E900057FD80B90EB010BDD0F8881441B1012390 -:103EA00068460C9400F06AFE50B900200EB010BDB8 -:103EB00008460EB010BD684603F048FE0EB010BDB7 -:103EC000684600F0BFFE0028EFD0E3E730B5D0F839 -:103ED00084448FB00A464CB10025012304F5896162 -:103EE0006846009502F034FC0FB030BDD0F888046D -:103EF0000028F9D000F58961012368460C9401F08F -:103F0000D1F80FB030BD00BF10B5D0F884448EB0EA -:103F10000A463CB1002321466846009302F010FD9A -:103F20000EB010BDD0F8881431B1234668460C9409 -:103F300000F024FE0EB010BD08460EB010BD00BF4C -:103F4000F8B5054690F8D00408B90146F8BDD5F893 -:103F50008434002B4CD0DC69D5F89004013C002857 -:103F600054D00368DB6B9847E0B1D5F8900478B380 -:103F700003681B6C9847A8B9D5F8900440B3036850 -:103F800001215B6C9847074610B3D5F8840458BBF1 -:103F9000D5F8886433466EB9D5F8900490B90020FE -:103FA0000146D3E7D5F88404E8B9D5F88834002B66 -:103FB000F5D00746184602F049F906463FB1D5F854 -:103FC000900428B1036800215B6C984700B1A41BE2 -:103FD000D5F88434FBB19B794FF40071994089B2D4 -:103FE000A1FB0401F8BD002704F002FC0646E5E74A -:103FF000D5F88834D5F89004B3B1D3F8304400280C -:10400000AFD1184602F022F90646E0E7184604F060 -:10401000EFFB0646DBE7D5F88864002EBFD0D6F864 -:104020003C14A1FB0401F8BD0028B8D01C4698E759 -:1040300090F8D03463B1D0F8843463B19A794FF4F6 -:104040000070D9699040013980B2A0FB010170472E -:10405000184601467047D0F888040028F9D0D0F8F7 -:104060003C14D0F83004A1FB000170472DE9F04367 -:10407000D0F890548DB04DB198462B680446284630 -:10408000DB699847B0F5405F064604D80026304605 -:104090000DB0BDE8F0834FF4007009F055FF0746FE -:1040A0000028F3D00DF10409B6F1806F02464346B3 -:1040B000294648462ED901F095FB0646384609F0B8 -:1040C0004BFF002EE2D02B682846271D1B6A98471D -:1040D00094F8C034FF2B21D0D4F8C43404F594658F -:1040E00002932846D4F8C8340393B4F8C034ADF82A -:1040F000043099E80E0005F013FD94F8B134C4F8CB -:104100009054002BC3D10123294638461A4604F0A7 -:10411000CFFDBCE704F032F80646CFE704F2944541 -:1041200094F8CC14284606F043FB2846C4F8905473 -:1041300005F0A0FD0028AAD10123D4F89014384638 -:104140001A4604F0B5FDA2E7F0B5D0F8906485B04A -:104150000446002E42D090F8D05490F8D13485B166 -:10416000FE2B63D094F8D20427283DD933686946E2 -:1041700030469B6C98470546284684F8D05405B0D5 -:10418000F0BDFE2B26D090F8D204272849D994F808 -:10419000C034271DFF2B2DD0D4F8C43404F5946609 -:1041A000D4F8C82401933046B4F8C0340292ADF874 -:1041B00000306B460ECB05F0B3FC94F8B134C4F874 -:1041C000906463B90123314638461A4604F070FD05 -:1041D000054604E01F4B9B689B03D8D40025284666 -:1041E00084F8D05405B0F0BD08F0C8FA051E18BF19 -:1041F0000125F4E704F2944694F8CC14304606F016 -:10420000D7FA3046C4F8906405F034FD0028E6D1B2 -:104210000123D4F8901438461A4604F049FD0546A7 -:10422000DDE708F0ABFA0028B1D1D7E733683046B4 -:104230005B6D9847421C034694D00028CFD194F878 -:10424000D124FE2ACAD1032126201D4608F0A8FA4F -:10425000C5E700BF0080004218484FF0290C184AFB -:104260000023184910B4C0F89424072280F8B1C480 -:104270004FF0FF0CC0F8A8144FF47F41124CC0F867 -:10428000AC24124AA0F8D014A0F89C3480F8B534BD -:1042900080F8CC3480F8D2C40460C0F8A0240C4963 -:1042A0000C4A5DF8044BC0F88434C0F88834C0F878 -:1042B000903480F8BC3409F041BE00BF30210020AA -:1042C000D808002000093D008408002000070020D5 -:1042D000B51C0000FC14002070B500F1240384B06C -:1042E0008C46044601AD164693E8070085E80700B2 -:1042F0004FEA4C122946206A01F0C4FE012806D17B -:1043000032462946206A01F0A1FE04B070BD0020AB -:1043100004B070BD10B5044600F0BAFD002384F867 -:10432000313084F8333010BD38B514460D460022C4 -:1043300000F12401006A01F089FE034620B14289A0 -:1043400001202A801B89238038BD00BF38B5144660 -:104350000D46002200F12401006A01F077FE0346B9 -:1043600020B1C28901202A809B89238038BD00BFEB -:1043700038B50D4690F8311009B1002038BD38220B -:1043800004460AF0DBFC012340222562184684F82B -:10439000333084F8312038BDF0B40D460978202937 -:1043A00003D115F8014F202CFBD0156095602C78B7 -:1043B0002F2C11D084B16E1C3C2C1D4F35462AD8B1 -:1043C000212C12D804F1FF3CBCF11E0F16D800209E -:1043D000F0BC704715F8014F202CFBD02F2CF9D0E2 -:1043E0001D601146F0BC01F01FBDA4F1220C5FFA64 -:1043F0008CFC27FA0CFC1CF0010FE8D12E2C01D00C -:10440000202C0DD116F8014B002CE5D02F2CE3D039 -:104410003C2C3546D4D95C2CD9D003D97C2CD6D0B1 -:104420009660EFE73E3C012CFAD80020F0BC7047C4 -:10443000012100052DE9F04F90F8333083B0054697 -:10444000DC0774D558060F46904640F1B080D5E998 -:104450000023D5E9041018EB020443F10003A14244 -:1044600070EB0303C0F0A980B8F1000F5BD04646A3 -:1044700005F11809D5E90032D5F820A0DAF838445A -:104480001C40C4F3080B002C70D1134370D195F875 -:1044900031305A064CBFDAF83424EA69AA619AF836 -:1044A0004504023ADAF82C14630A824001EB5421E5 -:1044B0001144BBF1000F45D1B6F5007F42D3DAF8C5 -:1044C0001C2291423ED0B6F5806F58D34FF0010BBD -:1044D0000BFA00FBABEB030B730A9B4528BF9B4613 -:1044E00091424FEA4B240AD801EB0B039A4206D2C1 -:1044F0000AF50470019106F0B5FD0199B8B1DAF83A -:1045000014025B460268D2F814A03A46D04770B154 -:1045100023462744D5E900125B1842F10002361BFE -:10452000C5E90032A8D1404603B0BDE8F08F95F848 -:1045300032304FF0FF3043F0020385F8323003B0E1 -:10454000BDE8F08FCBF5007400220AF50470B44288 -:1045500028BF344606F0B2FD0028E8D000EB0B017E -:104560002246384608F05CF92346D2E7AA6996E766 -:1045700095F833305B060ED5AA6901328EE7DAF87A -:1045800014023A4603681B6998470028CFD04FF4BD -:1045900000731C46BDE74A465046A96901F0B4FDC8 -:1045A0000028C4DB0CD0D5F820A0AA6977E795F8DD -:1045B000313019077FF558AF49E7A1EB020853E7FF -:1045C00095F8313013F0500FB1D0A8EB06084046F3 -:1045D000AAE700BFF0B583B00122044685690DF15A -:1045E0000701D0E90067FFF725FF0128A5610CBF8F -:1045F0009DF807004FF0FF30C4E9006703B0F0BD3D -:104600002DE9F04F1F4690F8313083B00446D0F8C2 -:104610001880002B51D01646D0E9001CBC4508BFBD -:1046200091425CD056EA07024DD01D0704D5D0E96F -:104630000402B042BA4140D394F83320751ED4F836 -:1046400020A0019247F1FF309AF845240932D2B2F6 -:10465000C2F1200ED540A2F1200900FA0EFB20FA8B -:1046600009F045EA0B0505430198400633D4481E7E -:1046700020FA02F24CF1FF3051EA0C0C00FA0EFE67 -:1046800020FA09F042EA0E0242EA000201D0954205 -:1046900029D25B064CBFDAF83434E369A36104F134 -:1046A000180906E0A169013D206A01F02DFD0028EE -:1046B00003DD4A46002DF5D107E00020C4F818803C -:1046C00003B0BDE8F08F002383610120C4E90067D7 -:1046D00003B0BDE8F08FE3692B44A361F5E7012047 -:1046E00003B0BDE8F08FAD1AD9E700BF2DE9F04F58 -:1046F000174690F831208FB00546002A40F0D78049 -:104700008B4691F8311011F0500F00F0D08003F07B -:1047100003019A46032900F0CA80013103F0080022 -:1047200041EA00030293002F00F0CB80396901F1C8 -:104730000E08B649A1FB0818DBE900104FEAD808BB -:10474000014308F102085FFA88F805D00020002133 -:10475000CBF81820CBE900010024029B264643F049 -:1047600040030393202206A95846FFF763FE00B3D7 -:10477000202840F09C809DF918209DF81830002AD0 -:10478000C0F2A28034B9DBF80020A2F12009DBF8E6 -:1047900018200192444501D20134E4B2002B00F00C -:1047A0001381202206A958460026FFF743FE002861 -:1047B000DED11AF4007F7AD0029B9B0777D5002FB9 -:1047C00075D0444517D2DDF804A0202206A958462A -:1047D000FFF730FE631C002861D0202867D12CB978 -:1047E000DBF80020DBF818A0A2F12009DCB2A0451C -:1047F000EBD8CDF804A03822002128469BF833409E -:104800000AF09CFADBF82030C4F38014019A2B6282 -:104810000823002685F82C4085F831303B68C5E92F -:1048200009297B60BE81B8F1000F33D008F1FF3950 -:10483000B346DFF8DCA15FFA89F901225946284620 -:10484000FFF74AFD044690B390F90020002A2EDBC2 -:10485000202200210AF072FA002E00F0BC80BBF189 -:10486000010F00F0D780C123A3461E3404F81E3C7C -:10487000BB8938461BB9D7E901239A4205D006F017 -:1048800045FC2BF8020FA345F2D101365FFA86FBF7 -:10489000D845D2D8284600F0FBFA06460DE0584627 -:1048A000DBF8186000F024FB002840F09180002322 -:1048B0001E4685F8313085F8333030460FB0BDE8FC -:1048C000F08F4FF0030847E756BB444538BF00243C -:1048D000852B7FF447AF31463822284601260AF05F -:1048E0002DFA9DF81C209DF8193085F8303002F023 -:1048F0003703D20658BF43F0080385F83130DBF8A0 -:104900000030DBF82020203B2A62DBF81820C5E9C4 -:1049100009239BF83330C3F3801385F82C3021E74B -:10492000C02B28D0C12B7FF43CAF3A4606A92846BD -:1049300001F0EEF9E8B1BB89DBB9D7E901329A425F -:1049400017D11AF4006FB2D11AF4884F70D195F8CC -:10495000333098076CD41AF4806FA8D11AF4804FC2 -:10496000ABD02846D5E90423FFF74AFE0028A4D19E -:104970009DE70646F6E6029B85F833309DF8193030 -:104980009B0702D5039B85F833300B9BEB61DDE978 -:104990000823C5E90423DDE90C23C5E90223002F20 -:1049A000CFD04FF000033A69BB813B687B609DF834 -:1049B0001B309A427FF4F5AEBE8ABDF81C30F61A61 -:1049C000B6FA86F67609CDE6002F7FF4F2AE6EE7F2 -:1049D000CBF818600BE78523237085F8309084F8B6 -:1049E0000190DAF80030002B46D00DF113020DF1E2 -:1049F000160105A89847BDF814306381BDF816303C -:104A000023819DF8133023753FE700BF898888888C -:104A10003C260020C02384F801B02370029B63F081 -:104A20007F0385F833303B69E370BB8AA3802CE7B2 -:104A300095F83130D9063FF53AAF13F001017FF414 -:104A400036AF1AF4806F89D095F8332092077FF53E -:104A50002EAF002B3FF42BAFD5E90032134304D027 -:104A600000220023A961C5E90023284600F042FC8A -:104A700000283FF41CAF20E745F621236381E38142 -:104A8000638202E72DE9F043002597B0994690F83C -:104A9000313001921495ADF81450002B3ED191F8AD -:104AA00031300F4613F0500F38D0137804461646B5 -:104AB0002F2B37D04FF0000801AB02AA3146204619 -:104AC000FFF76AFC50B3019E3378002B3ED00023E1 -:104AD00002AA39462046FFF709FEF8B1A44608AD00 -:104AE00004F13007DCF800000CF1100C5CF80C1C31 -:104AF000AE465CF8082C10355CF8043CBC45AEE8CA -:104B00000F00EFD1DCF8000008AF2860204600F06D -:104B1000BFF984F8318084F83380CDE7002017B0E6 -:104B2000BDE8F08316F8011F2F29FBD00196B1B91B -:104B3000382220463D6A0AF001F90123402225620D -:104B4000184684F8333084F83120E8E74B4602AA4F -:104B500039462046FFF7CAFD17B0BDE8F08338227A -:104B6000002108A83D6A0AF0E9F8012308AF109572 -:104B70008DF8533040238DF851309BE719B101F582 -:104B80008961FFF77FBF0846704700BF90F831305A -:104B900063B991F8313013F0500F07D00B6813F060 -:104BA0001F0C03D113466246FFF7A0BD00207047DB -:104BB0008169F8B50446006A01B10131012201F0B2 -:104BC00069F90128054632D901230146206A1A46AF -:104BD00001F0C0F9064650B3A3695BB394F83320E3 -:104BE000510612D5591CA94218D022F04002E169A1 -:104BF00084F8332005E0206A01F0A8FA3946B0B104 -:104C0000A3694F1C99423A46F5D34FF0FF3229462B -:104C1000206A01F09BFA50B1A16911B93046A56133 -:104C2000F8BD2A46206A01F091FA0028F6D1002644 -:104C30003046F8BD94F8333043F0400384F8333005 -:104C4000ECE700BF90F833309A0736D5C16970B5EC -:104C50000546A1B90024214607E0037803F07F034D -:104C6000037095F830308B4229D301340122284655 -:104C7000FFF732FBE1B20028EFD1002070BD5B06E8 -:104C8000006A34D590F84534D5E902240933013A55 -:104C9000DBB244F1FF34C3F1200CDA40203B04FACC -:104CA0000CFC24FA03F342EA0C021A4300230132FB -:104CB00001F050F90028CDD1DFE700207047002334 -:104CC0002C6A85F83130204685F8333006F0CAF971 -:104CD0000028D2D004F5047006F0C4F90028CCD026 -:104CE000D4F840040368BDE870401B6A184701F01F -:104CF0004DFA0028AED1C0E790F83130DB0601D480 -:104D00000020704710B5002288B000230446FFF74A -:104D100077FC08E020281BD19DF900309DF8002089 -:104D2000002B15DB32B1202269462046FFF782FBBB -:104D30000028EFD194F833300822204643F00203D4 -:104D400084F8312084F83330FFF77CFF08B010BDC1 -:104D5000002008B010BD00BF2DE9F0414FF0000861 -:104D600082B04A4F06464446414600223046FFF78D -:104D7000B3FA054630B10178C02969D0C1292BD0DA -:104D8000852909D096F83230002043F0010386F8D7 -:104D9000323002B0BDE8F08196F8313003F03703CD -:104DA00083803B6883B10DF103020DF1060101A878 -:104DB0009847BDF80630AB812B82BDF80430EB81FB -:104DC0006B829DF803306B75326A92F8103243F0B3 -:104DD000010382F810322978A1F185000022B0FA8F -:104DE00080F0400901E00422A95CE303012A02F1FA -:104DF000010243EA540311FA83F39CB201D1002863 -:104E0000F1D11F2AF0D908F1010896F830305FFA85 -:104E100088F18B42A9D2012206F12401306A01F007 -:104E200015F90028AED0356A4480284606F01AF9F4 -:104E30000028A7D005F5047006F014F90028A1D0C9 -:104E4000D5F8400403681B6A98470028A1D199E768 -:104E500096F8333013F0400F437814BF43F0020349 -:104E600003F0FD034370D6E90401D6E90732C5E932 -:104E70000201D6E902016B61C5E9060192F8103220 -:104E800043F0010382F810322978A5E73C26002080 -:104E900038B590F8313043B390F93320044690F898 -:104EA0003330002A0CDB056A284606F0DBF878B9B7 -:104EB00094F83230002043F0010384F8323038BDDA -:104EC00003F07F0380F83330BDE83840FFF744BF7C -:104ED00005F5047006F0C6F80028E9D0D5F84004BE -:104EE00003681B6A98470028E2D0012038BD00BF44 -:104EF00070B590F8313005465A064CD480682B6A5C -:104F0000D3F83C341844B0F1806F01D3002070BD59 -:104F10002846FFF74DFE0028F8D0286A0024AE6925 -:104F200090F84534023E9E40D0F82C341E4431198E -:104F3000052200F50470013406F0C0F84FF4007249 -:104F400000210028E2D009F0F9FE286A012390F838 -:104F5000452493409C42EAD395F831305B0615D442 -:104F600095F8332062F07F02D5E9023185F83320CD -:104F7000D0F83C249B1841F10000AB60D5E9043126 -:104F8000E8609B1841F10001C5E904312846BDE8FD -:104F90007040FFF77DBF006A01F0FEF9AFE700BF88 -:104FA00070B5044690F831009CB0002310F0180F43 -:104FB0000C931A9303D0206A0B6A984202D0002007 -:104FC0001CB070BD40F601236846FFF75BFD00286A -:104FD000F5D0A44604F130060EADDCF800000CF16B -:104FE000100C5CF80C1CAE465CF8082C10355CF814 -:104FF000043CB445AEE80F00EFD1DCF8000009AA8C -:1050000004F1240328609DF8305007CA83E80700A4 -:1050100094F83330204684F8305063F07F0384F8EE -:105020003330FFF735FF0028C9D0002102220823C2 -:105030000EA815918DF86B208DF86930FFF702FEF0 -:10504000BEE700BF38B591F8313013F0500F02D1F0 -:105050000025284638BD40F602230446FFF746FBEC -:105060000028F5D01023204684F83130FFF740FFA8 -:1050700005460028ECD0A169002200232046E1610A -:10508000FFF7BEFAC12294F8313084F83320002BA8 -:10509000DFD04123204684F83330BDE83840FFF7A5 -:1050A0005BBE00BFF0B5002597B01F4690F83130C9 -:1050B0000192ADF814501495002B46D191F831307F -:1050C0000E4613F0500F40D01378044611462F2B94 -:1050D0003ED001AB02AA2046FFF75EF9002834D08B -:1050E000019B1B78002B41D0002302AA31462046A9 -:1050F000FFF7FCFA30B947B302AA31462046FFF762 -:10510000A1FF10B3A44608AD04F13006DCF800009E -:105110000CF1100C5CF80C1CAE465CF8082C103539 -:105120005CF8043CB445AEE80F00EFD1DCF80000B9 -:1051300008AE28602046FFF7EDF8019901AB02AAFE -:105140002046FFF729F90028CAD1002017B0F0BD8A -:10515000013101910B782F2BFAD0316A08A8FFF7A3 -:1051600007F90028F1D0019908AEB2E702AA31464A -:105170002046FFF767FF17B0F0BD00BF2DE9F04FE5 -:105180000E4690F8311083B009079DF830B09DF8B5 -:1051900034909DF838809DF83C7040F18580A2F2F3 -:1051A000BC7294B27F2C7FD85A1E0B2A7CD80BF18C -:1051B000FF321E2A78D8B8F13B0F98BFB9F1170F0C -:1051C0008CBF4FF0010A4FF0000A3B2F88BF4AF016 -:1051D000010ABAF1000F67D105460193FFF758FEA7 -:1051E000002861D0019B51464BEA431B7B0817F016 -:1051F00001074BEA4424D34643EA481818BF642702 -:10520000A4B248EAC92806F001091FFA88F800226A -:105210002846FFF761F8002846D090F800C0BCF19E -:10522000850F45D00CF14003DBB2012B3CD8ACF12B -:1052300085010023B1FA81F1490902E0042310F845 -:1052400003C04FEACB32012B03F1010342EA5B02B8 -:105250001CFA82F21FFA82FB01D10029EED11F2B2A -:10526000EDD90AF1010A95F830305FFA8AF18B42E4 -:10527000CDD2012205F12401286A00F0E7FE98B1A1 -:105280002C6AA0F802B0204605F0ECFE60B104F5EF -:10529000047005F0E7FE38B1D4F8400403681B6AD7 -:1052A00003B0BDE8F04F1847002003B0BDE8F08F11 -:1052B00095F831302A6A03F03703838092F8103270 -:1052C00043F0010382F81032B9F1000F02D0A0F8C8 -:1052D00010804482B20703D50775A0F80880448186 -:1052E000730703D54775A0F80C80C48190F800C0FF -:1052F0009DE700BF90F833309A0762D570B5C56955 -:1053000082B00446A5B313F0400634D0006AA26808 -:1053100090F845C4013AE1680CF1090C41F1FF3104 -:105320005FFA8CFCCCF1200E22FA0CF2ACF1200CCE -:1053300001FA0EFE21FA0CFCA16942EA0E0242EAD1 -:105340000C02013219B3013D6D1A01312A44019159 -:1053500072BB63F07F03204694ED007B84F833300A -:1053600084ED027B84ED047BFFF792FD02B070BDFB -:10537000012002B070BD816961B90195C161294602 -:10538000206A00F003FFC8B194F83330E1E70195DB -:10539000E161DDE701AA006A019600F0B5FE002890 -:1053A0000CDB10D1019D002DE9D194F83330D0E70A -:1053B0000023019900F0CEFD0028E5D1002002B0C5 -:1053C00070BD002070474FF0FF32A169206A00F0E5 -:1053D000BDFE0028E6D1F1E72DE9F04390F8333027 -:1053E00083B004469D0740F1A18091461A070E46FE -:1053F00000F19580B9F1000F00F0288123684D4637 -:10540000206AA169D0F8382402EA0308C8F3080723 -:10541000B8F1000F40F09480002900F0D48094F897 -:1054200033305B0640F1EC8090F845C4D4E9023299 -:105430000CF1090C013B5FFA8CFC42F1FF32CCF11C -:10544000200E23FA0CF3ACF1200C02FA0EFE22FA25 -:105450000CFCE26943EA0E0343EA0C03134499424D -:1054600080F0D5800131A16190F845240239D0F84F -:105470002C3491401944B5F5007FC0F08A80B5F511 -:10548000806FC0F0A680012393406A0AA3EB080353 -:10549000934228BF1346D0F81C228A424FEA432881 -:1054A00009D35F18BA4206D2002280F810224FF0CA -:1054B000FF32C0F81C22D0F8140232460768BF6AD7 -:1054C000B84798B343464644A5EB0805D4E90072B3 -:1054D000D4E90401DB1942F1000298429141C4E988 -:1054E000003207D294F8331061F07F01C4E904322E -:1054F00084F83310002D83D1D4E902019842914100 -:10550000C0F09680534B1B68002B00F09D8094F8F0 -:105510003330484663F07F0384F833300DE0D0E940 -:105520000423FFF76DF800287FF464AF94F832305D -:10553000002043F0010384F8323003B0BDE8F0836B -:1055400090F8452402394FEA5828D0F82C3491407D -:1055500041441944002F8ED0C7F50078012200F590 -:105560000470A84528BFA84605F0A8FD0028DDD096 -:10557000384447444246314607F052F9B7F5007FB8 -:10558000206A9FD100F5047005F06CFD002899D1C8 -:10559000CCE76268636900920193226923689342B1 -:1055A000DDE900239A4112D2012200F5047005F0D2 -:1055B00085FD0028BAD02A4631463844A84607F06F -:1055C0002FF92B467FE7E16949B3A1614CE705223A -:1055D000EBE7D0F81C328B4206D1002380F8103262 -:1055E0004FF0FF33C0F81C32D0F814023246036883 -:1055F0005B6A9847002899D04FF40073984662E799 -:1056000004F1180200F080FD00288FDB04D1204651 -:10561000FFF7CEFA002889D0A169206A24E7204646 -:10562000FFF7C6FA002881D0A169206AE1611BE773 -:1056300094F833104846C4E9023261F07F0384F8DD -:10564000333003B0BDE8F083484676E7D4E9003252 -:1056500052E700BF3C26002069B170B505460846F8 -:105660000C4609F02DFD2B680246214628465B6852 -:10567000BDE87040184770478368C3F3080383B1DF -:10568000002110B40269D1540133B3F5007FF9D180 -:105690000168D0E903321C681846636A5DF8044B60 -:1056A00018470120704700BF82680346006940F236 -:1056B000FF1CC2F3080281546245586801EB700177 -:1056C000986800F10100C3E9011001D00120704782 -:1056D000D868196810B404684A1C646A1A601A69A8 -:1056E00023465DF8044B184738B58368CAB20D46A7 -:1056F0000169C3F3080340F2FF1C0446CA54634522 -:10570000416802EB71024260826802F1010282602C -:1057100005D0290A2046BDE83840FFF7C5BF01681B -:10572000C0684A1C03685B6A2260226998470028A7 -:10573000EFD138BDF8B50023064601601D46C0E92B -:105740000133A8B205F0F6FDA842044607D0C1B265 -:105750003046FFF7A9FF00283BD10020F8BD6C1CA4 -:10576000B4F5803F04D12AE00134B4F5803F04D081 -:10577000A0B205F0DFFDA042F6D0671BB7F5007FB1 -:105780001DD34FF6FF713046FFF7AEFF0028E4D07F -:10579000B9B23046FFF7A8FF0028DED02546B5F5A0 -:1057A000803FCED13046BDE8F840FFF765BFC5F376 -:1057B000072130460135FFF777FF0028CDD0A542FD -:1057C000E9B23046EBD2FFF76FFF0028EFD100209F -:1057D000F8BDC4F307213046FFF766FF0028BCD0B0 -:1057E0000135DCE72DE9F04F1F4689B00B680D4607 -:1057F00004901446C16002610846DB699847B0F521 -:10580000801F0090C0F0D88000230122009E013349 -:105810005200DBB201D09642F9D81C2B009640F220 -:10582000B780A3F10B08012248FA02F1C8F3470838 -:105830008A4002910792013301225B109A4006923E -:1058400004229A400392022202FA03F30193009A7F -:105850000021039B2046029E4FF0010AD31A4FF409 -:1058600000724AF6552BF34003FA06F90593019EA0 -:1058700009F064FAFF2384F8BFA184F8C0A1B14401 -:1058800084F8C431224684F8C53107230021284614 -:1058900084F8C231FE23C4F8C66184F8C3312B6892 -:1058A000C4F8CA915B6AA4F8FEB19847002863D097 -:1058B0004FF400720021204609F040FA009B84F862 -:1058C0006D804FF000086366F421059B04F17800B9 -:1058D000069AE3652023266423726372A372EB2386 -:1058E000A665464623707623C4F8489063709023DB -:1058F00084F86EA0A3704523E370582323714623D8 -:1059000063714123A3715423E371042323664FF48D -:105910008073A4F86830092384F86C308023C4E9CC -:10592000142284F86F304FF4C37209F007FAA4F818 -:10593000FEB1A8F16A03012B06D9B8F1700F03D0AC -:1059400014F8083003EB760608F10108B8F5007F7B -:10595000EFD12B682246DDF8049028465B6A494661 -:10596000984748B12B684946224628465B6A0C3165 -:10597000CDF80490984740BB2FB13B680F22B8493F -:1059800038465B6898470026304609B0BDE8F08F7E -:105990001A2B4FF0080800F2A6814FF48043CDF88F -:1059A000088001934FF4004303934FF480730793EF -:1059B0004FF4005306934AE7002FE4D03B681522CA -:1059C000A84938465B689847D7E7424600212046F9 -:1059D00009F1010A09F0B2F94AF6552309F1090261 -:1059E00004F2FF19A4F8FE3100239346A04601E01B -:1059F00018F8013FC14503EB7606F9D12B68224622 -:105A0000514628465B6A98470028B5D02B68224645 -:105A10000AF10C0128465B6A98470028ACD00AF1CD -:105A200001039B4502D09A462378DFE74FF40072CA -:105A3000002120469B4609F081F900220AF1030A61 -:105A40001146234601E013F8011F984501EB760645 -:105A5000F9D12B682246594628465B6A98470028A8 -:105A60008AD02B6822460BF10C0128465B6A9847C6 -:105A7000002881D00BF101018A456AD1231F04F56A -:105A8000FE7243F8046F9A42FBD12B6822462846E7 -:105A90005B6A984700283FF46FAF2B680BF10D014C -:105AA000224628465B6A984700283FF465AF2FB12D -:105AB0003B680C226C4938465B689847069A00217F -:105AC000019B2046002613444FF400729946059B23 -:105AD0004FEA830809F032F923464FF0FF3208F20B -:105AE0000728F821B7F1000B4FEA582A03F8011BE9 -:105AF0004FEA9838C4F8012018BF4FF0010BDA6064 -:105B00005A609A60C3F80F2002E00136B24523D0F4 -:105B1000B6FBF8F308FB136343B9BBF1000F05D0E4 -:105B20003B680122514938465B6898472B6809EB6E -:105B30000601224628465B6A984700283FF41CAFBE -:105B4000002EE2D131464FF40072204609F0F6F8FB -:105B5000DBE78B46217874E7002F34D03B680222C4 -:105B6000434938465B689847059E079A0736F6080A -:105B700006F2FF13B2EB532F4FEA5329FFF4FDAEA9 -:105B80004FF400720021204609F0D8F80723237053 -:105B9000B9F1000F00F08A804FF0000808E0B8F17A -:105BA000000F01D184F8008008F10108C1457BD9BC -:105BB000039A28462B6802EB080122465B6A984745 -:105BC0000028ECD1D8E6059E079A0736F60806F2BB -:105BD000FF13B2EB532F4FEA5329FFF4D4AE4FF427 -:105BE00000723946204609F0A9F807232370B9F15D -:105BF000000FD1D1039B079A04989918FFF79AFDDB -:105C000000283FF4C0AE029A4FF400739340049A08 -:105C100092689A423FF6B7AE4FF00208029B4FF4EB -:105C20000072002108FA03F9039B2046994409F009 -:105C300085F881220323049909F1FF3984F8202093 -:105C40008222237084F84020C4E90D864A684FF010 -:105C50000108636562648B68A3650023E3650EE059 -:105C600038060020D4050020EC050020FC050020AB -:105C700014060020079B98453BD208F101082B68C9 -:105C800009EB0801224628465B6A98470646002829 -:105C90003FF472AEB8F1010FECD14FF40072002165 -:105CA000204609F04BF8E8E7002FA3D03B68162206 -:105CB000144938465B689847039B079A04989918DB -:105CC000FFF738FD00283FF458AE029A4FF40073F6 -:105CD0009340049A92689A423FF64FAE0A4938467A -:105CE000FFF7BAFC98E74FF48072CDF8088007926E -:105CF000A1E5002F3FF448AE04493846FFF7ACFC5D -:105D000042E600BF000600201806002028060020FA -:105D10002DE9F0410C46154601F11E08AB892846D5 -:105D200034F8027F1BB9D5E901239A420ED005F061 -:105D3000EDF905F0FFFA0646384605F0FBFA864213 -:105D400009D14445EAD10120BDE8F081B7FA87F0D6 -:105D50004009BDE8F0810020BDE8F0812DE9F04F59 -:105D600090F8313083B08846002B4FD090F8303017 -:105D70000746012B53D9013A0B464FF0020A002483 -:105D80008E18DFF8A0B00022514638460193FEF786 -:105D9000A3FA00283AD00278C12A37D1054600F18B -:105DA0001E09019B35F8020F24B300F5105292B280 -:105DB000B2F5806F2AD20BEA8424C0F30900204395 -:105DC00000F580301946324605F016FA0346E8B170 -:105DD00000244D45E6D10AF1010A97F830205FFA18 -:105DE0008AFA5245CFD2A3EB08009846002388F8E0 -:105DF00000300FE000F5205292B2B2F5006F02D3EE -:105E00000028DFD1EFE7B2F5806F06D300231846F4 -:105E100088F8003003B0BDE8F08F0446D9E70020D1 -:105E2000E4E700BF00FC0F0070B50C4600234FF6FE -:105E3000FF75226819461E46A3812361626017E040 -:105E400005F064F9A84222D005F074FA2369F20340 -:105E5000A189013342EA5602060A236152FA80F010 -:105E600083B2C0F34E0040EAC33016FA80F086B227 -:105E700020460029E4D1D4E901239A42E0D12069E7 -:105E8000A6820138FE288CBF0020012070BD0020B2 -:105E900070BD00BF2DE9F84F07468A46914600299C -:105EA00042D0A1F10208D7F83034434542D908F076 -:105EB00007030125C8F3C80B9D40EDB24646444692 -:105EC000D7F82C140022384601EB143105F0F6F80F -:105ED000E8B10BF1FF3B834400F2FF101BF8011FF8 -:105EE0000AE04A452BD0A04510D0D7F83054A5423F -:105EF00014D913F0FF050CD0013429424FEA4503B1 -:105F0000A4EB0602EDD0A0452646EED10120BDE867 -:105F1000F88F58454FF00105E0D101E000263446E6 -:105F200001254FF0000BCBE7D0F82084D7F83034B0 -:105F30004345BCD84FF000080125C346BEE7BAF17F -:105F4000000F04D1B9F1010F08BFC7F82064B01CDD -:105F5000BDE8F88F2DE9F8438046881E15461E4699 -:105F60008318D8F83024934237D8CEBBD8F82034E1 -:105F7000834288BFC8F8200400F007030124D8F842 -:105F80002C74C0F3C8099C4007EB1031E4B2012225 -:105F900040468F1805F092F8F8B109F1FF3E8644AB -:105FA00000F2FF101EF801CF1CEA040F8CEA040C6B -:105FB0004FEA440414BF01220022B2420DD0013D39 -:105FC0008EF800C018D014F0FF04EDD17045A14642 -:105FD0004FF00104E6D13946D9E70020BDE8F88347 -:105FE000D8F820148B42C7D98142C5D3934228BF29 -:105FF0000023C8F82034BFE70120BDE8F88300BFC4 -:10600000F8B5D0F8303401338B4201D20020F8BD0E -:1060100007460C4600F50476002505E0D7F8303435 -:1060200001350133A342F1D3D7F8241400223046BE -:1060300001EBD41105F042F8A4000028E6D0C4F327 -:1060400008040459631CE9D1681CF8BD38B50C4636 -:106050000B6890F845C400F50470D0F82812023B94 -:10606000656803FA0CF3294003EB5123D0F81C12A6 -:10607000194405F023F818B16368C3F30803184402 -:1060800038BD00BF2DE9F8430C46D0F838344968D4 -:106090000B4011446160134490F8451401F109026A -:1060A000D2B2D3402BB380465D1E00F5047905E0E3 -:1060B0002368013D03F1010323601AD3267A002EE1 -:1060C000F6D1D8F8303432462768484601339F422B -:1060D00012D8D8F8241401EBD71104F0EFFFBF0059 -:1060E00050B1C7F30807C3595A1C09D0013D2360BA -:1060F000E4D20120BDE8F8834FF0FF30BDE8F8831B -:106100003046BDE8F88300BF38B5D0F830340133ED -:106110008B4202D24FF0FF3038BD0C46D0F8241429 -:10612000154600F50470002201EBD41104F0C6FFFF -:106130000028EFD0A400C4F3080403595A1C02D06D -:1061400001202B6038BD002038BD00BF01291BD9BC -:1061500038B5D0F830340C4601338B4201D20020E0 -:1061600038BDD0F82414154600F50470012201EB67 -:10617000D41104F0A3FF03460028F0D0A4000120AE -:10618000C4F308041D5138BD00207047D0F83034E6 -:106190000133994201D9002070472DE9F04F05469F -:1061A00083B00C4600F504790F464FF00008D5F88F -:1061B0002414002248464FEAD41B01EBD41104F00A -:1061C0007DFF90B1A300C3F30803C2580193531C91 -:1061D00016BF16464FF0000A4FF0010A012C04D9F1 -:1061E000D5F830240132944203D9002003B0BDE831 -:1061F000F08FD5F8241401224846594404F05EFF7C -:106200000028F2D0019B40F80380BAF1000F12D0B1 -:106210000134B44208D00023E21B39462846FFF778 -:1062200099FE0028E1D03746D5F830340133B34227 -:10623000DBD33446BBE7621C534639462846D21BA3 -:1062400003B0BDE8F04FFFF785BE00BF2DE9F8436E -:1062500000250646D0F82C1400F504782C460022C0 -:1062600040464F1C04F02AFFA8B100F1FF3E04F5A0 -:106270008059D6F8300405E079B90834844209D24F -:106280004C4516D01EF8011FFF29F5D108340835FA -:106290008442F5D3401BBDE8F8830822012319424C -:1062A0004FEA430C18BF0135013A5FFA8CF3F6D17F -:1062B000E3E73946D3E700BFF8B500234FF0FF36D8 -:1062C00000F504771546C0F84014044641601A46AC -:1062D000C0F81412194680F844340370C66080F880 -:1062E0001032C0F81C62384604F0E8FE042D0DD8C8 -:1062F000064658B1BDB16B1E00EB031393F8BE21E7 -:1063000012F07F0202D193F8C2310BB90020F8BD20 -:1063100000EB05163846D6F8B651294604F0CEFEF5 -:1063200006460028F2D005221A49F01C08F058FD54 -:106330000028EBD196F86C30092BE7D1336D01467C -:106340002B44C4F82434736DC4F82834B36D2B4443 -:106350000125C4F82C34F36DC4F83034336EC4F81E -:10636000343496F86D20C4F82004204602F1090365 -:1063700084F8452405FA03F35A1EC4F83C34C4F8E3 -:1063800038242A46FFF786FD4023284684F8443403 -:10639000F8BD00BF4806002010B50446D0F83414FC -:1063A000FFF72EFE94F845340933DBB2984010BD58 -:1063B00070B590F9023082B00446002B0DDBA56861 -:1063C00005F1280004F04EFE00283BD16378002040 -:1063D00043F00103637002B070BD80680122A169BF -:1063E000283004F06BFE0028F0D0A58805F00F05DA -:1063F0006B0100EB4515C35CE52BE7D023781B0749 -:1064000001D5E369EB61236A15491A0C6B830E68A9 -:10641000AA8266B10DF103020DF1060101A8B04791 -:10642000BDF80430BDF806202B836B82EA82A37886 -:10643000A56803F07F0305F12800A37004F012FEA5 -:106440000028C3D005F50E7004F00CFE0028BDD066 -:10645000286803681B6A98470028B7D0BBE700BFCD -:106460003C260020024638B552F8105F044680688A -:10647000294602F021F950B155B123690135AB42EB -:10648000A37818BF03F0BF0363F07F03A37038BD88 -:10649000A37843F04003F7E7F8B5047814F020043C -:1064A00004D11A4B054642699A4202D30027384666 -:1064B000F8BDFFF7D7FF07460028F7D0A8682E6978 -:1064C0008279023E416996400E440179A9B1214684 -:1064D00006E008F033FCA868E1B202798A420BD9E1 -:1064E000314405222830013404F0E8FD4FF40072F5 -:1064F00000210028EDD1D9E782794FF40073696952 -:106500003846934011FA83F36B61F8BD00FE1F001B -:1065100010B5044680680A462830A16904F0CEFD13 -:1065200020B1A38803F00F0300EB431010BD00BFA0 -:1065300010B5037804462BB1FFF73AFF0023237010 -:10654000A37010BD002301202370A37010BD00BFF5 -:1065500038B5037805460C4613B1FFF729FFF0B1B3 -:10656000A8680022A969283004F0A8FDB8B1AA885B -:1065700002F00F0200EB421352015D6880589968E7 -:10658000DA6820606560A160E26018695D699969F8 -:10659000DA69206101206561A161E26138BD0020F6 -:1065A00038BD00BF30B589B00D4614466946FFF7C7 -:1065B000CFFF28B1BDF81020BDF80E302A8023800F -:1065C00009B030BD30B589B00D4614466946FFF7B5 -:1065D000BFFF28B1BDF81820BDF816302A802380EF -:1065E00009B030BD0B7813F0700F01D10020704757 -:1065F000F0B540F6022389B00D46044601F0F0F8EC -:1066000038B1012210232046A2702370FFF744FF07 -:1066100010B9002009B0F0BD2269237822626BB165 -:10662000636933B1A378002223F02003C4E9042274 -:10663000A3702046FFF7BCFE0028EAD0A068012224 -:10664000A169283004F03AFD0028E2D0B4F804C073 -:1066500010220CF00F0C4FEA4C1300EB4C1C8CF882 -:106660000B20C058A768236A97F806E09E1EDCF846 -:106670000410DCF80820DCF80C3006FA0EF6EE46C2 -:10668000AEE80F00DCF81000DCF81410DCF818207D -:10669000DCF81C30AEE80F007B6907F1280001220E -:1066A000F1184FF02033CDF80130CDF80530ADF8BA -:1066B000093004F003FD84460028AAD02E27EE46B8 -:1066C0008DF800707646BEE80F00CCF80000CCF8DC -:1066D0000410CCF80820CCF80C308DF80170BEE81E -:1066E0000F00CCF81000CCF81410CCF81820CCF81F -:1066F0001C302B6A1A0CADF81A30ADF814200FCEEE -:10670000CCF82000CCF82410CCF82820CCF82C3081 -:106710000FCECCF83000CCF83410CCF83820CCF8C0 -:106720003C30A46804F1280004F09CFC00283FF4ED -:1067300070AF04F50E7004F095FC00283FF469AFCB -:10674000206803681B6A09B0BDE8F040184700BF25 -:106750002DE9F041002694B0984603780192ADF8F7 -:1067600014600B96002B41D10B780D4613F0700F7F -:106770003CD01378044616462F2B3BD0002728E048 -:10678000019E3678002E50D001F02AF8034602AA66 -:10679000294620462BB9B8F1000F27D0FFF722FF7A -:1067A00020B3A6460DF12C0CBEE80F00ACE80F009C -:1067B000BEE80F00ACE80F00DEF80050204623785A -:1067C000CCF800500BB1FFF7F3FD019E0BAD277025 -:1067D000A770314601AB02AA204601F04DF90646EA -:1067E00002AA294600232046002EC9D1002014B059 -:1067F000BDE8F0810136019633782F2BFAD0AD68D1 -:10680000242200210BA808F099FA0D95EB79102BA2 -:1068100003D0202B0FD00C2BE8D120238DF82C3067 -:1068200001230BAD8DF82E30A8E702AAFFF7DAFEA0 -:1068300014B0BDE8F0814023F0E700BF2DE9F0413E -:10684000002594B09846037801920295ADF838502F -:10685000002B37D10B780E4613F0700F32D013781F -:10686000044615462F2B31D000271EE0019D2D78C0 -:10687000002D40D000F0B4FFA6460DF1080C08B37F -:1068800066462578BEE80F00ACE80F00BEE80F00B2 -:10689000ACE80F00DEF800302046CCF800300DB137 -:1068A000FFF786FD019D2770A770294601AB0BAA53 -:1068B000204601F0E1F805460BAA314600232046A8 -:1068C000002DD3D1002014B0BDE8F0810135019531 -:1068D00029782F29FAD0A9B9B5682422204608F0D2 -:1068E0002DFAA560EB79102B03D0202B22D00C2B96 -:1068F000E8D120221FE043460BAA00F071FF14B03C -:10690000BDE8F081B6682422002102A808F016FA3A -:106910000496F379102B03D0202B03D00C2BD1D16C -:10692000202300E040238DF80830012302AE8DF8CB -:106930000A3099E74022012322701846A370C2E76B -:1069400019B101F58961FFF779BF0846704700BFAB -:10695000CB6870B50D46044693B906780EB118465B -:1069600070BD8D682422314608F0E8F9A560EB7906 -:10697000102B18D0202B10D00C2B14D0304670BD0B -:106980002422002108F0DAF901201023A0702370DE -:10699000D5E90223A260236270BD40220123227048 -:1069A0001846A37070BD2022F8E700BF70B50578C7 -:1069B0000DB1002070BD0E4604462422294608F081 -:1069C000BDF9A660F379102B0BD0202B03D00C2B34 -:1069D00007D0284670BD4022012322701846A370BC -:1069E00070BD2022F8E700BF2DE9F04F2DED028B9E -:1069F000837883B00546DF0740F18C8088460178B4 -:106A000092460E0700F191808C0608D583685A895A -:106A10004369C3EB42139BB29A4528BF9A46BAF129 -:106A2000000F00F0AF806A6905F110038806564632 -:106A30004FF0000908EE103AAF68C2F3080B3DD5DD -:106A4000396A01EB5221BBF1000F51D1B6F5007F3D -:106A50004ED37A6B91424BD0B6F5806FC0F08280F6 -:106A60002878730A800605D43879A0EB09008342A0 -:106A700028BF034691424FEA43240CD8C8188242EB -:106A800009D207F12800CDE9001304F0EBFADDE9A3 -:106A9000001300283ED0F86A026857694246B8479A -:106AA000002837D06A69361BA04422446A6169D045 -:106AB0002978C2F3080BAF688806C1D497F805900F -:106AC00009EA5229BBF1000F36D1B9F1000F33D1D9 -:106AD000002A33D14A064CBF3A6A2A6A2A61023A2E -:106AE000B8797969824049441144BBF1000FADD0B7 -:106AF000CBF50074002207F12800B44228BF3446C9 -:106B000004F0DCFA30B100EB0B012246404605F000 -:106B100087FEC7E76B784FF0FF3043F002036B70DE -:106B200003B0BDEC028BBDE8F08FC36942699B1ACC -:106B30009A4528BF9A4672E72A69D0E70B0705D520 -:106B4000AA78540602D52A690132C7E718EE102A3E -:106B50003846296901F0FEFD0028DBDB0CD0AF6868 -:106B60002A69BCE7F86A424603681B69984700280F -:106B7000D0D04FF4007495E72B7813F0700FC9D084 -:106B8000AAEB060A504603B0BDEC028BBDE8F08FBD -:106B900070B582B0012204460DF10701D0E9045618 -:106BA000FFF722FF01280CBF9DF807004FF0FF30D0 -:106BB000C4E9045602B070BD436913F4F07F30B5E8 -:106BC000044683B0C3F3431509D0012907D120330C -:106BD0004361A068383000EB451003B030BD01229E -:106BE0000DF107012046FFF7FFFE40B2012803D157 -:106BF00063691F336361ECE70020EEE72DE9F041A4 -:106C000003789AB0002613F0180F0896119606D054 -:106C1000174683688A6804460D469A4203D00020CE -:106C20001AB0BDE8F081FFF7C3FBA6460DF1440C96 -:106C3000BEE80F00ACE80F00BEE80F00ACE80F00A4 -:106C4000DEF800303246A169CCF80030A36803F1C9 -:106C5000280004F033FA0028E1D0A288EC4694F82A -:106C6000008002F00F0200EB421E5201DEF8041019 -:106C70008058DEF80C30DEF80820ACE80F00DEF8B3 -:106C80001410DEF81820DEF81C30DEF81000ACE836 -:106C90000F0018F008033A46294640F09B8008A8E8 -:106CA000FFF756FD0028BAD0109EBDF8243000250D -:106CB0000E990122A3809DF82330A068E3700B9BFE -:106CC0002830A161E3608DF820508DF8225004F047 -:106CD000F5F90028A3D0A38803F00F0300EB4310BD -:106CE000DDF80D30C0F80D30DDF81130C0F811308E -:106CF000DDF81530C0F81530DDF81930C0F819305E -:106D0000BDF81D30A0F81D309DF81F30C3779DF8E9 -:106D10000B30C372002E3BD0A068B31E2A46817987 -:106D200028308B4050F8141C194404F0C7F905466C -:106D300000283FF474AF006A6F46696AAA6AEB6A7A -:106D40000FC7286B696BAA6BEB6B0FC73146A06846 -:106D500001F022FD00283FF462AFA068236A827927 -:106D60002830023B50F8141C93400122194404F0CF -:106D7000A5F9064600283FF452AF6D460FCD3062AC -:106D80007162B262F3620FCD30637163B263F36319 -:106D900000210222082311A819918DF846208DF8B0 -:106DA000443000F0D3FE00283FF439AFA46804F16A -:106DB000280004F057F900283FF431AF04F50E70B5 -:106DC00004F050F900283FF42AAF206803681B6ADA -:106DD000984725E740F601236046FFF72FFD00287E -:106DE0007FF463AF1BE700BF0378DA0601D400200D -:106DF0007047436930B5044683B033B183780022CD -:106E000023F02003C0E90422837000230FE06361B4 -:106E1000A3686A0138339A5C03EB4513EAB1E52AAB -:106E200004D02E2A02D0DB7A1B0722D5636913F423 -:106E3000F07FC3F3431503F12003E8D101220DF1E4 -:106E400007012046FFF7D0FD40B2012803D1636956 -:106E50001F336361DCE763785BB9A37808222046BF -:106E600043F002032270A37003B0BDE8304000F08D -:106E70006DBE002003B030BD2DE9F041037804461B -:106E80000769002B39D00D464169A94242D0002D37 -:106E900037D018072AD5E269AA422ED3D4F808C001 -:106EA0006E1EA2789CF8060012F0400F00F1090057 -:106EB000C0B226FA00F630D14A1EC24009B196424D -:106EC0002FD25B064CBFDCF82030236A236104F12B -:106ED000100806E02169013EA06801F03BFC002893 -:106EE0000BDD4246002EF5D1A2780CE09A06D5D5EE -:106EF000A3685B89B5EB431FF6D900202761BDE885 -:106F0000F0818278056122F0200201206561A27083 -:106F1000BDE8F0810120BDE8F081236A334423619C -:106F2000F1E7B61AD3E700BF2DE9F0410E4615464A -:106F300000212422044698469DF8187007F0FEFEB2 -:106F4000B068336A00F13802A58005F00F0502EB46 -:106F50004512C4E90203D17A0B0711D401F01701DD -:106F60002170D37A13F0180F02D141F0080121707B -:106F700008F00303E770012B38D0022B06D0F3B1E1 -:106F8000002318462370A370BDE8F0810323217805 -:106F9000CD06F5D4CE07F3D408F0080118F4806FBD -:106FA00043EA0103A370416B958AA161518B41EAC9 -:106FB000054112D019BB63F07F03A37010E018F4F1 -:106FC000806FDDD108F0080343F00103A370416B2B -:106FD000938AA161518B41EA03412162D369E36144 -:106FE00018F4804F04D10120BDE8F0810223CEE7E0 -:106FF000E1692046FFF740FF0028F4D1C0E701F027 -:10700000CBFB0028BCD0A378D5E700BF0378002BCA -:1070100045D12DE9F0470B7884B00C4613F0700F82 -:1070200030D04B6913F01F052CD106469046A94677 -:1070300001220DF10F012046C3F3431A5F09FFF748 -:10704000D3FC40B24FEA4A1201281BD16369A16800 -:107050001F3301F1380C63611CF802200CEB4A1C51 -:1070600082B12E2A12D0A2F1E500B0FA80F04009D8 -:1070700060B99CF80B1011F0080E12D00F2907D040 -:107080000546D5E7002004B0BDE8F0870025CFE72E -:107090005106CDD502F01F059CF80D90C8E70020E1 -:1070A000704785B10CF10A0101E01CF8012F4FEA8D -:1070B000CE13614543EA5E0352FA83F35FFA83FE1F -:1070C000F3D1CE45DED14346BAB2214630460095D3 -:1070D000FFF72AFFD7E700BF03780BB1FFF768B9C6 -:1070E000012070472DE9F0470E46017882B009076C -:1070F0009DF828709DF82C909DF830A09DF8348064 -:1071000018D5A2F2BC7294B27F2C13D85A1E0193E8 -:107110000B2A0FD87A1E1E2A0CD8BAF13B0F98BF43 -:10712000B9F1170F06D8B8F13B0F03D80546FFF7A2 -:107130003FF918B9002002B0BDE8F087A868012225 -:10714000A969283003F0BAFF0028F3D0019B4FEA69 -:107150005802A98847EA4313F70701F00F0142EAF2 -:107160004A1243EA442300EB41109BB242EAC9228F -:1071700048BF4382B40792B208D518F001080382D1 -:10718000C28118BF4FF0640880F80D80710701D5E7 -:107190000383C282AC6804F1280003F063FF002877 -:1071A000C8D004F50E7003F05DFF0028C2D020683F -:1071B00003681B6A02B0BDE8F047184783789B0755 -:1071C00027D5036A10B5044682B0ABB1016911BB83 -:1071D000019301621946A06801F0DEFAB0B1A3780C -:1071E000616963F07F032278E161A37022B12046D8 -:1071F000FFF7DEF802B010BD012002B010BD6FF045 -:1072000070422169A06801F0B7FA68B9002002B0A5 -:1072100010BD00207047002301AA8068019301F08F -:1072200099FA0028F2DBEAD1019B002BD7D0D1E7F5 -:107230002DE9F047837805469C0777D588461907DE -:10724000914600F1B5806B6913EB09026ED2B9F17A -:10725000000F40D04F464FF0000AA868C3F308065D -:107260002969447914EA53243FD1002E3DD10029E5 -:107270006ED0AA78520676D5EA699A4273D901315E -:10728000296102398279436991401944B7F5007F39 -:1072900053D3B7F5806F70D303797A0A1B1B9342DF -:1072A00028BF1346426B8A424FEA432407D35E1835 -:1072B000B24204D24FF0FF3280F828A04263C06A85 -:1072C00042460668B66AB04780B36B693F1BA0446C -:1072D00023446B61C1D1EA699A4276D2AA784846C2 -:1072E000EB6162F07F03AB7025E08279023943697C -:1072F000914019442144002EC8D0C6F500740122E3 -:10730000BC4228BF3C46283003F0D8FE70B1304460 -:1073100026442246414605F083FAB6F5007FA86868 -:10732000D3D1283003F09EFE0028CED16B78002008 -:1073300043F001036B70BDE8F087C6F500746A691D -:10734000EB69BC4228BF3C469A4205D30522DAE7E6 -:10735000296A21B3296194E7AB7813F0200F14BF99 -:1073600005220122CFE705F1100201F0F3F9002810 -:10737000DCDB24D0A868296983E7436B8B4204D106 -:107380004FF0FF3380F828A04363C06A4246036889 -:107390005B6A98470028C9D04FF4007495E72846E7 -:1073A000FFF760F80028C1D02969A868296268E75A -:1073B000C169FFF761FD00287FF445AFB6E72846B5 -:1073C000FFF750F80028D5D1B0E7054B1B682BB16B -:1073D000AB78484663F07F03AB70ACE74846AAE75A -:1073E0003C2600202DE9F04F84468DB014461568E8 -:1073F00098460646894603AF01934FF0000EBCE85D -:107400000F000FC7BCE80F000FC7DCF80030656045 -:107410003B604346A4F80CE0002B3FD04FF0010A3C -:10742000A9EB0A0103A889B24901FFF725FD50B372 -:10743000002103A8FFF7C0FB074620B300250DE09D -:1074400003F064FE8046584603F074FF83464046CE -:1074500003F070FF834516D10D2D18D0EAB23946DE -:107460003046013500F0E4FEA38983462046002B18 -:10747000E6D1D4E901329342E2D1BBFA8BF0400964 -:107480000DB0BDE8F08F00200DB0BDE8F08F0AF11F -:10749000010A019B5FFA8AFA5345C1D20120EFE746 -:1074A0002DE9F04F07468DB016469A460DF10C0CAB -:1074B00002F1150402F1200501914FF000090FCFF0 -:1074C000ACE80F000FCFACE80F003B68CCF8003001 -:1074D0004FEAC91314F8012F43EA5903A54252FA9F -:1074E00083F35FFA83F9F3D133684FF000087360D8 -:1074F000A6F80C80BAF1000F4ED00127019B03A81B -:10750000D91B89B24901FFF7B7FC002855D00021EB -:1075100003A8FFF751FB00284FD0059A574500F10B -:10752000010B4FF0010492F828304FF0000543F0B2 -:10753000010382F828304FF00F030CBF47F04002E0 -:107540003A46C3724FF00003027003734FF000031A -:1075500080F80D90438306E0ABF80000013401355C -:107560000BF1020BE4B2B08918B9D6E901239A42B3 -:1075700016D0304603F0CAFD042DEBB2ECD90A2B2D -:1075800002D8ABF80300E9E70D2CABF80500E5D114 -:107590000137FFB2BA45B1D201200DB0BDE8F08F7E -:1075A000B8F1000F06D008F101084FF6FF705FFA3E -:1075B00088F8E1E74FF00108DEE700200DB0BDE8F4 -:1075C000F08F00BF02464FF0203152F8163B2DE9F4 -:1075D000F043C0F81610864684685160C2F8071060 -:1075E0001A782E2A14BF0120002003D113F8012F8E -:1075F0002E2AFBD0611E99420BD90A4602E0934223 -:10760000114606D01146013A91F800C0BCF12E0F88 -:10761000F5D19C424FF0000540F2868007260827EE -:10762000A946A84606E001330A264FF008091027AC -:107630009C425BD91A782E2A08BF9942F3D0222A9D -:107640000DD07C2A0BD0A2F15B0CBCF1020F06D945 -:10765000A2F12A0CBCF1050F21D82D2A1FD002F06F -:10766000C002802A5DD04E452FD299422CBF002007 -:1076700001200A2E08BF40F00100002847D09EF8E4 -:107680001630202B40D09EF8143001207E2131226C -:1076900073448EF815009975DA75BDE8F083A2F190 -:1076A0003A0CBCF1050FDAD9A2F1210CBCF15D0F47 -:1076B000D5D84E45D9D3A2F1610CBCF1190F28D809 -:1076C000203A3D43D2B2EDB201E000205F2209F141 -:1076D000010CF144013389F816205FFA8CF2062A76 -:1076E000914698BF8EF814209C42A3D89EF816307D -:1076F000202B09D00028C6D018EA050F18BF022594 -:107700008EF81550BDE8F0830020BDE8F0830B46ED -:107710008EE7A2F1410CBCF1190F98BF47EA0808A7 -:10772000D5E70133002083E7A846DFE72DE9F84FCE -:107730004FF0620900250F460446DFF8A0B04FF075 -:107740007E0A91F8148001F11606B8F1030FDBF8F8 -:10775000003028BF4FF003082B449DB208F104030A -:10776000DBB205F00F02581E2D09092A02F137017C -:1077700098BF02F13001FA18C3B291759845F0D163 -:1077800007EB08030021204683F816A0FFF774FBDF -:1077900001212046FFF710FA03460B2230469BB129 -:1077A00093F800C01946BCF1000F13D0DB7A1B0719 -:1077B000EED407F017FA0028EAD109F1FF3919F0E1 -:1077C000FF09C2D1484603E06078B0FA80F0400972 -:1077D000BDE8F88F0120BDE8F88F00BFC42B002062 -:1077E0002DE9F04F2DED028B8BB0CDE902038B68B4 -:1077F00007930B7813F0700F53D0029B1B78002B6C -:107800004FD1136990469A4A0E460C33A2FB0323CC -:10781000C3F3870298F815309807049200F0A78008 -:10782000571CFFB20023304619461C460693FFF74B -:1078300023FB08F11603A346A146A24608EE103A20 -:107840000594756900213046FFF7B6F9C5F34F1569 -:10785000034620B30278E52A29D042B3BC4238BFA0 -:1078600000242E2A2BD090F80BC0BCF10F0F54D05F -:107870001CF0080C23D1B9F1000F40F0D5800B2289 -:1078800018EE101A07F0AEF90028DAD198F8153082 -:1078900013F0010300F0E48001230593D1E773782E -:1078A00083B100200BB0BDEC028BBDE8F08F002C43 -:1078B00008BFAA46BC4201D20134E4B212B14FF073 -:1078C0000009BEE7039B9A05EBD503F00303013BD8 -:1078D000012BE6D8002C08BFAA46BC4203D348E0DF -:1078E000DCB2A74245D000213046FFF765F9631CA2 -:1078F0000028F5D17378002BD3D1A74239D9079D41 -:1079000005E02B7904EB0314E4B2A74231D93046E9 -:10791000FEF7C2FD0028F4D1C3E7B9F1000F19D179 -:1079200002F01F0B049959458BD112F0400988D001 -:10793000437B89460693BBF1010F82D1691C4B46FC -:107940004246304689B2FFF74DFD002808BF4FF090 -:10795000000976E70BF1FF3B5FFA8BFB5A45AED18E -:10796000437B069A9342E6D04FF0000969E701276E -:1079700058E7059B2BB141463046FFF7D7FE00285C -:107980008FD0013F42463046FBB20AEB03051F464B -:10799000ADB22946FFF784FD002882D06901304648 -:1079A000FFF76AFA00283FF47CAF00213046FFF76A -:1079B00003F9044600283FF474AF2022002107F0A9 -:1079C000BDF9D8F81620D8F81A302260636098F80C -:1079D0002030B8F81E20A372228198F8153003F0E9 -:1079E00018032373234B1B68002B3BD00DF123029C -:1079F0000DF1260109A89847BDF824302382BDF86F -:107A00002630E3819DF823306373079A92F828307B -:107A100043F0010382F82830039B2A46314602983E -:107A20000097FFF781FA3DE7BBF1010F7FF439AF13 -:107A30000A3001E013F8012F4FEACC11984241EAD5 -:107A40005C0152FA81F25FFA82FCF3D1069B634536 -:107A50007FF427AF4F46039B19053FF522AFDBE7C5 -:107A60001F46F8E745F62123238223836382CCE770 -:107A70004FECC44E3C2600202DE9F0411F460B7808 -:107A800082B00C46202B154603D114F8013F202B61 -:107A9000FBD02C60237863B32F2B2AD04FF0000843 -:107AA000294E211D204601AA03F0F8FB044670B1BF -:107AB000019BB3F5803F40D27F2B08F1010831D8FC -:107AC0003C2BD9B229D8212905D81F2909D8002053 -:107AD00002B0BDE8F0812239C9B226FA01F1CA0725 -:107AE000F5D42E2B01D0202B1CD123780BB12F2BBA -:107AF000D7D12B69013BFE2BE9D82378202B03D16A -:107B000014F8013F202BFBD02F2BF9D028463C60E6 -:107B100002B0BDE8F041FFF755BD5C29D7D005D9CB -:107B20007C29D4D0C5F81080AC60DEE73E3901294D -:107B3000F8D8002002B0BDE8F08108F10208AC607E -:107B4000C5F81080D1E700BF01210005F0B5002382 -:107B50008BB0019383789A0724D5016A054619B141 -:107B6000806800F019FEE8B101212846FEF7D0FC3C -:107B7000C0B1421E00F10A0C0024E30112F8011FFB -:107B800043EA5403944551FA83F3DCB2F5D1E52678 -:107B900000230670AF682B7007F12800AB7003F06C -:107BA00061FA10B900200BB0F0BD07F50E7003F0BC -:107BB00059FA0028F6D0386803681B6A98470028ED -:107BC000F0D0EB78002BEED0294601A8FEF7C0FEDE -:107BD0000028E7D0EB78002BE4D0012721E001A8B2 -:107BE000FEF7EAFF7B1CF9B20028DBD0C27A0F2A2D -:107BF000D8D102785FFA83FC9FB202F01F038B4258 -:107C0000D0D1437BA342CDD10670A96891F828302A -:107C100043F0010381F8283053060DD4EB78634517 -:107C2000C0D3A98801A8C91B89B24901FFF724F96B -:107C300000210028D3D1B5E7AC6804F1280003F097 -:107C400011FA0028AED004F50E7003F00BFA0028EC -:107C5000A8D0206803681B6A9847A4E72DE9F84379 -:107C6000DDF82090A2B105460C469846571801E071 -:107C7000BC420DD02B68204649465E6AC04721466B -:107C8000024628460134B0470028F1D1BDE8F88308 -:107C90000120BDE8F88300BF486810B50C4630B13C -:107CA0000B894A8901339BB29A420B8101D9206822 -:107CB00010BD0368012203495B68984700232068D0 -:107CC000238110BDFC0500202DE9F04F054687B04B -:107CD0008846924600214FF40072406A07F02EF861 -:107CE000286A28B103680C223A495B689847286AD9 -:107CF0006B6A4FF00009EE690AF1FF32DFF8E0C06D -:107D0000E968ADF814904C1CCDE903304FEA5A13E2 -:107D1000ADF816303368DF6A674526D16AB301EBE8 -:107D20000A07DFF8C0A00AE02146039A3046013472 -:107D3000D84700283FD0A7421ED033680498D3F814 -:107D400024B00028F0D0BDF81430BDF8162001335F -:107D50009BB29A42ADF81430E6D80368514601222E -:107D60005B689847ADF81490DEE703AB21463046D8 -:107D70000093194BB847F0B1286A20B1036802227A -:107D800016495B689847B8F1100F4FF0F8016A6A1E -:107D90004FF001030CBF04200C201170FF216A6A10 -:107DA000D15401339842FAD1E8696A6A0368E968F4 -:107DB0005B6A984718B9002007B0BDE8F08FD5E995 -:107DC0000231E86919446A6A03685B6A984707B038 -:107DD000BDE8F08FEC050020595C0000140600207F -:107DE0001D5C0000FC05002038B5436A4FF40075A7 -:107DF000044600212A46184606F0A0FF4FF0203125 -:107E0000EB22A0F80B50C0F803100346C0F807108F -:107E100090210270762099700222587094F82B10ED -:107E200059734AF65521208D1A74F822D8815A7553 -:107E30002269DA61A269A3F8FE111A6238BD00BF97 -:107E400070B504464FF400720021406A06F076FFD8 -:107E5000656A2269216805F2BF1003F07DF9A36904 -:107E6000226905F2C31021681A44013A03F074F93B -:107E700094F82A204AF6552385F8C2212269E06940 -:107E8000C5F8C621626AA169A5F8FE310368C5F884 -:107E9000CA1100215B6ABDE87040184770B5466999 -:107EA0004FF4807390F82BE00446A6F58072456A83 -:107EB0004360B2FBFEF202F2011C4FEA1C214FEAC2 -:107EC000410C81600CF1A10098420ED98033F21A66 -:107ED000B2FBFEF202F20111090A4FEA410C0CF169 -:107EE000A1008342F2D3C4E901311B1AA2F6F57155 -:107EF00003F18000B1F5704F20614FD20CF1210CDD -:107F00008133204602FB0EC2E360B2F5803FA261DE -:107F100034BF0423062384F82A3001232385FFF786 -:107F20008FFF08B9002070BD2046FFF75DFF2922B2 -:107F3000A1684FF0203385F826204622C5F82F305F -:107F4000802085F836205422C5F82B30C5F8323011 -:107F5000312385F838203622E982412185F83930ED -:107F600085F837104FF4007185F8240085F83A2021 -:107F70000F4BE069C5F827300368A5F81110626A55 -:107F800021695B6A98470028CCD062682046E36884 -:107F90001021D21ABDE87040FFF796BE206A002873 -:107FA000C0D00368132203495B689847002070BD66 -:107FB00087D61200C0050020F8B546694FF400537B -:107FC00090F82BC04FF48042A6F58041036142F245 -:107FD000090E0446456A4260B1FBFCF101F18103E0 -:107FE000DB0983600EEB4300904240F2B68002F55D -:107FF0000052B11AB1FBFCF101F18103DB090EEB78 -:1080000043005F008242F2D3C4E901234FF6F473C8 -:10801000994240F2978001FB0C2CA2F500522046B9 -:10802000D21B92B202F5005322854D4AE360ACF5B3 -:108030000053944594BF4FF00B0C4FF00C0CA36110 -:1080400084F82AC0FFF7FCFE08B90020F8BD2046DE -:10805000FFF7CAFEA16829224FF020338020696211 -:1080600085F8422054214622C5F84B3085F840005F -:108070004120C5F84730C5F84E30022385F852201C -:10808000332285F85410322185F8552085F85300A5 -:1080900085F85610EB62E069324B334A2B63036874 -:1080A000C5F843205B6A626A216998470028CCD0F2 -:1080B000E069216903680631626A5B6A98470028B3 -:1080C000C3D04FF400720021606A06F037FEE06909 -:1080D000264A0368C5F8FC2121695B6A0231626A9D -:1080E00098470028B1D0E069216903680831626AC5 -:1080F0005B6A98470028A8D04FF0FF33E0691C4A1C -:10810000C5E97A331B4B2A60C5F8E431036821695D -:10811000626A5B6A01319847002896D0E06921695C -:108120000368626A07315B6A984700288DD0A268AD -:10813000204694F82B30202103EB4202BDE8F840A2 -:10814000FFF7C2BD206A00283FF47FAF0368132207 -:1081500009495B6898470020F8BD5F0056E700BFFB -:108160000004FB000100060087D61200000055AA9B -:108170005252614172724161C005002038B5044617 -:108180000D68C16108466262EA692362904700F2A5 -:10819000FF736061DB0A062B236024D9102B13D8F0 -:1081A0000223B0F5800F84F82B3020462ED2FFF743 -:1081B00075FE0546206A05B320B103680D221949F2 -:1081C0005B689847284638BD202B23D9402B23D9FC -:1081D000802B23D9B3F5806F22D9B3F5004F8CBF24 -:1081E00080234023DDE7206A20B1036814220E4972 -:1081F0005B6898470025284638BD0028FAD00368F8 -:108200000F220A495B689847284638BDFFF7D4FE1D -:108210000546CFE70423C4E70823C2E71023C0E7DD -:108220002023BEE7A005002088050020B00500201F -:10823000042A04D801EB4202B2F8010070470A2A6E -:1082400003D801EB4202908870470C2A03D801EB57 -:108250004201C88870470020704700BFF8B5047815 -:108260000E467CB114F06004174607D0012A09D9E4 -:108270002F22002301200A704B70F8BD2146FEF723 -:1082800047F918B9002318463370F8BD0346A446D1 -:10829000082111E0027B114203D00EF1200E5FFA9B -:1082A0008EFE651CBD42EDD20CF1010C06F804E017 -:1082B000ECB2BCF10C0F10D0BCF1080F11D013F8C8 -:1082C00001EBAEF14102192AE4D9BEF1200FE8D149 -:1082D0000CF1010CBCF10C0FEED1002320463355FC -:1082E000F8BD1A78202AF8D010214FF02E0ED8E7CA -:1082F0002DE9F04F00248BB0037889460194002BC0 -:1083000055D0C3780646002B58D0014601A89046A8 -:10831000FEF71EFB00284AD0F078002843D008F171 -:10832000FF38CB464FF0010AC844B18801A8A1EB41 -:108330000A0189B24901FEF79FFDC0B3002101A8DF -:10834000FEF73AFC98B3C37A0F2B30D103785FFA6B -:108350008AF103F01F038B4229D1471C0025042D0D -:10836000EBB23FD83B8874BB03F5205189B2B1F51D -:10837000006F3ED3A3B118465946424602F03CFF77 -:108380008346A0B10024013502370D2DE7D10AF153 -:10839000010AF1785FFA8AF31FFA8AFA9942C4D285 -:1083A000ABEB0900D946002389F8003003E0002335 -:1083B000184689F800300BB0BDE8F08FFFF74EFF8C -:1083C0000BB0BDE8F08F03F5105189B2B1F5806FA5 -:1083D000EDD20A4AC3F3090302EA8420184300F5E8 -:1083E0008030C9E70A2B94BFB7F80330B7F80530DF -:1083F000B9E7B1F5806FDAD21C46C4E700FC0F0084 -:10840000FFF776BF2DE9F843DDE90887C3B1814660 -:108410000C4615465E1802E0C047B44210D0D9F8A9 -:10842000003021462A4648461B69984703463A468B -:10843000204629460134002BEED11846BDE8F883CA -:1084400001231846BDE8F88310B41468B4F5807FA2 -:10845000A44628BF4FF4807C01EB4C00814207D238 -:1084600031F8023B13B95368013353608842F7D89F -:10847000A4EB0C0414605DF8044B704710B414684E -:10848000802CA44628BF4FF0800C01EB8C00814269 -:1084900007D251F8043B13B9536801335360884243 -:1084A000F7D8A4EB0C0414605DF8044B704700BFD0 -:1084B0002DE9F843C37904460D461746202B59D0C1 -:1084C000102B30D00C2B51D1027AC1F34E018369AD -:1084D00000F50E7911FA85F1A2F1020248468EB23A -:1084E000B2FA82F2C1F34621520901EB03085200AD -:1084F000414602F0E3FD002838D0C6F30806731C9D -:10850000865DB3F5007F23D018440378EA07E2695B -:1085100046EA03234CBF1B09C3F30B039A4240D224 -:108520000020BDE8F883027AC1F30721836900F5D2 -:108530000E70A2F102021944B2FA82F252095200FC -:1085400002F0BCFD90B16D0005F4FF75435B25E0C2 -:10855000227A08F101014846A2F10202B2FA82F23F -:108560005209520002F0AAFD0028CED14FF0FF3090 -:10857000BDE8F883027A816900F50E70A2F102026B -:1085800001EBD511B2FA82F25209520002F096FDC7 -:108590000028EBD0AD0005F4FE754359E2699A421C -:1085A000BED301203B60BDE8F88300BF2DE9F8434E -:1085B000C37905460C461646202B48D0102B2DD0EB -:1085C0000C2B41D1C1F34E01836900F50E7911FAEC -:1085D00084F11FFA81F8C1F34621CF18037A484687 -:1085E000022B394614BF0122032202F067FD58B363 -:1085F00014F00104C8F308033FD0C25C02F00F027C -:1086000042EA0612C2540133B3F5007F3AD0C6F3F2 -:108610000712034401201A70BDE8F883027AC1F3FF -:108620000721836900F50E70022A194414BF012244 -:10863000032202F043FD034630B16400012004F43C -:10864000FF741E53BDE8F8830020BDE8F883037A69 -:10865000816900F50E70022B01EBD41114BF0122C9 -:10866000032202F02BFD03460028EDD0A4000120D8 -:1086700004F4FE741E51BDE8F883C6540133B3F50B -:10868000007F15D12B7A791C4846022B14BF01229A -:10869000032202F013FD03460028D5D0C6F30712CB -:1086A000002CB7D1197821F00F0141EA1212B1E77D -:1086B000C6F307120344F5E72DE9F041C46882B020 -:1086C00005460E468C42904640D301270134EB69A3 -:1086D00001AA2846A34205D29FBBEC6801273C446F -:1086E000A3422ED3A64218BF012C214629D9FFF759 -:1086F000DFFE002825DBE9D0019B002BE6D107B186 -:10870000EC60EB69A3421CD36FF07042214628460F -:10871000FFF74CFF0746A0B13EB96B6A002B01DBA7 -:10872000013B6B62C8F800400CE0012E09D0EB69F8 -:108730009E4206D8314622462846FFF737FF0028DA -:10874000EBD10027384602B0BDE8F0810C46002787 -:10875000BCE700BF01290CD910B4C4698C4203D313 -:108760005DF8044BFFF7A4BE4FF0FF305DF8044BFB -:1087700070474FF0FF30704701290BD910B4C4691E -:108780008C4203D35DF8044BFFF710BF00205DF867 -:10879000044B70470020704770B5054682B00C4608 -:1087A0001DE0EB699C421FD8FFF782FE064621467A -:1087B0000022002E284617DBEB699C4214D8FFF7F5 -:1087C000F5FE621E80B16B6A002B03F10103A8BFA6 -:1087D0006B62EB68A342019C88BFEA602EB1012C5A -:1087E000214601AA2846DCD8002002B070BD00BF97 -:1087F0002DE9F0470646406A84B000281BDAF2797A -:108800000C2A1BD1F7697B1C022B40F2CD8002247D -:108810000025214602AA3046FFF74AFE002804F14F -:10882000010306DB57D1A7421C465CD0F269934294 -:10883000EFD94FF0FF3004B0BDE8F087F1690020B8 -:1088400096F8383201313469DB07CDE9021000F1C6 -:10885000858000214FF0FF33202A06F5127786F835 -:108860003812C6F8443242D0D6F800804F4BD8F8C0 -:108870000020D6F818A095699D4278D1002C00F010 -:1088800082800AEB0409136951463A4640469847EC -:108890000028CED00299B1F5807F8E4628BF4FF4D4 -:1088A000807E07EB4E0CBC450BD9039D3B46002256 -:1088B00033F8024B0CB9013502469C45F8D802B199 -:1088C00003950AF1010AA1EB0E01D14502915AD09C -:1088D000D8F80020D7E7029A002AA4D1A74205F1D0 -:1088E00001051C46A2D1284604B0BDE8F087D6F8A1 -:1088F00000A02E4BDAF80020D6F8189095699D421A -:1089000046D1002C3FD009EB0408136949463A468A -:108910005046984700288CD0DDF808C0BCF1800F85 -:10892000E64628BF4FF0800E07EB8E02BA420BD905 -:10893000039D3B46002153F8044B0CB90135014619 -:108940009A42F8D801B1039509F10109ACEB0E0385 -:10895000C845029317D0DAF80020D6E706F50E7066 -:1089600002F080FB00283FF464AFF27971E7234600 -:1089700002AC3A465146019440460D4C0094A8473B -:1089800000283FF456AF0398706204B0BDE8F0874A -:10899000234602AC3A46494601945046054C0094A1 -:1089A000A8470028EFD144E7002044E7C563000052 -:1089B000096400003D64000070B5002304461546BC -:1089C00001204FF0FF3204F128062160E371E060DE -:1089D000E162C4F83C1284F8283084F838326263CB -:1089E000C4F84422CDB1042D01D9002070BD1A462F -:1089F0001946304602F062FB6FF0704300F5DF72FB -:108A00002B441D0102EB03130028EED01979002935 -:108A1000EBD0525D5206E8D19D68002229463046CF -:108A200002F04CFB0028E0D0B0F80B30B3F5007F2B -:108A3000DBD1037C5A1E2372012AD6D8417B4B1E00 -:108A40000129217163714FF00003A37144D0012209 -:108A500052000133D2B2DBB2914204D0082BF7D1DD -:108A60000020A37170BD1E46A371C18A216109B99E -:108A7000416A2161C289B0F811302A4463815B01E7 -:108A8000A26190F810C003F2FF1301FB0C2202EB6D -:108A900053232262B0F81320636102B9026AED1A0F -:108AA000AB18F3405A1CE2614FF0FF32626240F6AD -:108AB000F47293420CD94FF6F47293420AD9C26A07 -:108AC000202322620120E3712163C4F8401270BDAB -:108AD0000C23F7E71023F5E71E46C6E7F8B5002696 -:108AE0008F6B0D460446C0E90E669FB101462420F7 -:108AF00000F0DCF8068086708446AD6BA0630FCD75 -:108B0000ACE80F000FCDACE80F002B68CCF80030BC -:108B10002046F8BDCB6B002BFAD00146382000F080 -:108B2000C5F880F8317047860246EB6BE06303F1CD -:108B300030071E68103353F80C5C103253F8080CE1 -:108B400053F8041CBB4242F8106C42F80C5C42F82B -:108B5000080C42F8041CECD11B6820461360F8BDD9 -:108B600010B50446806B10B1FDF7E2FC30B9E06B44 -:108B700010B1FBF7CFFB20B9002010BD0023A36389 -:108B800010BD0023E36310BD002952D02DE9F04150 -:108B90000446806B0D4617461E4610B1FDF7C8FC13 -:108BA000A0BBE06B10B1FBF7B5FBB8BBD5F8808478 -:108BB000B8F1000F11D02146242000F077F8334699 -:108BC00000263A4606808670A063D5F88014FDF72B -:108BD000B7FE58BBA063BDE8F081D5F8843493B1EB -:108BE0002146382000F062F8334680F831803A465A -:108BF000A0F83280E063D5F88414FBF7BFFFA8B972 -:108C0000E063BDE8F0810020BDE8F0810023D5F8E5 -:108C10008084A363B8F1000FCDD1DEE70023D5F83F -:108C20008084E363B8F1000FC5D1D6E70120BDE829 -:108C3000F0810020704700BFF8B50446806B0D46F8 -:108C4000174610B1FDF774FC38BBE06B10B1FBF7B1 -:108C500061FB38BBAE6B76B12146242000F026F8CC -:108C600000213A4601808170A063A96BFEF7CEF91E -:108C700088B9A063F8BDE86B0028FBD021463820F6 -:108C800000F014F83A4680F831604686E063E96BFC -:108C9000FBF77CFF20B10120F8BD0023A363D9E7D7 -:108CA000E063F8BD0023E363D4E700BF08467047E4 -:108CB0002DE9F041002604469846C0F88814C0F813 -:108CC000806401464FF490601746FFF7EFFF42467D -:108CD00080F84464054680F87964A0F87A64C4F8A2 -:108CE0008404D4F88814FDF7E7FAA0BB00262146D7 -:108CF00040F26C40C4F88464FFF7D8FF0223C671C9 -:108D00004246A0F84864054680F84A640372C4F8F5 -:108D10008004D4F88814FFF74FFE38B900231A4AAC -:108D200018461360C4F88034BDE8F08105F5896603 -:108D30003046FDF7FDFB29463046FDF737FE00289B -:108D4000ECD0124B1A68AAB91D600F4BAFB10120CD -:108D50001C60BDE8F08105F589663046FBF7DAFA5C -:108D600029463046FBF704FB0028BFD0084B1A68A1 -:108D7000002AE9D0044B002FE9D11A68002AE6D076 -:108D80000120BDE8F08100BFCC270020D0270020C3 -:108D9000BC26002070B500254FF47A760446456065 -:108DA00005738660C0E91255034D40F8105BFFF76C -:108DB000EBFE204670BD00BFE00700204FF0FF3003 -:108DC000704700BF407C7047007D7047407D704712 -:108DD00001207047007F70472DE9F0471E46C37C95 -:108DE00005460C46022B9146089F28D02B68214649 -:108DF00028461B6E984798B1AC61B9F1000F12D0AC -:108E000004EB090801E0A0450DD039462046B047E3 -:108E10002B6801462846DB6D013498470028F2D1C3 -:108E20000020BDE8F087AB69287F4B44AB61002888 -:108E3000F7D12B6828465B6EBDE8F0471847836979 -:108E40008B42D3D1D9E700BF704700BF043002F096 -:108E5000B5B800BF10B50446202103F07DFD2046C3 -:108E600010BD00BF2DE9F0411F46C37C05460E46EC -:108E7000022B144624D02B68314628461B6E984797 -:108E800078B1AE6187B1002601E0B7420CD02A6804 -:108E9000214628460136D26D04F50074904700281B -:108EA000F3D10020BDE8F081AB69287F3B44AB6182 -:108EB0000028F7D12B6828465B6EBDE8F0411847C3 -:108EC00083698B42D7D1DDE72DE9F041204E07467B -:108ED00000F10408356805F51675ADB203E0336896 -:108EE000EB1A1B0410D4404602F06CF8FF2804462D -:108EF000F5D1FD21404602F083F8BB7CCBB90023BD -:108F00000120FB74BDE8F0811E23B87C7B7400282F -:108F1000F8D0387C012102F009F8FF21404602F028 -:108F20006FF8404602F022F800231846BB74BDE8F3 -:108F3000F0810121387C01F0F9FF2146404602F022 -:108F40005FF8404602F012F80023BB74D7E700BF79 -:108F5000C42B00202DE9F041C37C012B35D0867C49 -:108F600004464EB1043002F02DF8B0F1FF0518BFF1 -:108F700001252846BDE8F081071D4FF0010838465D -:108F800001F0D6FF3146207C01F0D0FFFF213846AA -:108F900002F036F8384684F8128002F013F8A37C09 -:108FA000B0F1FF0518BF0125002BE2D04146207C1F -:108FB00001F0BCFFFF21384602F022F8384601F0EC -:108FC000D5FF2846A674BDE8F08100252846BDE8F7 -:108FD000F08100BF2DE9F843204F044688469146B2 -:108FE0003D68061D05F59675ADB203E03B68EB1ACA -:108FF0001B040DD4304601F0E5FFFF282075F5D0A5 -:10900000FE281AD01823A07C637430B9BDE8F88319 -:109010001D23A07C63740028F8D0207C012101F07E -:1090200085FFFF21304601F0EBFF304601F09EFF47 -:1090300000231846A374BDE8F8834A4641463046EB -:1090400001F0CCFF207538B9304601F0BBFF304647 -:1090500001F0B8FF0120D9E72523D4E7C42B002075 -:10906000F0B5002783B00C2104463A46C77400F0DF -:109070005BF8B0B9A67C1EB90126304603B0F0BD3E -:1090800005460121207C01F051FF201DFF210190A8 -:1090900001F0B6FF019801F069FF3046A57403B0F6 -:1090A000F0BD0923A67C6374002EE6D0251D207C2C -:1090B00001213E4601F03AFFFF21284601F0A0FFC2 -:1090C000284601F053FF3046A77403B0F0BD00BF3F -:1090D000C27C022A03D0012A04D001207047036811 -:1090E0005B6E1847FFF7BCBF38B503680D460D49E6 -:1090F00004461A6A8A420CD1C27C022A04D0012A90 -:109100000BD00120257738BD5B6E98470028F8D139 -:1091100038BD90470028FBD0F3E7FFF7A1FF0028F8 -:10912000F6D0EEE7917000002DE9F041036882B0BF -:109130000F463549019206461A6A8A425ED1C27CC0 -:10914000022A41D0012A5BD0B47C002C47D0351DC7 -:109150000C2F11D0DFF8B480D8F8004004F59674D5 -:10916000A4B204E0D8F80030E31A1A0434D4284634 -:1091700001F028FFFF28F5D10DF1040802AC47F0FB -:109180004001284601F03CFF14F8011D284601F07B -:1091900037FFA045F8D1002F28464FF00A040CBF36 -:1091A0009521872101F02CFF284601F00BFF28466E -:1091B000013C01F007FF0306A4B2307501D5002C75 -:1091C000F5D102B0BDE8F0815B6E98470028BBD1B5 -:1091D000FF2002B0BDE8F081002FCDD0F8E7351DAB -:1091E000284601F0A5FE2146307C01F09FFEFF21BC -:1091F000284601F005FF0123B374A9E79047E5E78E -:10920000FFF72EFFE2E700BF91700000C42B0020A3 -:109210002DE9F04788B005464FF00008174601AC2D -:109220002E1D85F8128085F8118085F8158084E858 -:109230000E009DF80400287401F074FE0121287CC2 -:1092400001F074FE6C490723C5E9021394E8070096 -:1092500005AB83E8070030460ECB01F073FEAC7C13 -:1092600085F81380002C67D00A240121287C01F0A6 -:109270005DFEFF21304601F0C3FE611E11F0FF04C8 -:10928000F7D121460A24287C01F050FE002228460E -:109290001146FFF749FF012804F1FF3304460AD0C5 -:1092A00013F0FF04F2D10123A87C6B74002851D184 -:1092B00008B0BDE8F0874FF4D57208212846FFF7C3 -:1092C00033FF420757D56C752B68DFF830A19B6DD3 -:1092D000534561D1687DA0F10204DFF82491B4FA0E -:1092E00084F4D9F80030640903F5FA68A4071FFA7A -:1092F00088F805E0D9F80030A8EB03031B0449D433 -:10930000372100222846FFF70FFF22462921284651 -:10931000FFF70AFF0028EDD12B689B6D534565D1FF -:10932000687D022849D0AB7CCBBB07230120C5E96F -:10933000027308B0BDE8F087304601F0F9FD214620 -:10934000287C01F0F3FDFF21304601F059FE012396 -:10935000AB7489E7287C012101F0E8FDFF2130464C -:1093600001F04EFE304601F001FE00231846AB74BA -:1093700008B0BDE8F087022304246B75304601F085 -:1093800021FE631E287513F0FF04F7D1AA289BD095 -:10939000062389E7172387E7284698479BE701219B -:1093A000287C01F0C3FDFF21304601F029FE304644 -:1093B00001F0DCFD0023AB74B7E700223A21284618 -:1093C000FFF7B2FEA8B9304601F0FCFD00F0C00086 -:1093D000C02801D103236B75304601F0F3FD304600 -:1093E00001F0F0FD304601F0EDFD9CE7284698477E -:1093F00097E7122358E700BF801A06008D6D000022 -:10940000C42B0020F8B500220D463A210646FFF78E -:109410008BFEE0B9371D2C1D384601F0D3FD04F852 -:10942000010DA542F8D1B47C14B901242046F8BD41 -:10943000307C012101F07AFDFF21384601F0E0FD8A -:10944000384601F093FD00232046B374F8BD122383 -:10945000B47C7374002CE9D0341D307C012101F000 -:1094600065FDFF21204601F0CBFD204601F07EFD89 -:1094700000231C46B3742046F8BD00BF70B51646E5 -:1094800082B000220446FFF74FFEB0B11B23637485 -:10949000A07C08B902B070BD251D207C012101F01F -:1094A00045FDFF21284601F0ABFD284601F05EFD99 -:1094B00000231846A37402B070BD05461022314641 -:1094C0002046FFF787FD0028E2D0A67C002EE1D0E1 -:1094D000207C012101F02AFD201DFF21019001F0D7 -:1094E0008FFD019801F042FD3046A57402B070BDB9 -:1094F0000368254ADB6C934200B585B00FD16A46FC -:109500000921FFF7BBFF38B19DF8003013F0C0030D -:1095100008D0402B27D0002005B05DF804FB694639 -:109520009847F0E79DF809309DF80A2003F00303FF -:109530009DF806109DF807005B0001F00301800014 -:109540009DF808C043EAD2139DF8052040EA812027 -:1095500002F00F0240EA9C1013440130073B984090 -:1095600005B05DF804FB9DF809009DF80730013057 -:109570009DF8082003F03F0300EB034000EB0220BE -:10958000800205B05DF804FB6D78000003680A46B0 -:1095900030B59B6D83B0164D0446AB4224D1407D5F -:1095A00003284FF01201204618BF5202FFF7BCFDFE -:1095B00020B901231846E37403B030BD0C23A07C0E -:1095C00063740028F8D0251D207C012101F0AEFC39 -:1095D000FF21284601F014FD284601F0C7FC0023B6 -:1095E0001846A37403B030BD01919847019AD7E79C -:1095F0008D6D0000F8B51446C27C06460D46012A62 -:109600001F4602D183698B4205D029463046FFF7B9 -:10961000BDFF80B1B56187B1002501E0AF420CD03C -:1096200021464FF400723046013504F50074FFF70F -:10963000D1FC0028F2D10020F8BDB369307F3B4453 -:10964000B3610028F8D13046BDE8F840FFF708BD07 -:109650002DE9F84F9B46C37C06460C46012B154668 -:10966000DDF82890DDF82C8002D183698B4205D08B -:1096700021463046FFF78AFFB0B1B461BBF1000F5D -:1096800015D004EB0B0A02E0C847A2450FD04FF4F7 -:10969000007229463046FFF79DFC074642462046A9 -:1096A00029460134002FEFD10020BDE8F88FB369BF -:1096B000307F5B44B3610028F7D13046BDE8F84FF6 -:1096C000FFF7CEBC03682DE9F0415F69164B9F425E -:1096D0001FD1C37C04460D461646012B02D1836977 -:1096E000994205D029462046FFF750FF70B1A56189 -:1096F0004FF4007231462046FFF76CFC30B1A3698D -:10970000207F0133A36148B1BDE8F0810020BDE8AE -:10971000F081BC460123BDE8F04160472046BDE82A -:10972000F041FFF79DBC00BFB575000003680A4615 -:1097300030B59B6D83B0164D0446AB4224D1407DBD -:1097400003284FF01901204618BF5202FFF7ECFC26 -:1097500020B902230120E37403B030BD0E23A07CA6 -:1097600063740028F8D0251D207C012101F0DEFB68 -:10977000FF21284601F044FC284601F0F7FB0023B6 -:109780001846A37403B030BD01919847019AD7E7FA -:109790008D6D000003682DE9F043DB6C1746414AEC -:1097A00085B004460E46934245D16A460921FFF72B -:1097B00065FE0546B5B19DF80A305A0618D5637D99 -:1097C000032B01D076027F02324620212046FFF78C -:1097D000ABFC28B93A4621212046FFF7A5FC70B31F -:1097E00026236374A57C9DB9284605B0BDE8F083A7 -:1097F00003F03F039DF80B205B0043EAD2137A1C71 -:1098000032431342DBD02723A57C6374002DEBD0B9 -:10981000251D207C012101F089FBFF21284601F054 -:10982000EFFB284601F0A2FB00231D46A374284647 -:1098300005B0BDE8F083694698470546BAE7024699 -:1098400026212046FFF770FC0028C9D1DFF8588098 -:1098500042F2107704F10409D8F800301F44BFB277 -:1098600004E0D8F80030FB1A1B0417D4484601F076 -:10987000A9FBFF280646F4D1A37C002BB4D001211C -:10988000207C1D4601F052FB3146484601F0B8FBF2 -:10989000484601F06BFB0023A374A5E728236374FB -:1098A000A0E700BF6D780000C42B002070B5002237 -:1098B00082B00E4609210446FFF736FCB0B11B23E7 -:1098C0006374A07C08B902B070BD251D207C012105 -:1098D00001F02CFBFF21284601F092FB284601F005 -:1098E00045FB00231846A37402B070BD0546102244 -:1098F00031462046FFF76EFB0028E2D0A67C002E02 -:10990000E1D0207C012101F011FB201DFF210190FD -:1099100001F076FB019801F029FB3046A57402B0F6 -:1099200070BD00BF70B5002282B00E460A21044609 -:10993000FFF7FAFBB0B11B236374A07C08B902B037 -:1099400070BD251D207C012101F0F0FAFF21284681 -:1099500001F056FB284601F009FB00231846A374CA -:1099600002B070BD0546102231462046FFF732FB9B -:109970000028E2D0A67C002EE1D0207C012101F05D -:10998000D5FA201DFF21019001F03AFB019801F06A -:10999000EDFA3046A57402B070BD00BF70B5051D6C -:1099A00016460446284601F02BFB4FF40072314660 -:1099B000284601F02FFBFF21284601F021FBFF2163 -:1099C000284601F01DFB284601F0FCFA00F01F03B9 -:1099D0002075052B04D02023A07C637410B970BDC2 -:1099E000012070BD207C012101F0A0FAFF21284652 -:1099F00001F006FB284601F0B9FA00231846A374CB -:109A000070BD00BF2DE9F041174D06460F4600F12D -:109A100004082C6804F51674A4B203E02B68E31A5A -:109A20001B040CD4404601F0CDFAFF28F6D13A468B -:109A3000FC213046FFF7B2FF18B1BDE8F0812423C6 -:109A40007374B07C0028F8D0307C012101F06EFAEC -:109A5000FF21404601F0D4FA404601F087FA002386 -:109A60001846B374BDE8F081C42B0020036870B5BC -:109A70009B6D1646224A82B004460D4693423CD165 -:109A8000407D03284FF01801204618BF6D022A467A -:109A9000FFF74AFB0546B0B10D236374A07C08B9FB -:109AA00002B070BD251D207C012101F03FFAFF218D -:109AB000284601F0A5FA284601F058FA0023184676 -:109AC000A37402B070BD3246FE212046FFF766FF48 -:109AD0000028E3D0A67C002EE2D0207C012101F0FA -:109AE00025FA201DFF21019001F08AFA019801F06A -:109AF0003DFA3046A57402B070BD9847C1E700BF7B -:109B00008D6D000010B4047F34B104680123A46A91 -:109B1000A4465DF8044B60475DF8044BFFF7A6BF11 -:109B200010B584B004460DF1040C8CE80E009CE8DE -:109B30000E00FFF76DFB20B19DF8053003F0010327 -:109B4000237704B010BD00BF00207047002070478D -:109B500000207047704700BF084B0021084A0948A1 -:109B600010B499631C6B146012685DF8044B1A639F -:109B70009A6C22F081029A640170704700002C40B8 -:109B800038260020F82B0020034B586A80F08070A4 -:109B9000C0F30060704700BF00002C40014B1878F4 -:109BA000704700BFF82B00202B4A2C4B526AD3F889 -:109BB00000312B49C2F3C22203F03F03013270B5DA -:109BC000284C4FF47A75A4FB034305FB00F09B0877 -:109BD000B1FBF3FEBEFBF2FEB0EB1E1F35D201233C -:109BE0001E465B001A01BEFBF2F2824201D9FF2B36 -:109BF000F6D9BEFBF3F2360290422AD24FEA430C6A -:109C0000012200E0A446154603EB0C040132BEFB22 -:109C1000FCF1814217D9102AF4D1F0254FF47A7360 -:109C20001149124A03FB0CFCBEFBFCF30B60104B0A -:109C3000D16A0B402B43334343F46023D362536A0E -:109C40001B07FCD570BD2D01E8E7724600260123F5 -:109C5000D2E79C460025E1E700C00F4000800D40A0 -:109C600000EC695EABAAAAAA0426002000002C40E2 -:109C70000F00F0FF014B1878704700BFF61A002064 -:109C8000014B1868704700BF3826002010B4074CFD -:109C90008C460FCCCCF800000120CCF80410CCF896 -:109CA0000820CCF80C305DF8044B70470C260020DF -:109CB00010B4074C8C460FCCCCF800000120CCF837 -:109CC0000410CCF80820CCF80C305DF8044B704739 -:109CD0001C260020024B01201B680B60704700BF50 -:109CE0002C260020704700BF10B504460C2102F05E -:109CF00033FE204610BD00BF044B1B7823B1044B3C -:109D000018780230C0B2704701207047F52B002050 -:109D1000F62B0020184B1A7812F0C0020FD0402A00 -:109D200001D000207047587ADA79197A013002F0B0 -:109D30003F0300EB034000EB0120800270475A7A9A -:109D40009979D87902F0030293F808C001F0030171 -:109D50008000520040EA812000B593F80AE040EA12 -:109D60009C105B7942EADE12013003F00F031344CA -:109D7000073B98405DF804FB1C260020404A052064 -:109D8000404938B5D2F800413F4B44F080043F4D84 -:109D9000C2F80041D2F8004124F03F04C2F800416B -:109DA000D2F8004144F01804C2F80041D2F8004152 -:109DB00024F08004C2F80041D3F8802042F00C0265 -:109DC000C3F880205A6A22F460525A62DA6942F477 -:109DD0008032DA615A6A42F400625A62C1F8CC01F8 -:109DE000C1F8D001C1F8BC01C1F8C001C1F8C4017B -:109DF000C1F8C801AA6C264B42F00042AA64EA6A84 -:109E00001343EB62EC6A14F08074FBD14FF4C8701A -:109E1000FFF7CAFE1B4B47F2B80241F2B801C3F884 -:109E2000CC411C48C3F8D041C3F8BC41C3F8C04181 -:109E3000C3F8C441C3F8C841C3F8BC23C3F8C02366 -:109E4000C3F8AC23C3F8B013C3F8B4231249C3F862 -:109E5000B823124B6863C1F8F8314FF0E0234FF498 -:109E600080420F49602081F86E00C3F80C21EB6A34 -:109E7000064A43F00063EB62D36A1B01FCD438BD91 -:109E800000800D4000801F4000C00F4000002C40AB -:109E9000008000010B007F11001C0020197B0000D6 -:109EA00000E400E02DE9F04102F014FC174E184DDB -:109EB0000746DFF8748004E002F00CFCC01B40454C -:109EC0001BD8346B2C40F7D0124A0021124B117072 -:109ED000326B1A601968114A31631B68134209D04A -:109EE0000F491F240F4B40F27A2200200C701A6099 -:109EF000BDE8F0810120BDE8F081064A064B1470F0 -:109F0000326B1A601B683363EAE700BF00002C4025 -:109F100002007F11F72B00203826002000007F115F -:109F2000F61A00200826002040420F002DE9F843D1 -:109F3000264C0F462378002B38D1254B5A6AD20580 -:109F40002BD5234DDFF89480AB6A43F48033AB62AA -:109F500002F0C0FB064604E002F0BCFB801B40455B -:109F60002AD86B6A13F48069F6D007F13C0C1848C4 -:109F700007F50F77436A5B05FCD5ACF1400353F856 -:109F8000042F9C450262FAD10CF1400CBC45F1D182 -:109F9000012318462370BDE8F8839A6A22F48032C0 -:109FA0009A629A6A42F400329A62CAE7FFF77AFF2D -:109FB0000028C2D1BDE8F88306492124064B4FF49E -:109FC0007E7248460C701A60BDE8F883F72B0020BB -:109FD00000002C40F61A00200826002040420F0006 -:109FE0002DE9F041074688461F4C02F073FB1F4ED7 -:109FF000054604E002F06EFB431BB34224D8636ABB -:10A00000D907F7D4BB02C4F8088020D427F0FF0397 -:10A01000154C174EE36002F05DFB144F054604E05B -:10A0200002F058FB401BB8420ED8236B3342F7D0E6 -:10A03000226B104B1A601A6822631A68D20703D584 -:10A040001B6813F4702F0BD00020BDE8F081A26CC8 -:10A05000FBB222F0FF02A264A26C1343A364D5E713 -:10A060000120BDE8F08100BF00002C4040420F00FD -:10A0700001000F0038260020154B30B50D4685B085 -:10A080001968FFF7ADFF08B3124B05F10F041A6909 -:10A0900000925969019199690291DB690393002348 -:10A0A00001E05EF8102C03F0030C01334FEACC0CF6 -:10A0B00023F0030E0F2B22FA0CF20EF1100104F81C -:10A0C000012D0DEB010EECD10023EB7305B030BD7B -:10A0D0003026002000002C4010B5037ADB0705D5A0 -:10A0E000154B1B68B3B1BDE810401847134B1B78E4 -:10A0F0003BB9134B5C6A84F08074C4F3006420465F -:10A1000010BD0F4B0F4C1B6B1C40B4FA84F4640958 -:10A11000204610BD0C4B1C78002CF0D00B4B0C488B -:10A120001968FFF75DFF0028E9D0054B1C6984F42E -:10A130008074C4F30024E2E734260020F72B0020CB -:10A1400000002C4002007F11F42B0020302600205C -:10A1500000001A0D08B5044B04481968FFF740FFCA -:10A1600008B1034B186908BD3026002000001A0D05 -:10A1700000002C4008B5074B07481968FFF730FF6F -:10A1800030B1064B186980F48070C0F3002008BD20 -:10A19000012008BD3026002000001A0D00002C40D0 -:10A1A0002DE9F047294B8946DFF8C0A0284ECAF8B0 -:10A1B000003002F08FFA274D0446DFF8B480264FB6 -:10A1C00006E002F087FA001BB84229D803F04AFEE5 -:10A1D00031682846FFF704FF0028F2D0D8F8103085 -:10A1E000DB05EED500234FF40072CAF80030D8F832 -:10A1F000283023F48033C8F82830184BC8F80420DE -:10A200001B78CBB149461648FFF7EAFE30B915492D -:10A210000E24154B40F257420C701A60BDE8F087CF -:10A22000104A0A210020104B117040F24B42CAF82C -:10A2300000001A60BDE8F0874FEA492908484946FE -:10A24000FFF7CEFE0028E9D1E1E700BF358100002D -:10A250003026002000001A0D40420F00F62B00208F -:10A2600020003A19F61A0020082600203426002083 -:10A2700000002C402DE9F041254C00212548A36A1F -:10A2800023F48033A362FFF7ABFE054648B92249A9 -:10A290000920224B40F23D2208701A602846BDE892 -:10A2A000F0811F4BDFF88080C8F8003002F012FA0E -:10A2B000636A0646D80118D41A4F04E003F0D2FDB1 -:10A2C000636AD90111D402F005FA831BBB42F5D9A8 -:10A2D000114A0A210025114B11704FF410722846C3 -:10A2E000C8F800501A60BDE8F0810022084BC8F899 -:10A2F00000205A6A9207D1D5586B9A6AD96A22F41B -:10A30000803241F08061D96258639A62C6E700BF2B -:10A3100000002C400000DB0CF61A0020082600206C -:10A32000497B000040420F00342600202DE9F04711 -:10A3300082468946364E02F0CDF9364D0446DFF8A6 -:10A340000081354F04E002F0C5F9031BBB4227D85A -:10A3500031682846FFF744FE0028F4D0D8F81030C2 -:10A36000DA05F0D501232D4D2D4F51462B700023DA -:10A370002C483B602C4BC8F80090C8F804302B4B9D -:10A38000C8F83830FFF72CFE0446A0B9284904204D -:10A39000284B40F29F12087020461A60BDE8F087F3 -:10A3A00023490A20234B4FF4CC72002408701A6012 -:10A3B0002046BDE8F087204BDFF88890C9F80030D0 -:10A3C00002F088F92B780646BBB1DFF84C8003E039 -:10A3D00003F048FD2B7883B102F07CF9831B4345E1 -:10A3E000F6D90023C9F8003011492520114B4FF44C -:10A3F000D172002408701A60DAE73B6800229B07DC -:10A40000C9F80020F0D53A680C4B1A42D0D0EBE7DF -:10A410003026002000001A0D40420F00F82B0020CB -:10A420003826002011003A064000010002007F118A -:10A43000F61A0020082600205D7B000000007F1136 -:10A4400000002C40342600202DE9F041324D144606 -:10A45000AB7A13F0400012D103F03F03EA7A5B00BD -:10A4600043EAD213621C0A43134208D02B49272423 -:10A470002B4B40F202320C701A60BDE8F081294B80 -:10A480001B780BB9490264022748FFF7A9FD40B9C0 -:10A4900022490F24224B40F20A320C701A60BDE8A8 -:10A4A000F08121462148FFF79BFD40B91B4910244C -:10A4B0001B4B40F20D320C701A60BDE8F081002198 -:10A4C0001B48FFF78DFD38B914491124144B4FF484 -:10A4D00044720C701A60E2E702F0FCF8154E164D5B -:10A4E0000446DFF85C80154F31682846FFF778FD99 -:10A4F00018B1D8F81030DB05D1D402F0EBF8001B0E -:10A50000B842F1D905492824054B40F21332002006 -:10A510000C701A60C3E700BF1C260020F61A00204A -:10A5200008260020F62B002000001A2000001A2127 -:10A5300000001B263026002000001A0D40420F00AC -:10A5400000002C402DE9F04F12F0030483B018BF37 -:10A55000012401900093002B08BF44F001045CB17A -:10A5600040492520404B40F2F512002408701A6043 -:10A57000204603B0BDE8F08F3C4B15463C4A0E46E2 -:10A58000DFF80C91136002F0A5F8DFF808810746A8 -:10A59000DFF804B1DFF8F0A006E002F09BF8C01B82 -:10A5A000504544D803F05EFCD9F800104046FFF750 -:10A5B00017FD0028F1D0DBF81030DA05EDD5009A50 -:10A5C0002C4B2B4903EA024300222B4F0A6043F431 -:10A5D00000730121DFF8C4803970C8F80020CBF87F -:10A5E0000050CBF80430254BCBF83830244B1B7887 -:10A5F00043B331460198FFF7F3FC81460028B7D0FA -:10A60000204B1B4A136002F065F83B780546DBB12E -:10A610001D4E03E003F026FC3B78ABB102F05AF884 -:10A62000401BB042F6D90023114A1360A0E70D4B3E -:10A630000A2200210E481A704FF4FC720A4B016086 -:10A640001A6095E77602D4E70023094A1360D8F828 -:10A6500000309B078CD5D8F800200C4B1A4208BF5D -:10A660004C4685E7F61A00200826002035810000B8 -:10A67000342600200000FF1FF82B002002007F116D -:10A68000F62B00205D7B000040420F0000007F1190 -:10A690003026002000001A0D00002C403826002033 -:10A6A000F8B50646007A0C461546C0071F4613D477 -:10A6B00083B10F4401E0BC420CD033682A462146E6 -:10A6C00030461B69013405F5007598470028F2D122 -:10A6D0000020F8BD0120F8BD900712D0002BF9D062 -:10A6E0000F4401E0BC42F5D033682A46214630468B -:10A6F0001B69013405F5007598470028F2D1002048 -:10A70000E7E70648FFF71EFF0028E3D104490C24C1 -:10A71000044B40F2A1320C701A60F8BD37003A12B7 -:10A72000F61A002008260020F8B50646007A0C46E6 -:10A730001546C0071F4613D483B10F4401E0BC4245 -:10A740000CD033682A46214630465B6A013405F551 -:10A75000007598470028F2D10020F8BD0120F8BD0F -:10A76000900712D0002BF9D00F4401E0BC42F5D085 -:10A7700033682A46214630465B6A013405F5007588 -:10A7800098470028F2D10020E7E70648FFF7DAFEF5 -:10A790000028E3D104490E24044B40F23D420C70E2 -:10A7A0001A60F8BD27003A19F61A00200826002082 -:10A7B0002DE9F04F0025DFF8C0929B4C91B0DFF8F7 -:10A7C000BC829A4E0172457289F80050257088F853 -:10A7D00000503570FFF7D2FA29462846FFF700FCF3 -:10A7E00050B90121924B40F28E22054621701A6029 -:10A7F000284611B0BDE8F08F03258E4F4FF4D57178 -:10A800003846FFF7EDFB00284ED1013DF6D13378F5 -:10A81000002B3DD0DFF868B201F05CFF864E0546A4 -:10A82000DFF860A2854F00213046FFF7D9FB50B911 -:10A83000002517217E4B4FF42A72284621701A609A -:10A8400011B0BDE8F08F59465046FFF7C9FB00280C -:10A85000EED001F03FFF401B794BB842E8D81A69AF -:10A86000002AE0DA1969774A11601B695A0002D59B -:10A87000012388F8003000217348FFF7B1FB05463B -:10A8800010BB02216A4B40F2B12221701A60AFE77F -:10A89000FFF774FA29462846FFF7A2FB3378002B0E -:10A8A000B8D14FF4401BB7E7654B1B69B3F5D57FB3 -:10A8B00007D006215E4B4FF42572002521701A60E7 -:10A8C00096E701233370A5E700216048FFF788FB76 -:10A8D000054630B90321564B4FF42D7221701A6092 -:10A8E00086E7574E5A4B32695A4F13405A495B48D4 -:10A8F0003B60FFF7C1FB054630B907214C4B40F2E6 -:10A90000B92221701A6073E755495648FFF7B4FB26 -:10A91000054630B90821464B4FF42F7221701A605A -:10A9200066E739685048FFF75BFB054630B90521FB -:10A930003F4B40F2BF2221701A6059E739683E4808 -:10A94000FFF74EFB38B91421394B40F2C3220025E2 -:10A9500021701A604CE702214448FFF741FB05468D -:10A960000028F0D0B36A69466FF07F4023F00603F9 -:10A97000B362B36A43F00203B3624FF0101373641F -:10A98000FFF7D4FC9DF80D309B0743D5002841D03C -:10A99000274E6946364894F800803768FFF7C6FCB2 -:10A9A0009DF8103003F00F03012B36D1A8B34CF201 -:10A9B0005030304C0523C4F8CC31C4F8D031C4F841 -:10A9C000BC31C4F8C031C4F8C431C4F8C831FFF791 -:10A9D000EBF8002347F2B802C4F8CC31C4F8D03108 -:10A9E000C4F8BC31C4F8C031C4F8C431C4F8C831AB -:10A9F00041F2B803C4F8BC23C4F8C023C4F8AC23A4 -:10AA0000C4F8B0330123C4F8B423C4F8B82389F8D8 -:10AA10000030EDE646F2A810CBE746F2A81084F825 -:10AA200000803760C5E700BFF61A0020F52B002034 -:10AA30000826002000001A0800001A3740420F00C4 -:10AA400000002C402C2600200000090200001A0300 -:10AA50000000FFFF302600201C260020000009090E -:10AA60000C2600200000090A00001B0700001A063F -:10AA7000F1FFFF8000801F40F42B0020F62B002008 -:10AA80000000304000000229374B5A6A92052DE938 -:10AA9000F0410F460DD49A6A22F480329A6272B65F -:10AAA0009A6A42F400329A629A6A42F480329A6256 -:10AAB00062B601F00FFE2C4EDFF8C480054604E0BC -:10AAC00001F008FE431B434537D8746A14F4006450 -:10AAD000F6D007F13C0C244807F50F77436A1B05B5 -:10AAE000FCD5ACF14003026A43F8042F9C45FAD12F -:10AAF0000CF1400C6745F1D101F0ECFD1A4F1B4DF4 -:10AB00000646DFF87C8004E001F0E4FD831B43454A -:10AB10001DD83C6B2C40F7D03B6B154A1360136873 -:10AB20003B63136813F002031BD01268114B1A42E7 -:10AB30000CBF01200020BDE8F0810F491A250F4B02 -:10AB400040F2563220460D701A60BDE8F0810A4985 -:10AB50001D250A4B40F2613220460D701A60BDE897 -:10AB6000F0811846BDE8F08100002C4002007F1102 -:10AB70003826002000007F11F61A00200826002049 -:10AB800040420F002DE9F047294B8946DFF8C0A06D -:10AB9000284ECAF8003001F09DFD274D0446DFF82D -:10ABA000B480264F06E001F095FD001BB84229D87D -:10ABB00003F058F931682846FFF712FA0028F2D05E -:10ABC000D8F81030DB05EED500234FF40072CAF838 -:10ABD0000030D8F8283043F48033C8F82830184BB8 -:10ABE000C8F804201B78CBB149461648FFF7F8F99E -:10ABF00030B915490C24154B40F2BD320C701A6067 -:10AC0000BDE8F087104A0A210020104B117040F275 -:10AC1000B132CAF800001A60BDE8F0874FEA49294E -:10AC200008484946FFF7DCF90028E9D1E1E700BF11 -:10AC3000358100003026002000001A0D40420F0030 -:10AC4000F62B002030003A12F61A002008260020C9 -:10AC50003426002000002C402DE9F04100221D4C3C -:10AC60000D4642721146A36A1B4823F48033A36247 -:10AC7000FFF7B6F940B919490924194B40F2D3320C -:10AC80000C701A60BDE8F081002DFBD0154B164EFC -:10AC9000336001F01FFD636A0746DA0116D4DFF85E -:10ACA0004C8004E003F0DEF8636ADB010ED401F0AF -:10ACB00011FDC01B4045F5D9084A0A210020084B68 -:10ACC000117040F2D73230601A60DBE7002328466B -:10ACD0003360D7E700002C400000DB0CF61A0020A0 -:10ACE00008260020497B00003426002040420F0047 -:10ACF0000A4B1B7810B504461BB9637A43B901208F -:10AD000010BDFFF7CFF80028FAD0637A002BF6D0F9 -:10AD100020460121BDE81040FFF79EBFF72B002021 -:10AD20002DE9F0410446007AADF5007D164610F09D -:10AD3000010513D093073CD0012338486A46FFF73A -:10AD400001FC00283AD04FF400726946304601F009 -:10AD500067FD28460DF5007DBDE8F081DFF8CC8069 -:10AD60000F4698F80030002B35D1637A012B39D08B -:10AD700022682B49126A8A424AD198F80020002A98 -:10AD800034D1002B39D139462046FFF7FBFEE8B11C -:10AD900001236760637231462046FFF775FEA8B154 -:10ADA000636805460133284663600DF5007DBDE804 -:10ADB000F08101231948FFF7C5FB38B919490B2069 -:10ADC000194B4FF45D72002508701A6028460DF586 -:10ADD000007DBDE8F081FFF765F80028F6D0637AC2 -:10ADE000012BC5D16268BA42C2D1D4E7FFF75AF845 -:10ADF0000028EBD0637A002BC5D001212046FFF755 -:10AE00002BFF0028BFD128460DF5007DBDE8F0815D -:10AE1000204690470028F6D0B5E700BF11003A1150 -:10AE2000B18C0000F61A002008260020F72B002025 -:10AE30002DE9F041047AADF5007D0F46904614F0FF -:10AE400001041DD012F0030F06D0684611464FF4DE -:10AE50000072804601F0E4FC0123424639462C484A -:10AE6000FFF770FB044630B92A490D202A4B40F207 -:10AE7000114208701A6020460DF5007DBDE8F08192 -:10AE8000264D06462B782BBB737A022B29D03268CD -:10AE90002349126A8A4236D12A7832BB002B2BD141 -:10AEA0003368394630461B6E98470028E3D00223AA -:10AEB00077607372336841463046DB6D98470028EF -:10AEC000D9D0736804460133204673600DF5007DC8 -:10AED000BDE8F081FEF7E6FF0028CCD0737A022BA4 -:10AEE000D5D17268BA42D2D1E4E7FEF7DBFF002881 -:10AEF000C1D0737A002BD3D001213046FFF7ACFECE -:10AF00000028B8D0CCE7304690470028B3D0C7E738 -:10AF100001003A18F61A002008260020F72B00201E -:10AF2000B18C0000012101F03BBC00BF01F0FCBB73 -:10AF300008B5034653F8040B93E80600F7F7ECFC5A -:10AF400008BD00BF84B00DF1100C0CE90E000246E4 -:10AF500023B11846136004B0F8F78ABD024B1846B7 -:10AF6000136004B0F8F784BDD01000200268D37CD1 -:10AF700013B3D80704D5906A4FF0E021C1F800015F -:10AF8000990704D5D06A4FF0E021C1F804015807B1 -:10AF900004D5106B4FF0E021C1F80801190704D562 -:10AFA000506B4FF0E021C1F80C01DB0604D5926B29 -:10AFB0004FF0E023C3F81021704700BF0068F8F796 -:10AFC00075BE00BF0268FF2312685366D36D13F489 -:10AFD000F81FFBD0506FC0B2704700BF30B50C46B1 -:10AFE00083B00546FF212046019203F0A7FE2868A2 -:10AFF000019B22462146F8F755FE002003B030BDE4 -:10B0000003681A685166D36D13F4F81FFBD0536FB1 -:10B01000704700BF531EB3F5007F30B51446ADF541 -:10B02000017D054611D36AB10368481E196882186C -:10B0300010F8013F4B66CB6D13F4F81FFBD0904224 -:10B040004B6FF5D10DF5017D30BD684601F0E8FB91 -:10B050006A46234628681146F8F724FE0DF5017D5F -:10B0600030BD00BF30B5037883B0DC071DD5044682 -:10B07000406804F110020368E16801925B6A984736 -:10B08000019A0546A8B12378990708D56068D4E9E4 -:10B090000231194403685B6A984750B1237823F062 -:10B0A00001032846237003B030BD0125284603B0B4 -:10B0B00030BD0025284603B030BD00BFF8B5436859 -:10B0C0000BB3C36804460F4615468B4206D110F8F1 -:10B0D000103B05F003052B432370F8BDFFF7C2FFBB -:10B0E00088B16B0705D504F1100630460023E760F0 -:10B0F000EFE7606804F110063946036832461B69C1 -:10B1000098470028F1D10020F8BD00BF10B50446D3 -:10B11000808982B018B10023A38102B010BDD4E9A8 -:10B1200001318B42F9D201AA184600F0B7F880B17C -:10B13000019B6060B3F5803F01D298B2EDE7980AB9 -:10B14000C3F30903A0F52150A3F5105380B2A381E6 -:10B15000E3E74FF6FF70E0E7B1F5807F21D81029D3 -:10B160002ED840234FF0200CB2FBF3F1B1F5806FE5 -:10B1700020D203FB112300B5B2FBFCFEB3FBFCF3B2 -:10B180000CFB1E224FEA910CDBB201322CF03F0C7B -:10B19000C9B2037042EA0C028170D2B242705DF80B -:10B1A00004FB3F239C46802910D9B1F5FC7F0FD8C2 -:10B1B0001B01D9E7FF21FE234170037081707047A6 -:10B1C000202916D880234FF0200CCDE7DB00CBE7F9 -:10B1D000B1F57C7F04D9B1F5FC6F03D89B01C3E7BF -:10B1E0005B01C1E7B1F57C6F94BFDB01C3EB0323C7 -:10B1F000BAE720239C46D6E77F28A2EB010205D8B8 -:10B2000012B10A4602F8010B10467047B0F5006F04 -:10B210000FD2012A40D94FEA901C00F03F030A46A2 -:10B220006CF03F0063F07F0302F8020B10464B7096 -:10B230007047B0F5803F16D2022A2DD9C0F3851C85 -:10B2400000F03F03CA1C63F07F0300B54FEA103ED5 -:10B250006CF07F008B706EF01F0E4870104681F806 -:10B2600000E05DF804FB032A16D94FEA904CC0F3C6 -:10B270000532C0F3851300F03F0062F07F026CF0EE -:10B280000F0C63F07F0360F07F004A700A1DC870E6 -:10B2900081F800C08B70B7E70022B5E788423DD245 -:10B2A000034610B490F900001C7800282DDA04F051 -:10B2B000E000C02834D004F0F000E02834D004F0DE -:10B2C000F800F02826D104F007040420184488422E -:10B2D00020D8013313F8011B01F0C00C01F03F012D -:10B2E000BCF1800F41EA841414D18342F2D1A4F15D -:10B2F00080010F4B99420DD8A4F55843B3F5006F68 -:10B3000008D314605DF8044B7047581C14605DF856 -:10B31000044B704700205DF8044B704700207047D5 -:10B3200004F01F040220D1E704F00F040320CDE74E -:10B330007FFF10007E283ED94FF0350C002330B43B -:10B34000284C04E034F82120824220D80B46ACEB94 -:10B350000302012A03EB5201F4D89BB234F82320F4 -:10B36000904216D24B2400231F4D04E035F82120D3 -:10B3700082421ED80B46E21A012A03EB5201F5D88D -:10B380009BB235F8232082421FD030BC70478C46D8 -:10B39000DDE704EB8304821AE3789A42E2DA94F957 -:10B3A0000230012B16D0D3B19BB2034430BC98B20B -:10B3B00070470C46DFE7A0F16103192B8CBF002317 -:10B3C0000123A0EB431398B2704705EB830568880F -:10B3D00030BC704702F00102831A98B2D5E74EF2F2 -:10B3E000A033E2E7B40400207C0300202DE9F04FF5 -:10B3F00083B00021824600F067FC019000284AD00B -:10B4000000F58273041DDFF8C0B147F6FF77684E80 -:10B41000684DDFF8B881DFF8B891009326E09B45CE -:10B42000B8BF9B46DAF8201032788B42D4BF002395 -:10B4300001239A4233702B681ED0D8F80020934223 -:10B440002CDA13EB4303D9F8002048BF0133012A5B -:10B450004FEA6303C8F8003002F1010362D0C9F873 -:10B46000003000232B60009B9C420AD034F9023B41 -:10B47000BB42D4DA1F46D5E701332B60009B9C42C8 -:10B48000F4D1019800F0D4FB17EB0B0748BF01374C -:10B490007F10CAF8207003B0BDE8F08F002B1A4669 -:10B4A000B8BF5A1C13EB62034FF0000248BF0133D0 -:10B4B000C9F800205B10C8F800303F4B19683F29DD -:10B4C00010DC3E4B3E4A1B78002B40D0136850687E -:10B4D0005B0843EAC07340080131C2E90030364BD3 -:10B4E0001960BEE736494BF6FC700B895B009BB2D6 -:10B4F00083420B81B5D1334B1868C86001F0EAF87C -:10B50000304B00222E490AF1280C18604FF0010E32 -:10B51000294B1A60294B1A700FC98CE80F008AF862 -:10B520001CE09EE7244B00221968C9F800203F293F -:10B5300012DC224B224A1B78002B31D0D2E900309A -:10B540005B0843EAC073400840F00040C4E713685A -:10B550005068DB184041BFE7194943F6FD700B897D -:10B560005B0043F001039BB283420B817FF479AF10 -:10B57000144B1868C86001F0ADF8124B00224FF070 -:10B58000010E0F4918600AF1280C0B4B1A600B4B87 -:10B5900083F800E00FC98CE80F008AF81CE060E730 -:10B5A00013685068DB1843F00103404194E700BF83 -:10B5B000FE2B0020E0270020D4270020F71A0020CF -:10B5C000E0200020D82700200080FFFFDC2700209B -:10B5D000E427002090F8A32090F8A200101A7047EA -:10B5E00090F8A23090F8A3209A4205D95A1C03443F -:10B5F00080F8A220987E70474FF0FF30704700BF60 -:10B6000090F8A23090F8A3209A4202D91844807E84 -:10B6100070474FF0FF307047704700BF0346B0F8E7 -:10B62000300178B193F82F21882A03D90122002014 -:10B630005A60704702F1010C01201A4483F82FC1AF -:10B6400082F8A510704700BF38B5B0F830410CB98A -:10B65000204638BD90F82F310546C3F18904A24237 -:10B660000DD8144605F1A5002246184401F0D8F87B -:10B6700095F82F312046234485F82F3138BD01221B -:10B680004260EFE72DE9F04FD0F814A01524017EB9 -:10B690008146437E83B00AEB0111384A0AEB03135B -:10B6A000374F097A93F8283002EB01150901E86851 -:10B6B00052F8018002EB0311D5F804B01B01CE68EB -:10B6C000D558CBF80040C8F88400D8F804304A6850 -:10B6D00003432C490192C8F804301460C5F8846013 -:10B6E0006B6833436B60284B4C683A68A3FB0232AB -:10B6F000920C02EB820252004B681B1B9A42FBD851 -:10B700004FF0090C1F4ADFF880E0D8F808300342F8 -:10B7100002D0AB6833422FD1C5F8886054683968CD -:10B72000AEFB0131890C01EB810153681B1B99426F -:10B73000FBD8C5F8846054683968AEFB0131890CC8 -:10B7400001EB810153681B1B9942FBD8BCF1010C32 -:10B75000DBD1604699F81830019A0AEB0313DB68D5 -:10B76000CBF8003099F819300AEB031ADAF82C30CC -:10B77000136003B0BDE8F08F0120EBE7E40B00207D -:10B78000CC100020001000E083DE1B430E4A10B5F1 -:10B790001168046905E0DB0107D413685B1A102BFC -:10B7A00008D8636913F0007FF5D14FF4FE43012000 -:10B7B000636110BDFFF766FF0028FAD04FF4FE4327 -:10B7C00001206361F5E700BFC42B00202DE9F0479D -:10B7D00090F82FA10569BAF1000F4FD08146884635 -:10B7E000FFF7D4FF002849D0374E0024376818E00F -:10B7F0006B69190551D4DA0455D4580559D4990404 -:10B8000041D43268D21B322A3DD8544507D9EA6D5B -:10B81000520704D19B0555D4B8F1000F52D002F065 -:10B8200021FB5445E4D8EA6D500702F00703DFD44A -:10B8300013E099F8A5200133022442F48062042B1E -:10B840002A661ED08A4503F1010309EB01020ED9D5 -:10B8500092F8A520042B2A66CAD00121002CE8D03A -:10B860002146013301348A4509EB0102F0D8B8F1D1 -:10B87000000FBDD04FF400732B66B9E70420BDE87C -:10B88000F0870124B4E72B694FF40072042043F4DD -:10B8900040732B612A66BDE8F0872B69042043F4CE -:10B8A00040732B61EBE72B69052043F440732B6158 -:10B8B000E5E72B694FF40072022043F440732B61DB -:10B8C0002A66DCE70020DAE7C42B00202DE9F84FD8 -:10B8D00083460C4615461F46D0F810A0FFF756FFCA -:10B8E000002800F09E806100012DDFF83C8140F2CD -:10B8F0000146CBB24FF0000138BF0125D8F80090C7 -:10B900000C461E43ABF8A21020E09BF8A330872B17 -:10B910003FD9DAF8142010055AD412F4105F70D110 -:10B92000D8F80030A3EB0903322B6AD89BF8A33078 -:10B93000AB4209D3022C07D9DAF85C30590703D19E -:10B9400093054BD4002F49D002F08CFA022CDCD89E -:10B95000DAF85C3003F007025B07D6D4681E224495 -:10B9600040F480704CB9CAF860600134131B032B9B -:10B97000CBD8022CC9D8002CF5D0012C37D01FB160 -:10B980004FF40073CAF860309BF8A3300324872B70 -:10B99000BFD8DAF85C2012F4E02FC2F3024CB8D022 -:10B9A000591C9C441933C9B25FFA8CFC5BFA83F3CF -:10B9B000DAF870004A1C61458BF8A310D1B203F885 -:10B9C000010FA6D08929F3D1DAF814201005A4D5E7 -:10B9D000DAF8103043F44073CAF81030DAF85C300B -:10B9E00013F4E02F06D19BF8A300BDE8F88FCAF846 -:10B9F0006000BAE7DAF8103043F40073CAF8103088 -:10BA0000F1E7DAF810304FF4007243F44073CAF8EB -:10BA10001030CAF86020DAF85C3013F4E02FE2D07E -:10BA2000E8E70420BDE8F88FC42B0020F8B50669CC -:10BA30000446D6F8145115F4706301D0C6F81431D9 -:10BA4000A8070BD5D6F8702111043DD5002301219C -:10BA500084F8A230234484F8A3109A76EA0710D51C -:10BA600094F83071F7B194F82E7194F82F31BB42ED -:10BA700026D97B1C274484F82E3197F8A530C6F8C8 -:10BA80006031AB050DD594F8A30018B1D4F83C3162 -:10BA900003B198470023A4F8A230A4F82E3184F80B -:10BAA0003031F8BDD4F8383103B19847002384F819 -:10BAB0002E31012384F8303194F82F31BB42D8D88D -:10BAC0000023C6F86031DCE794F8A330872BC5D893 -:10BAD000591CC9B2BEE700BF0148FFF7A7BF00BFAE -:10BAE000301100200148FFF7A1BF00BF70120020F5 -:10BAF0000148FFF79BBF00BFB01300204FF0E023C9 -:10BB00004022C3F808227047F8B5144B144D1C6846 -:10BB10006E689CB1237A20466BB123686F681B68FE -:10BB200098476B68E188DB1BC3F38F12B1EB931F5F -:10BB3000A28038BFE2806469002CEBD1084B094A2F -:10BB40005B6810889B1B084CC3F38F11B0EB931FED -:10BB5000218038BF1180BFF34F8FF8BD44260020ED -:10BB6000001000E0E62B0020E42B002003681847BB -:10BB70000B680360704700BF0B680360704700BF2D -:10BB8000704700BF30B472B6244D254C2A8804F1AA -:10BB9000700104EB82038B423CD204F16F01501C14 -:10BBA000C91A00EB910002E00132824232D09C4679 -:10BBB00053F8041B0029F7D0B1FA81F04FF000438D -:10BBC000C34021EA0301CCF8001001B90132154B42 -:10BBD0002A801A88013291B2198062B6ACEB040C4B -:10BBE00041F67C73C0EB00644FEAAC0CC0EB8410F0 -:10BBF00001240CEB8C1C03EBCC1303EB80030A48F1 -:10BC00000068C4541844094B1C88944230BC38BFA7 -:10BC10001980704762B6002030BC7047E82B0020C6 -:10BC200048260020E02B002040260020E22B0020A8 -:10BC3000428872B60378012B03D9013B037062B6C8 -:10BC40007047D14353090B484FF0004201F01F01E8 -:10BC5000CA4050F823100A430749B1F800C040F821 -:10BC600023209C45054A88BF0B801388013B138025 -:10BC700062B6704748260020E82B0020E02B002009 -:10BC8000C36813B91DE0DB68E3B1187A9042FAD1BA -:10BC900010B4586893F809C0006950F82C4054B1AA -:10BCA000DB682BB1187A9042F3D0DB68002BF9D116 -:10BCB0005DF8044B704740F82C100878013008708C -:10BCC000EEE77047704700BF437A8B4206D903699D -:10BCD000002253F8210043F82120704700207047CC -:10BCE00000220449C0E90022028102740A68086047 -:10BCF000C2607047B8260020037CFBB90368014688 -:10BD0000FBB14368EBB1427A5B7A9A421CD230B401 -:10BD100072B62B4B1C68ECB1E368C3B1486801E014 -:10BD2000DB68A3B15A688242FAD193F809C04A7A13 -:10BD30009445F5D162B6042030BC7047012062B64C -:10BD40007047032062B67047022062B6704764698C -:10BD5000002CE1D11B4C236843B1994202D10BE086 -:10BD6000994207D01A46DB68002BF9D1052062B64C -:10BD700030BC704702F10C040D68E868E8B1C36894 -:10BD80001BB908E0DA683AB1134681421846F9D186 -:10BD900062B60620D0E70346D960CB680020236056 -:10BDA0000123C860AA7A2B721A44AA724A68947A4C -:10BDB00013721C4494720B74D9E7E960EDE700BF7D -:10BDC00044260020B826002010B5047C9DF808E029 -:10BDD0000CB1012010BD027280F809E0C0E9001327 -:10BDE000BDE81040FFF788BF38B5037C002B36D084 -:10BDF00043680446427A5B7A9A4238D272B6016846 -:10BE0000CB68002B2DD0984233D01A46DB689C4279 -:10BE10002AD0002BF9D16268607A136953F82000A8 -:10BE200048B1FFF705FF72B662680025607A1369B2 -:10BE3000216843F820508B7A013BDBB28B7203B947 -:10BE40000B72937A013BDBB2937203B913720A4B04 -:10BE500000201A6820741C60E26062B638BD0120C0 -:10BE600038BD62B6032038BDE368D360D3E7022053 -:10BE700038BDC368CB60CEE7B826002010B50446B5 -:10BE8000FFF7B2FF094A136843B19C4202D108E0B0 -:10BE90009C4205D01A46DB68002BF9D1204610BD24 -:10BEA0000C32E3682046136010BD00BFB8260020A6 -:10BEB0000C4B1A789AB90C4A0C4910B4C2F85811B4 -:10BEC0000B48D02401224FF0E02180F84640402466 -:10BED0001046C1F808415DF8044B1A707047002005 -:10BEE000704700BFF92B0020001C0020C99A0000F9 -:10BEF00000E400E030B472B621B9036813B10279EE -:10BF00000F2A3BD9244C2188002341FA03F212F076 -:10BF1000010208D00133102BF7D162B60022037161 -:10BF2000026030BC70474FF0010C0CFA03FC41EA90 -:10BF30000C01218062B619495FFA83FC184C194440 -:10BF400080F804C04B01E16F41F0C001E16740F2AD -:10BF5000824414490C6081F81AC081F81EC081F82F -:10BF600018C081F81FC0036030BCC3E90022C3E9D8 -:10BF70000222C3E90422C3E906227047064C218845 -:10BF800041FA02F5ED07BFD5044D1544B3EB451F4B -:10BF9000BAD162B6C5E700BFEC2B00208074000266 -:10BFA00000C00F4000800E4003790F2B11D8094AC2 -:10BFB000937672B60849012290F804C00B8802FA01 -:10BFC0000CF223EA02030B8062B6102200230271F6 -:10BFD0000360704700800E40EC2B0020EFF31082CE -:10BFE00072B6437F5BB9017F012930B40BD00329BE -:10BFF00013D00123437702B962B630BC70470AB947 -:10C0000062B670477047124C2168B1B11149436163 -:10C010000B68086083615861EBE70F4D0F492C688E -:10C020008CB143610B68836158614FF0E0234FF09E -:10C0300080540860C3F8044DDBE7064B20601860AD -:10C04000C0E90511D5E7C0E905442860EDE700BF68 -:10C05000202700202C27002028270020242700202C -:10C0600070B5EFF3108272B60C4C206880B10C4EA4 -:10C0700000254369236073B19D6102B962B683688C -:10C0800045779847EFF3108272B620680028F0D108 -:10C0900002B962B670BD3360EFE700BF2827002009 -:10C0A00024270020FFF7DCBF0449054A4968054BF7 -:10C0B0001960136801331360704700BF001000E07F -:10C0C000C42B0020C02B0020704700BF704700BF6A -:10C0D000704700BF704700BF70B51A4C1A4D2368F7 -:10C0E000AB4202D0194AD16829BBA369AB4202D046 -:10C0F000164AD169C9B9236BAB4202D0134AD16A3F -:10C1000069B9A36CAB4209D0104AD16B31B101219E -:10C110001B680F48D163BDE87040184770BD01210E -:10C120001B680C48D1629847EBE701211B680A485D -:10C13000D1619847DFE701211B6804F10800D16055 -:10C140009847D2E7C01E002050060020004108405A -:10C15000101F0020F81E0020E01E002038B5064CFD -:10C16000A4F1600554F8083C2046183CDB68984769 -:10C17000AC42F7D138BD00BF101F002003682DE985 -:10C18000F041044688B01746002B4BD000229A603D -:10C190000122DA60304D04A8DFF8E0801D4451F838 -:10C1A000083B2D1102935B6805EB45069847F600A6 -:10C1B00006F1080058F806304044DB6801909847C3 -:10C1C000264A04A9DDE90103029248F806309B687B -:10C1D0009847029B04A8DB689847236803222048FD -:10C1E0001F609A601F4A23791F4C5355137851786A -:10C1F000C0F828428B4228BF0B469178D2788B42F8 -:10C2000028BF0B46934228BF1346184C4FF0E0223C -:10C210004FF08061012084F87A30C2F80C1108B028 -:10C22000BDE8F081124AD36E43F44053D366012235 -:10C23000104B1A60104A134602604032986800287A -:10C24000A8D0103393422360F8D10023184623600E -:10C2500008B0BDE8F08100BF00BFF7BF5006002066 -:10C26000001C0020F014002099A0000000E400E071 -:10C2700000C00F400040084000410840C01E0020A0 -:10C2800010B4064B0020064C064A1C609C611C63DF -:10C290009C6405495DF8044B01F050BEC01E0020AF -:10C2A00050060020FC1400201DA10000084601F0EB -:10C2B00045BD00BF2DE9F0410C46D1B1EAB1804641 -:10C2C0008E1800250E4F04E001F038FDB4420544FD -:10C2D0000CD0D8F8003014F8010B1B68BB42F3D027 -:10C2E000014640469847B4420544F2D12846BDE88D -:10C2F000F0810D462846BDE8F0811546F6E700BFFF -:10C300006DA20000054B022888BF034610B41C68CC -:10C31000184663685DF8044B184700BF20110020E1 -:10C320000EB400B582B003AA52F8041B019202F0C9 -:10C3300019FC02B05DF804EB03B07047A249A34BAF -:10C3400088422DE9F047A24C5E699A69D4F80C80C6 -:10C350001BD9A04B984240F20281C31A9E491B0A86 -:10C36000A1FB031340F22761DB0903EB830303EB1B -:10C37000830303F2E2438B4228BF0B46A3F54877C1 -:10C38000964BA3FB0737FF0804E0954FB8428CBFDC -:10C390000E2706278D4908F01F09D1F88030B945CE -:10C3A00043F0C003C1F880300CD228F01F08A1F57B -:10C3B000F82148EA0708C1F80C800B68002BFCDA6A -:10C3C00008F01F0916F0007324D186490C698649CC -:10C3D000A14300F0EA8082F4805134464FF4805546 -:10C3E00014F0605F04D026F060561E43774B5E6108 -:10C3F00011F4405F07D022F4405274492A438A6105 -:10C400008B6C1A07FCD446F00076704A5661936C28 -:10C410009B06FCD4754CA04200F2CE804FF0010C7C -:10C420000146634603FB011203F1010E0CF1010505 -:10C43000A24218D8BEF1080F4FF0010340F08D80E2 -:10C44000BCF1040F00F291800A18A24200F2A4800D -:10C4500005FB00F1AC4603F1010E03FB01120CF1E8 -:10C460000105A242E6D90CF1FF318C0286EA812156 -:10C470005F4810445F4A90427FD9DFF8A4A16C2244 -:10C480005D48584DB0FBFEF0D5F800E0B0FBFCF085 -:10C49000DFF890C10EEA0C0CD44509D042F40052EA -:10C4A0004FF4805CC5F800C02A602A68002AFCDAD4 -:10C4B000464A156905F007059D4203D01361936C48 -:10C4C000DD03FCD411F4E05F09D026F4E05604F457 -:10C4D000E0543E4A26435661936C9907FCD4474981 -:10C4E000474A014491423CD8464BC909A3FB01315C -:10C4F000090B4B1E1B0286EA030212F4407F06D092 -:10C5000026F4407603F44073304A334353612F4A94 -:10C51000536923F000735361936C9B06FCD43A4B30 -:10C520004F45A3FB00234FF0FF324FEA9343B0FB8C -:10C53000F1F1B2FBF3F3354A1060354A1160354A28 -:10C54000136008D228F01F08214A48EA0707D7607D -:10C550001368002BFCDABDE8F087734662E7122708 -:10C5600018E74FF440730421C5E70CF1FF31204870 -:10C5700007238C02104486EA8121274ADFF8A8A00D -:10C58000A2FB0020020D2548362A38BF362202FBC6 -:10C5900000F042EA0A0A74E74FEA8C24002386EA94 -:10C5A0008C214FF0010EAC4662E71D4686F0C05468 -:10C5B00011464FF0C05313E700244FF0010C024620 -:10C5C00031462346E64653E700A4781F00C00F40DB -:10C5D000000008400046C32323B24C001F85EB51E6 -:10C5E00000366E0100800D4040300080FFB19F2674 -:10C5F000808D5B00FF7EF64D00643F4D7FD1F008DB -:10C600007F17B42C9F10E50083DE1B43CC10002065 -:10C61000C8100020B02B0020819F5E16001BB700C1 -:10C620006C2000807F3001800020008000B97047BE -:10C630002DE9F84F01218146214C224D224E54E82C -:10C64000003F2A68306844E80013002BF7D11F49E7 -:10C650004B684FF47A7BDFF878A01B1A01270BFB9D -:10C6600002F8DAF80020A3FB02325A4594BF904446 -:10C67000D84454E8003F2A68306844E80073002B2F -:10C68000F7D14B68DAF800C01B1A0BFB02F2A3FBD0 -:10C690000C3CBCF57A7F94BF624402F57A72A2EB3F -:10C6A0000802B2F57A7F06D3B9F1010908F57A7864 -:10C6B000DFD1BDE8F88F01F0D5FB0449D9E700BF11 -:10C6C000C82B0020C42B0020C02B0020001000E04D -:10C6D000B02B002030B40F4B4FF0010C0E4D0F4C1F -:10C6E00053E8002F2868216843E800C2002AF7D1E8 -:10C6F0000B4B5B680B4A5B1A4FF47A71126801FBB3 -:10C7000000F0A3FB023230BC8A4294BF801840186C -:10C71000704700BFC82B0020C42B0020C02B002076 -:10C72000001000E0B02B0020272816D80201104B83 -:10C7300003EB00109B5810B4C2685C68144205D02B -:10C7400061B95DF8044BC3F888207047836851B124 -:10C75000084A5DF8044B1A60704770475DF8044B57 -:10C76000C3F884207047044A5DF8044B1A60704790 -:10C77000E40B002038F001003830010027280BD8E6 -:10C78000064B020103EB00109A58C36892681A42E4 -:10C7900014BF01200020704700207047E40B0020E8 -:10C7A000272829D8164B0201012903EB00109A58BB -:10C7B00010B45368C4680ED004290CD023EA0403D3 -:10C7C00053608368A9B1022917D003290CBF0D4A11 -:10C7D0000D4A1A6007E0234301295360836808D09B -:10C7E00040F638021A60436815225DF8044B1A605F -:10C7F000704738221A60F6E77047044A1A60F2E779 -:10C80000E40B0020383001003800010038F001004E -:10C8100008B5F5F749FCF5F799FC01F023FBFAE7B9 -:10C82000844641EA000313F003036DD1403A41D33B -:10C8300051F8043B40F8043B51F8043B40F8043BFA -:10C8400051F8043B40F8043B51F8043B40F8043BEA -:10C8500051F8043B40F8043B51F8043B40F8043BDA -:10C8600051F8043B40F8043B51F8043B40F8043BCA -:10C8700051F8043B40F8043B51F8043B40F8043BBA -:10C8800051F8043B40F8043B51F8043B40F8043BAA -:10C8900051F8043B40F8043B51F8043B40F8043B9A -:10C8A00051F8043B40F8043B51F8043B40F8043B8A -:10C8B000403ABDD2303211D351F8043B40F8043B2A -:10C8C00051F8043B40F8043B51F8043B40F8043B6A -:10C8D00051F8043B40F8043B103AEDD20C3205D33A -:10C8E00051F8043B40F8043B043AF9D2043208D032 -:10C8F000D2071CBF11F8013B00F8013B01D30B88A4 -:10C9000003806046704700BF082A13D38B078DD081 -:10C9100010F003038AD0C3F10403D21ADB071CBF53 -:10C9200011F8013B00F8013B80D331F8023B20F8BD -:10C93000023B7BE7043AD9D3013A11F8013B00F8F6 -:10C94000013BF9D20B7803704B7843708B7883707E -:10C950006046704701F0F8BA01F0FEBA01F1FF3C01 -:10C9600070B56646002400E00134B0FBF2F502FB2E -:10C970001503092B03F1370E03F130035FFA8EFE26 -:10C9800098BF5FFA83FE9042284606F801EFEBD28B -:10C99000631C0022C818CA547CB162461CF8015FAF -:10C9A00010F8016DA1EB0C0302328CF80060013B22 -:10C9B000521A057023449A42EFDB084670BD00BF4F -:10C9C00000230F2248F2B82C194610B54FF47044DA -:10C9D0004FF4806EA0F88C414FF46044A0F88E2193 -:10C9E0000A46A0F89031B0F888319BB243F0F003CA -:10C9F000A0F8883101EB4103013100EB4313042916 -:10CA00009C80A3F806E05A841A865A805A81A3F8BB -:10CA10000EC05A82DA825A83DA83EBD1B0F88831B9 -:10CA20009BB243F00F03A0F88831B0F888319BB275 -:10CA300043F47063A0F8883110BD00BF374B384A0B -:10CA4000996F384841F47F0170B5996741F201064A -:10CA5000D3F8801045F6C05543F226040A43C3F8C4 -:10CA60008020FFF7ADFF00F58040FFF7A9FF00F53C -:10CA70008040FFF7A5FF00F58040FFF7A1FF0022EF -:10CA8000A0F503104FF00F0E114600EB42134FEAD2 -:10CA9000421C01329981042A5981A3F80EE09E823A -:10CAA000DD8020F80C1019829C81EED100221E48F6 -:10CAB0004FF00F0E41F20106114645F6C05543F204 -:10CAC000260400EB42134FEA421C01329981042AEA -:10CAD0005981A3F80EE09E82DD8020F80C101982A7 -:10CAE0009C81EED1002211480F2641F2010511462A -:10CAF00045F6C05443F2260E00EB42134FEA421CA7 -:10CB000001329981042A5981DE819D82DC8020F8DE -:10CB10000C101982A3F80CE0EED170BD00C00F40DC -:10CB2000000003FC00C03D4000001E4000401E40CD -:10CB3000074A506A936A19468446506A936A994232 -:10CB4000F9D18445F7D1DB0B43EA4040704700BF81 -:10CB500000400D4072B6EFF30583524CC4F88430A8 -:10CB60001EF0040F0CBFEFF30882EFF309824FF0C1 -:10CB7000E0234D4E4D4DD3F8280DD3F82C1DC4E9BC -:10CB80002201D3F8341DD3F8383DC4E92413936946 -:10CB9000C4F89830D369C4F89C3000F0D3F884ED21 -:10CBA000280AFFF7C5FF0B214FF0FF32C4F8A4009D -:10CBB0000B46C4F880103E49301D5A40202402F034 -:10CBC0000103013C01FB03F383EA5202F7D1A842BF -:10CBD00002D073680646EFE7324BC3F8A820BFF3D4 -:10CBE0004F8F4FF0E0233049324AC3F8701FC3F82B -:10CBF000702FBFF34F8FBFF36F8F2F4A02252F483F -:10CC0000D36E2F4943F44053D3660560D3692D4852 -:10CC100023F07F0343F04003D3610B6883423DD888 -:10CC2000264D00214FF0E0234FF0FF32296001260E -:10CC3000C5F808112449C5F80011C5F80861C3F802 -:10CC40008021C3F88421C3F88821C3F88C21C3F85C -:10CC5000902101E000F068F9D5F80C31002BF9D0F3 -:10CC60000134C5F80C614F2CF4D9184B0220184937 -:10CC70004FF00042C1F840015A63D5F80C313BB97E -:10CC8000144815490D4A0163D2F80C31002BFAD033 -:10CC90004FF0E023114AC3F80C2DFEE7FFF74EFBDF -:10CCA000BEE700BF00FF272080FF2720A8FF272026 -:10CCB0002083B8EDA0FF272000C00F4000400840AF -:10CCC000CC100020803DCD0B009F240000900D4033 -:10CCD00000002E4000800F40F100AD0B0400FA056B -:10CCE0000A490A6838B108B513180948834204D8BC -:10CCF00010460B6008BD1046704702F055F90C2332 -:10CD00004FF0FF320360104608BD00BFF81400204A -:10CD100000002820002070474FF0FF30704700BF10 -:10CD20004FF4005300204B60704700BF0120704754 -:10CD30004FF0FF30704700BF30BFFDE730BFFDE769 -:10CD4000FFF708BF124AD2F880305B07FBD5D2F854 -:10CD500080301048C3F30B230F4990ED007A07EEA3 -:10CD6000903A91ED006AB8EE477A0C4AF8EEE77A0D -:10CD70000B4BD2ED006A77EEC77A93ED007AB8EEEE -:10CD8000477A67EE867A87EEA60A37EE400A704742 -:10CD900000810D40A02B0020A82B0020AC2B0020F0 -:10CDA000A42B0020836BF0B41BB1536843F4004301 -:10CDB000536072B6446B3CB31A4B2260D3F8B04157 -:10CDC0000C421DD1184E776804E07468E41BB4F57A -:10CDD000166F0BD2D3F8404144F48044C3F840416D -:10CDE000D3F8B851D3F840416404EED50D4007D1D3 -:10CDF0000C4CC0E90225D4F8B0310B43C4F8B03173 -:10CE0000426362B6F0BC7047064DC0E90224D5F813 -:10CE1000B0310B43C5F8B0310263426362B6F0BC77 -:10CE2000704700BF00002E40001000E070B5056B99 -:10CE30009DB106462A46002403E012680134012A07 -:10CE40000CD0536813F08003F7D032632CB128461E -:10CE5000B36B2D689847013CF9D170BDC6E90C331E -:10CE6000F4E700BF30B4D9B91F4C204B0021204A51 -:10CE700001254FF0011099601D60C4E90231802442 -:10CE80005C60C2F8BC01D2F8B0311A482B43C2F83A -:10CE9000B0310160D2F8B031002BFBD130BC70470B -:10CEA0000904154B104C012541F080019860104A8F -:10CEB000596000F580511D60D96000F50051A364F0 -:10CEC000196100F5405100F58040596100219861D9 -:10CED000E164D2F8B03143F48033C2F8B031D2F813 -:10CEE000B031002BFBD1C0E700000020201F002044 -:10CEF00000002E40002B0020401F00200849012286 -:10CF00000B7802FA00F023EA0000087030B9054AF5 -:10CF1000D2F8483123F08003C2F84831704700BF8F -:10CF2000052C002000002E402DE9F04F974C83B0D7 -:10CF3000D4F84471FB07C4F8447153D5D4F8AC213C -:10CF4000002A4AD0924EDFF860A2DFF87492DFF830 -:10CF500074B2DFF87482C4F8AC21D6E90A20D4F8A0 -:10CF6000403143F40053C4F84031D4F840319D04BB -:10CF7000F5D5D4F8403123F40053C4F840314FF0D4 -:10CF80000113C4F8B431D4F8B45115F00115FAD135 -:10CF900093B28446CAF80050B3F5086F00F0CF8111 -:10CFA00000F2DB8040F202318B4200F0E78100F2B8 -:10CFB0009A80822B00F0CB81B3F5817F40F08A808C -:10CFC00010F0780F83B200F003824FF00113C4F821 -:10CFD000C031D4F8AC21002ABDD16C4AD2F8BC31A2 -:10CFE000002B42D17E0616D5684BD3F8AC21C3F88E -:10CFF000AC21D3F8BC21C3F8BC21D3F8B041002C3C -:10D00000FBD14FF0FF32C3F8B421D3F8843100F0E4 -:10D010002DFD604B1C60FC0103D55F4B1B6803B109 -:10D020009847B80103D55D4B1B6803B19847790752 -:10D0300008D5564BD3F8843113F4007347D0584BBE -:10D0400001221A70514BD3F848311A060AD53B0613 -:10D0500008D5544A13782BB1013BDBB21370002B77 -:10D0600000F0728203B0BDE8F08F4F49C2F8BC31C6 -:10D070000868034240F0D181464A14681C40B1D090 -:10D080005FEA144810D0424E4FF0010998FAA8F513 -:10D09000B5FA85F506EBC51009FA05F54030FFF73E -:10D0A000C5FE38EA0508F1D1A4B2002C9AD0384E5A -:10D0B0004FF0010894FAA4F5B5FA85F506EBC51012 -:10D0C00008FA05F5FFF7B2FEAC43F3D18AE7344A1C -:10D0D0001370B7E7802B7FF478AF344802210580C6 -:10D0E000FFF7C0FE75E7B3F5A06F00F00B81A3F565 -:10D0F000D063012B3FF669AF2D4B5D68002D3FF4E7 -:10D1000064AF1FFA8CFC4FEA124E04E01D690C3329 -:10D11000002D3FF45AAF1A887245F7D15A886245FC -:10D12000F4D14FEA1E22032A00F0A5811A89000CCF -:10D13000824228BF0246BEF5007F40F0A181184B15 -:10D140001C4918781C4B0192002818BF19461B482F -:10D15000FFF766FB194D019AE1E142F221218B4272 -:10D160007CD033D942F221318B4200F081804FF6DE -:10D17000C0018B427FF429AF10F47F4F83B27FF45C -:10D1800024AF43F46E4363F30F0CB5E700002E4069 -:10D1900000000020042B0020D82B0020DC2B0020D6 -:10D1A0000B2C00200C2C0020002B0020682B0020D2 -:10D1B000040F00206C1F0060D01F0060400E202074 -:10D1C000F82A00205DCFC6B8C0012E40B3F5106F1D -:10D1D00066D042F221018B427FF4F7AE030C072B9D -:10D1E0007FF4F3AEB24BB349F560D960B249B36096 -:10D1F000C3F80890C1E9002001221A60AF4A5A60C2 -:10D20000AF4A1A61D4F8B01141F00101C4F8B0116D -:10D2100002F5805102F5005259619A61D4F8B0319B -:10D22000002BFBD1A74AF36493600123B26413601F -:10D2300048F2800353604FF00113C4F8BC31D4F8B6 -:10D24000B03143F48033C4F8B0314FF48033CAF8BE -:10D250000030D4F8B031002BFBD1BAE680B238B937 -:10D26000994BC2F307421968984B1960984B1A7092 -:10D27000944B00229A60F2640122B3641A60802207 -:10D280005A604FF00113C4F8BC31D4F8B03143F404 -:10D290008033C4F8B031D4F8B031002BFBD198E61C -:10D2A000C2F307428B4B1A708B4BC4F8C8318B4BBF -:10D2B000C4F8CC318A4BC4F8D03100F0D9FB8022BD -:10D2C0002946884801F03AFD874B8022C6F8A0B075 -:10D2D000C6F8E0307B4BF5645A600122B3649D6070 -:10D2E0001A604FF00113C4F8BC31D4F8B03143F4E4 -:10D2F0008033C4F8B031CAF80050D4F8B031002BF4 -:10D30000FBD166E66F4B0121F564196080219D60B9 -:10D31000B36459604FF00113C4F8BC31D4F8B03194 -:10D3200043F48033C4F8B031D4F8B031002BFBD1D2 -:10D33000130C5B0643F08073C4F8543149E6654B27 -:10D3400001216A481B780370FFF78CFD41E683B228 -:10D3500010F078007FF439AE03F07F0258F8221005 -:10D36000624A1080180600F19E80CB0701D5012388 -:10D37000137002215D48FFF775FD2AE610F0780F63 -:10D3800083B27FF422AE03F07F0213F0800F58F8CF -:10D39000223014BF43F4803343F0010348F82230B5 -:10D3A0000022484BF2649A600122B3641A60802222 -:10D3B0005A604FF00113C4F8BC31D4F8B03143F4D3 -:10D3C0008033C4F8B031D4F8B031002BFBD100E683 -:10D3D00003F07F0213F0800F58F8223014BF23F4BB -:10D3E000803323F0010348F822300022354BF264E9 -:10D3F0009A600122B3641A6080225A604FF00113D0 -:10D40000C4F8BC31D4F8B03143F48033C4F8B0313F -:10D41000D4F8B031002BFBD1DBE5002008602649B1 -:10D420000C88486842F221018C427FF425AE80B21C -:10D4300000287FF421AE2E492E4C03C9A1808628F6 -:10D440004FEA11412060A1717FF416AE72B62A48EE -:10D45000017841F008010170D2F848110D0605D499 -:10D4600080200143C2F84401C2F8481162B6234A41 -:10D470005021117000E6000C2A78824228BF024633 -:10D48000BEF5E06F44D11E4B1E4D18781E491F4B50 -:10D490000192002818BF19462846FFF7C1F9072353 -:10D4A0006B70019A3BE0C9033FF561AF61E700BFD4 -:10D4B000401F0020F83A0020F020002080000700E4 -:10D4C000F84A0020201F0020C42B0020D42B00206D -:10D4D000092C00200A2C00200200CC00C800020009 -:10D4E0000200C800800000201993D574682B00202A -:10D4F000F82A0020CC2B0020052C00200C2C00202A -:10D500000B2C0020400E2020D01F00606C1F0060FC -:10D510002946104D01922846FFF782F9019A25F01D -:10D520001F031544BFF34F8F4FF0E021C1F8703F48 -:10D5300020339D42FAD8BFF34F8FBFF36F8F05485A -:10D540001146FFF78FFC44E50320FFF7D7FC06F0F8 -:10D5500007FF00BF400E20202DE9F0471F46831E25 -:10D56000022B01D9BDE8F087DFF84C9015460C4638 -:10D570003C2209EBC01806464FEAC01A002108F108 -:10D580000400240401F0DAFBB5FA85F20123520904 -:10D5900044EA427449F80A40C8F83870C8F80830BC -:10D5A000002FDFD0034AB34011680B431360BDE87E -:10D5B000F08700BF042B0020000000202DE9F04779 -:10D5C0000D46811E022901D9BDE8F087C701DFF8A9 -:10D5D0004C909246044640373C2200211E4609EBFF -:10D5E00007082D0408F1040001F0A8FBBAFA8AF23A -:10D5F000520945EA427249F807200122C8F838600A -:10D60000C8F80820002EDFD0034B10341968A24060 -:10D610000A431A60BDE8F087042B002000000020B8 -:10D6200012048160C36101F5405342F0800210B4DE -:10D630000124426001F50052046001F5805401F5B7 -:10D640008041C46081615DF8044BC0E904237047E8 -:10D65000831E0A46022B00D97047064B00F11001C9 -:10D660004FF0010C03EBC0100CFA01F14030FFF752 -:10D6700099BB00BF00000020831E0A46022B00D980 -:10D6800070470121024B814003EBC010FFF78ABBBA -:10D690000000002040687047124A134BD2F8200265 -:10D6A00020F07F40984210B584B002D200EB800099 -:10D6B00040000E4C01A90A22FFF750F901A90023EE -:10D6C000204611F8012B01333AB10A2B20F8022F22 -:10D6D000F7D11623237004B010BD5B00DBB22370BA -:10D6E00004B010BD00441F4080969800E01A00204E -:10D6F00000F0DCBA00F0ACBA00F010BB00F0CABA1F -:10D7000000F066BB00F03CBB0846114600F02CBBA5 -:10D71000F8B5144C4FF0E025134E4FF4003204EBF3 -:10D720004024124F06EB40160346C5F88C212146D3 -:10D730003A883046FFF774FF3B882344BFF34F8F8E -:10D74000C5F85C4F2034A342FAD8BFF34F8FBFF324 -:10D750006F8F03203146FFF78FFF4FF40033C5F87A -:10D760000C31F8BDC00E2020601F0020EE2B0020E1 -:10D77000244B2DE9F0411C884368C569C3F30E436F -:10D78000E41A002C24DD204920480A780078D3B21E -:10D790001F4E82421F4807D010F8038036F81870D9 -:10D7A000C7F50072944218D90133002226F81540BB -:10D7B000082B194E88BF134626F8152098BFDAB2F9 -:10D7C000C554164B0A701A6814441C60BDE8F081F9 -:10D7D0002846BDE8F041FFF79BBF07EB4820104902 -:10D7E00022462744084401EB4521FFF719F80B4A6C -:10D7F000284626F8187013682344BDE8F0411360EA -:10D80000FFF786BFEE2B0020032C0020042C002005 -:10D81000742B0020942B0020842B0020702B0020E0 -:10D82000C00E20201D4B1A78002A36D102F0FF03CB -:10D830001B4A12788AB32DE9F0411A4D2A8852B357 -:10D84000194EC2F50068194F3278194C07EB421790 -:10D8500004EBC224424638462146FFF7E1FE04EBC2 -:10D860000802BFF34F8F4FF0E023C3F8704F20340E -:10D87000A242FAD8BFF34F8FBFF36F8F042039460F -:10D88000FFF7E6FE33780133DBB2032B88BF0023BA -:10D89000337000232B80BDE8F0817047082C0020F6 -:10D8A0000A2C0020F02B0020072C002060200020F4 -:10D8B000C01E20202DE9F04F85B0CDE901100029D0 -:10D8C00000F0BF800023604CDFF89881DFF898A15A -:10D8D0005E4F009301235E4A23705E4B1978B8F8BF -:10D8E000003002EB4119002B40F0A7801E461D4678 -:10D8F0009B464846FFF7CEFE10F0800000F08C807B -:10D90000BFF34F8F9AF8003084F800B005B93E6835 -:10D91000002B7DD13B689B1B782B00F287804E4B00 -:10D920001B78002B74D000F09DFA0122B8F800306B -:10D9300015462270002BDCD0464AC3F500601178F2 -:10D940001A4600EBC120454DC9022844019D95426D -:10D9500017D20393DDE901512A46FEF761FF039BCD -:10D960004FF040425B1BA8F800303D4BC3F88420C9 -:10D97000BFF34F8F009800232844237005B0BDE803 -:10D98000F08F364BCD180299FEF74AFF00234FF473 -:10D99000006229464846FFF743FEBFF34F8F05F16B -:10D9A000200205F50063934234BF012340234FF06A -:10D9B000E02205EB4313C2F8705F2035AB42FAD189 -:10D9C000BFF34F8FBFF36F8F04204946FFF740FE30 -:10D9D000204A13780133DBB2032B84BF00231D4A96 -:10D9E0001370B8F80030019AD11A009A1A440191C4 -:10D9F0000092029A1A4400230292194AA8F80030B1 -:10DA0000C2F88430BFF34F8F237000297FF462AFD8 -:10DA1000009805B0BDE8F08F4FF400620D4B8AF816 -:10DA2000000019781346A8F800208AE7012300981F -:10DA30008AF8003005B0BDE8F08F1A46C3F50060E3 -:10DA40007FE70198E5E700BF082C0020C42B0020E9 -:10DA500060200020072C00200A2C0020C01E20205F -:10DA600000002E40F02B0020062C0020704700BF45 -:10DA70002D4B002180222D4870B51B7800242C4DA1 -:10DA80008B422C4E0CBF40234FF400732B8033800D -:10DA900001F054F9284A2146284B14704FF4807243 -:10DAA00027481C8001F04AF9264A1021264B022003 -:10DAB000C2E90044C2E90244244AC3E900441470A4 -:10DAC000234AC3E90244234B1C70234614602246B8 -:10DAD000FFF774FD2246318803201F4BFFF73CFD02 -:10DAE0002346012229880420FFF768FD20460134DF -:10DAF000FFF70EFE082CF9D1184B00214A221848D6 -:10DB0000184C0460C3F88410C3F88020D3F848216F -:10DB1000154942F08072C3F8482121B1134A1378A5 -:10DB200043F00103137070BD0B2C00206020002017 -:10DB3000F22B0020EE2B0020072C0020F02B0020E1 -:10DB4000601F0020742B0020842B0020032C002059 -:10DB5000702B0020042C002031B7000000002E4064 -:10DB6000D82B0020E5B70000000000000D2C00209D -:10DB70002DE9F04F4FF0E0234FF40032DFF8C8A05A -:10DB800083B0C3F88C218B469AF8004000294FD00F -:10DB90008046E4B20027DFF8B490264BABEB0702D7 -:10DBA00025491B78A34204F101043FD0092C234BE3 -:10DBB000404628BF00241E5D39F816C00CEB4623F2 -:10DBC00019441F4B33F81650A5EB0C05AA421CD282 -:10DBD0000CEB462C18491B4C61440192FEF720FEC9 -:10DBE000216839F816505846019AA1EB0B012A44D6 -:10DBF000394429F8162021604FF0E0234FF4003219 -:10DC0000C3F80C2103B0BDE8F08F2A462F44FEF77D -:10DC100007FE0C49E3B230460A68A844521B0A606A -:10DC20008AF80030FFF774FDBB45B6D83846E3E705 -:10DC30000846E1E7032C0020C00E2020942B002092 -:10DC4000742B0020702B0020042C0020842B00203B -:10DC50000B4B0C4A12781978D3B28A420DD001339B -:10DC600009480A4A092B0A4928BF0023C35C31F836 -:10DC7000131002EB4323585C70474FF0FF3070479E -:10DC8000032C0020042C0020942B0020C00E202008 -:10DC9000842B0020044B10B51C680CB1204610BD2D -:10DCA00000F0E0F8204610BD702B00202DE9F84F61 -:10DCB000144E154D33782A78934221D0DCB2DFF828 -:10DCC0005090DFF850B0DFF85080104F0134082C2E -:10DCD0005FFA84FA01D90024A24619F80400DBF89F -:10DCE000003038F8102037F81010521A9B1ACBF871 -:10DCF0000030FFF70DFD86F800A02B78A342E5D198 -:10DD0000BDE8F88F042C0020032C0020842B002079 -:10DD1000942B0020702B0020742B002000B583B0C2 -:10DD200001210DF10700FFF723FF20B19DF8070047 -:10DD300003B05DF804FB4FF0FF30F9E7094B00B585 -:10DD400083B01B788DF807003BB101210DF107006E -:10DD5000FFF7B0FD03B05DF804FB03F0FF0003B074 -:10DD60005DF804FB0A2C0020044B1B7803F0FF0233 -:10DD70000BB1FFF79FBD1046704700BF0A2C002073 -:10DD80002DE9F0410024DFF8448001230D4D2746A2 -:10DD90000D4E88F80030337828462035A34204F130 -:10DDA000010405D0FFF776FC030658BF07F50067AE -:10DDB000042CF0D1BFF34F8F0023384688F8003091 -:10DDC000BDE8F08160200020072C0020082C0020F6 -:10DDD0002DE9F8431D4B1B7813B11D4D2A880AB954 -:10DDE000BDE8F8831B4EC2F500691B4933784A46EB -:10DDF0001A4C01EB43181A4F04EBC324012340468D -:10DE00003B7021460023FFF70BFC04EB0902BFF334 -:10DE10004F8F4FF0E023C3F8704F2034A242FAD85E -:10DE2000BFF34F8FBFF36F8F04204146FFF710FC05 -:10DE300033780133DBB2032B88BF00233370002318 -:10DE40002B80BFF34F8F3B70BDE8F8830A2C002076 -:10DE5000F02B0020072C002060200020C01E202076 -:10DE6000082C00202DE9F8432D4B1E7866B12D4F6C -:10DE70003B784BB90123F1073B7043D4B20726D45A -:10DE800000233B70730701D4BDE8F883264B1A6862 -:10DE9000002AF9D0EFF30582002AF5D1EFF31085BF -:10DEA00072B61868002834D0204C2178002930D16F -:10DEB0000122227042691A60002A2ED0916105B9B0 -:10DEC00062B600258368457798472570DCE7DFF860 -:10DED000648098F80030002BD2D00025DFF85890ED -:10DEE0002B4659F823400135236820461B69984783 -:10DEF00010B163699B68984798F80020EBB29A428A -:10DF0000EFD8BDE7FFF7C6FE0028B7D0AFF300801B -:10DF1000B4E7002DB8D162B6B6E7054B1A60CEE77C -:10DF20000D2C0020FD2B002020270020FB2B0020A3 -:10DF30002C270020FC2B0020A827002003460846A1 -:10DF4000194600F0B9BC00BF024B0146186800F04A -:10DF50000BB800BF881A0020024B0146186801F078 -:10DF6000B1B900BF881A00202DE9F04F01F10B066E -:10DF7000162E83B0044624D8102900F2BA8000F08F -:10DF8000A3FA102618220220B54F3A44A2F1080144 -:10DF900053688B4200F0BA805A68D96822F00302B5 -:10DFA0001A449D68E9608D60516841F00101204686 -:10DFB000516003F1080500F08DFA284603B0BDE872 -:10DFC000F08F36F0070600F19480B14200F29180A4 -:10DFD00000F07AFAB6F5FC7FC0F09A81730A00F07F -:10DFE0008F80042B00F26F81B30903F1390003F134 -:10DFF000380CC3009A4F3B44A3F108055B689D426F -:10E0000006D10CE0002980F22781DB689D4206D012 -:10E010005A6822F00302911B0F29F3DD60463D6927 -:10E02000DFF850C265457CD06A6822F00302931B7A -:10E030000F2B00F37B81002BC7E904CC80F26C81AD -:10E04000B2F5007F80F01A81D308796801334FEA76 -:10E05000521E012202FA0EF20A4357F833E0C5F8C5 -:10E0600008E007EBC3010839E9607A6047F83350EC -:10E07000CEF80C50831001219940914257D811429B -:10E0800006D120F003004900114200F10400FAD04B -:10E0900007EBC0094D468646D5F80C80454508D1AA -:10E0A0001DE1002B80F22481D8F80C80454500F05A -:10E0B0001681D8F8042022F00302931B0F2BF0DD09 -:10E0C0002046D8E9025408EB060146F00106C8F8DC -:10E0D0000460EC60A56043F00104C7E90411C1E9E4 -:10E0E00002CC4C6048F8023000F0F4F908F1080561 -:10E0F00002E00C2323600025284603B0BDE8F08F22 -:10E100004FF4007340204FF03F0C73E7D3689A42FE -:10E1100008BF02307FF440AF3D69DFF858C1654564 -:10E1200082D17A688310012199409142A7D9BD68B4 -:10E130006B6823F003094E4503D8A9EB06030F2BA8 -:10E140007ADCDFF834B1474BDBF800201B68013282 -:10E15000334405EB090A00F0338103F580530F3394 -:10E1600023F47F6828F00F084146204600F0F4FEB3 -:10E17000411C024600F0F380824500F2EE803A4BEB -:10E18000196841441960084600F04E81DBF8001020 -:10E19000019301311BBFA2EB0A010918CBF8002043 -:10E1A000196012F0070B00F01781CBF108010A4447 -:10E1B000CBF5805190440831A1EB0801C1F30B0A63 -:10E1C00051462046009200F0C7FE421CDDE90023C4 -:10E1D00000F04F81801A00EB0A081968BA6048F015 -:10E1E00001005144BD425060196000F02981B9F12D -:10E1F0000F0F40F227816868A9F10C0C2CF0070C76 -:10E2000000F0010040EA0C0068604FF0050E05EBDD -:10E210000C00BCF10F0FC0E901EE00F23281506832 -:10E220001546124B1A688A4238BF1960104B1A689B -:10E230008A4238BF196094E0AA1943F0010346F0FE -:10E2400001066E602046BA60536000F043F908355D -:10E25000284603B0BDE8F08FD9681A44A1E600BF94 -:10E260006C160020B829002088290020B029002041 -:10E27000B429002074160020741A0020B2F5206F13 -:10E280004FEA522363D3142B00F2B78003F15C01F1 -:10E29000C9005B3307EB010E7958AEF1080E8E45CD -:10E2A00000F091804B6823F00303934202D9896800 -:10E2B0008E45F7D1D1F80CE07A68C5E9021ECEF898 -:10E2C0000850CD60D6E6142B59D9542B00F29D800E -:10E2D000330B03F16F0003F16E0CC3008AE60EF1FD -:10E2E000010E1EF0030F05F108057FF4D5AE51E0D5 -:10E2F000424445465368D8F80C1043F0010353607C -:10E3000055F8083F2046D9608B6000F0E3F8F3E64B -:10E31000F00806F1080237E62A442046536843F025 -:10E3200001035360083500F0D5F8E5E6A919204649 -:10E3300046F0010643F001046E60C7E90411C1E92B -:10E3400002CC4C60AB5000F0C5F80835D4E6930918 -:10E3500003F13901C90038339CE7BD425FD0BD6885 -:10E36000686820F003084645A8EB060302D80F2B87 -:10E370003FF762AF204600F0ADF80025BCE603F1A0 -:10E380005C0003F15B0CC30034E659F808394B45D7 -:10E3900040F0968010F0030F00F1FF30F5D17B685C -:10E3A00023EA01037B60490099423FF6C0AE19B9E8 -:10E3B000BDE649000EF1040E1942FAD0704667E638 -:10E3C00003F11008D0E69A104FF001087B6808FAB4 -:10E3D00002F21A437A6070E702EB08014942C1F386 -:10E3E0000B0A51462046009200F0B6FD431CDDE9C1 -:10E3F00000237FF4EFAEDA46EFE6542B25D8130B5B -:10E4000003F16F01C9006E3344E7B3F5AA7F25D845 -:10E41000F30B03F1780003F1770CC300EAE5294B15 -:10E42000186840441860B1E6CAF30B0CBCF1000F49 -:10E430007FF4ACAEBD68C84448F001006860F0E607 -:10E440001546EEE60123536094E7B3F5AA7F23D87F -:10E45000D30B03F17801C90077331BE740F2545224 -:10E46000934223D8B30C03F17D0003F17C0CC3006D -:10E47000C0E5ABF1080BD844A8EB02084FF0000A46 -:10E48000ABE605F108012046009300F01BFFBD68D4 -:10E49000009B68681968C4E640F254518B420BD85F -:10E4A000930C03F17D01C9007C33F3E64FF47E73D6 -:10E4B0007F204FF07E0C9DE54FF47E717E23E9E6D0 -:10E4C0007B6870E788290020014800F09BBD00BFF1 -:10E4D00080290020014800F097BD00BF802900205E -:10E4E0002DE9F84F1746002900F098800C4607F1F7 -:10E4F0000B058046FFF7E8FF162D54F8041C5BD887 -:10E5000010252A46AF425CD821F003069642A4F1BA -:10E51000080962DABC4BD3F808C009EB0600844551 -:10E5200000F09780D0F804C02CF0010303445B682E -:10E53000DB0768D42CF0030C06EB0C03934247DA9C -:10E54000CB0710D454F8083CA9EB030ADAF80430DE -:10E5500023F003018C44B444944580F21181731874 -:10E56000934280F2E88039464046FFF7FDFC0746BB -:10E57000E0B154F8043C23F001034B44A0F108023D -:10E58000934200F0D280321F242A00F2F580132A31 -:10E5900000F2AC8003462246116819605168596048 -:10E5A00092689A602146404600F08CFE4046FFF794 -:10E5B00091FF3846BDE8F88F25F00705002D2A4663 -:10E5C000A0DA0C23C8F8003000273846BDE8F88FE1 -:10E5D0001E46D0E90223D3609A60731B0F2B22D80A -:10E5E000D9F8043003F0010333434E44C9F8043032 -:10E5F000736843F00103736040462746FFF76AFFE4 -:10E600003846BDE8F88FC907ADD454F8083CA9EBEB -:10E61000030ADAF8041021F00301A0E7BDE8F84F7F -:10E620001146FFF7A1BCD9F8042009EB050102F05F -:10E6300001024E4443F001032A43C9F804204B6011 -:10E64000736843F0010308317360404600F03AFEFE -:10E65000D2E7DCF8040020F0030B06EB0B0C05F10D -:10E66000100084454DDAC9073FF57DAF54F8081C0A -:10E67000A9EB010ADAF8041021F003018B44B3443A -:10E6800058453FF76CAF5746DAF80C1057F8080FAB -:10E69000321F242AC160886000F2DB80132A40F216 -:10E6A000D6802168CAF808106168CAF80C101B2AC5 -:10E6B00000F2DF8008340AF11002216811606168FD -:10E6C0005160A16891600AEB0501ABEB050242F0D5 -:10E6D000010299604A60DAF8043003F001032B4329 -:10E6E0004046CAF80430FFF7F5FE6EE72368036082 -:10E6F000636843601B2A68D804F1080200F108032C -:10E700004AE709EB05029A60ACEB050343F001030D -:10E71000536054F8043C03F001032B43404644F893 -:10E72000043CFFF7D7FE27464FE750F8043C23F0A0 -:10E7300003031E4451E75746DAF80C1057F8080F48 -:10E74000321F242AC16088604CD8132A48D9216816 -:10E75000CAF808106168CAF80C101B2A56D8083489 -:10E760000AF110021E462368136063685360A368B1 -:10E770009360D1463C4630E7214600F063FA11E74A -:10E78000D0E902135746CB60996057F8081FDAF8B2 -:10E790000C30CB60321F242A99602DD8132A29D936 -:10E7A0002368CAF808306368CAF80C301B2A42D8BC -:10E7B00008340AF1100322681A6062685A60A2687D -:10E7C0009A606646D1463C4607E7A3688360E368E3 -:10E7D000C360242A26D004F1100200F11003DBE606 -:10E7E0003A46BFE7214638461E46D14600F02AFA8F -:10E7F0003C46F2E63B46DEE7214638466646D146D1 -:10E8000000F020FA3C46E8E66C160020A168CAF841 -:10E810001010E168CAF81410242A20D010340AF12C -:10E8200018029FE7236903616169416104F11802DD -:10E8300000F11803B0E6A368CAF81030E368CAF81C -:10E840001430242A21D010340AF11803B3E73A46D1 -:10E8500033E72146384600F0F5F9164B33E72269D5 -:10E86000CAF818206269CAF81C2018340AF120027C -:10E8700078E7A168CAF81010E168CAF81410242AD1 -:10E880000DD010340AF1180217E72369CAF81830BE -:10E890006369CAF81C3018340AF120038BE7226937 -:10E8A000CAF818206269CAF81C2018340AF120023C -:10E8B00003E700BF6C16002013460A4601460220FB -:10E8C00000F06CBC024A0349034800F0BBB800BF2B -:10E8D0007C1A002095F70000A80F00200C4B41681F -:10E8E000994210B5044601D002F074FFA168094BAB -:10E8F000994202D0204602F06DFFE168064B994232 -:10E9000004D02046BDE8104002F064BF10BD00BF37 -:10E91000BC290020242A00208C2A00202DE9F8435D -:10E920002A4C2B4B2B48DFF8C090DFF8C0802A4FD1 -:10E930001860002504230822294604F15C00274EB4 -:10E940006566C4E90253C4E90055C4E90455A561EC -:10E9500000F0F4F9224B63670822294604F1C40051 -:10E96000C4E90749C4E90987C4E91A55C4E91E5531 -:10E97000C4F8CC502567C4F88050E66200F0DEF998 -:10E98000184BC4F8DC30294604F16803082204F56A -:10E990009670C4F88430C4E92298C4E92476C4E9A6 -:10E9A0003455C4E93855C4F83451C4F8D850C4F8C3 -:10E9B000E85000F0C3F904F1D003C4E93C98C4E97D -:10E9C0003E76C4F8EC30BDE8F88300BFBC290020D7 -:10E9D000F42A002085C80000B1CA0000D1CA000096 -:10E9E00009000100120002004DCA000071CA0000B7 -:10E9F00010B504460A4800F005FB636B23B9094BC8 -:10EA0000094A1B68626323B1BDE81040044800F066 -:10EA1000FBBAFFF783FFBDE81040014800F0F4BAED -:10EA200084290020F42A00209DC80000014800F03D -:10EA3000E9BA00BF84290020014800F0E5BA00BF10 -:10EA4000842900202DE9F84380460F4616464FF0F2 -:10EA50000009D6E90154013D11D4A389012B05F128 -:10EA6000FF3508D9B4F90E300133214603D04046B2 -:10EA7000B84749EA00096B1C04F16804EDD1366817 -:10EA8000002EE6D14846BDE8F88300BF10B50C461D -:10EA9000B1F90E1000F04AFA002803DB236D03449D -:10EAA000236510BDA38923F48053A38110BD00BF4B -:10EAB0002DE9F0410C46B1F90C101F46CB05054677 -:10EAC00016460BD421F48051A1813B46B4F90E10B7 -:10EAD00032462846BDE8F04100F050BAB4F90E10B5 -:10EAE0000223002200F00CFAB4F90C10EAE700BF90 -:10EAF00010B50C46B1F90E1000F002FAA389421CC1 -:10EB00000EBF23F4805343F480532065A38110BDCE -:10EB1000B1F90E1000F0E2B9F0B5ADF5057D04AF26 -:10EB2000009313464FF400720E460392394603AA2F -:10EB3000054600F025F888B104460246039B31469D -:10EB4000284600F01BFABC42039004D02846214618 -:10EB500000F0B8FB03980DF5057DF0BD4FF0FF30D8 -:10EB6000F9E700BF10B4054C8446134620685DF8F1 -:10EB7000044B0A466146FFF7CFBF00BF881A00204A -:10EB800030B5146815469BB01A4609B1002C19D14E -:10EB900000214FF42273ADF80C30009104914FF630 -:10EBA000FF7302910591ADF80E3069461E9B01F08E -:10EBB0006FF8002813DB009B286000221A7004986D -:10EBC0001BB030BD4FF4C16300910491ADF80C301F -:10EBD0002146E4DA8B23036000201BB030BD002007 -:10EBE000EEE700BF032A70B514D940EA01039B0782 -:10EBF00022D104460B46194620460E680568B542E8 -:10EC000004F1040403F1040316D1043A032A204654 -:10EC10001946F0D8541E9AB1421E013901E0C318BA -:10EC20000CD012F801EF11F801CFE645A4EB020376 -:10EC3000F5D0AEEB0C0070BD541EEDE7184670BD6C -:10EC4000104670BD88420DD98B1883420AD900EB5B -:10EC5000020CBAB1624613F801CD02F801CD994217 -:10EC6000F9D170470F2A0ED8034602F1FF3C4AB192 -:10EC70000CF1010C013B8C4411F8012B03F8012F1E -:10EC80006145F9D1704740EA01039B0750D1A2F1D9 -:10EC9000100370B501F1200C23F00F0501F1100EE7 -:10ECA00000F11004AC441B095EF8105C44F8105CE1 -:10ECB0005EF80C5C44F80C5C5EF8085C44F8085C98 -:10ECC0005EF8045C44F8045C0EF1100EE64504F1B5 -:10ECD0001004E9D1013312F00C0F01EB031102F023 -:10ECE0000F0400EB031327D0043C24F003064FEA83 -:10ECF000940C1E441C1F8E465EF8045B44F8045FAF -:10ED0000B442F9D10CF1010402F0030203EB8403D5 -:10ED100001EB840102F1FF3C4AB10CF1010C013B13 -:10ED20008C4411F8012B03F8012F6145F9D170BD16 -:10ED300002F1FF3C03469BE72246EBE7830730B531 -:10ED400048D0541E002A3FD0CAB2034601E0013C1D -:10ED50003AD303F8012B9D07F9D1032C2DD9CDB25D -:10ED600045EA05250F2C45EA054536D9A4F11002E0 -:10ED700022F00F0C03F1200EE6444FEA121C03F1BF -:10ED8000100242E9045542E9025510327245F8D1A9 -:10ED90000CF1010214F00C0F03EB021204F00F0C43 -:10EDA00013D0ACF1040323F003030433134442F8FB -:10EDB000045B9342FBD10CF003042CB1C9B21C4498 -:10EDC00003F8011B9C42FBD130BD64461346002C66 -:10EDD000F4D1F9E703461446BFE71A46A446E0E734 -:10EDE000002A3ED040EA01039B0730B584462FD16C -:10EDF000032A2DD90B4608E0043A8446194625D04B -:10EE00001EF0803F22D1032A22D90468194653F804 -:10EE1000045BA4F1013EAC4284462EEA040E00F1EC -:10EE20000400E9D09CF800000C78A0421BD1E64613 -:10EE300068B11EF8010F11F8014FA2EB0E03A042BA -:10EE400003F1FF330FD11CEB0303F1D1002030BDE0 -:10EE50009CF800000C78844205D1012AF6D0E646E1 -:10EE6000E6E710467047001B30BD00BF40EA0103D3 -:10EE70009B0730B501D1032A0FD8844601F1FF3E2C -:10EE800007E01EF8011F03F8011B541EC1B19C4688 -:10EE900022466346002AF4D130BD0B46844619460B -:10EEA00053F8045BA5F1013424EA050414F0803F13 -:10EEB000E4D1043A032A4CF8045B1946EFD8DDE7A5 -:10EEC0009444002CE8D003F8011B6345FBD130BD0E -:10EED000014B93F8280170470015002038B5074D05 -:10EEE0000022044608462A60FDF716FF431C00D0A6 -:10EEF00038BD2B68002BFBD0236038BD082B0020C9 -:10EF000038B50C46084D8446114620461A46002363 -:10EF10002B606446FDF70CFF431C00D038BD2B6806 -:10EF2000002BFBD0236038BD082B002038B50C46E1 -:10EF3000084D8446114620461A4600232B6064463D -:10EF4000FDF7E8FE431C00D038BD2B68002BFBD03A -:10EF5000236038BD082B002038B5074D0022044639 -:10EF600008462A60FDF7BCFE431C00D038BD2B6864 -:10EF7000002BFBD0236038BD082B002038B50C4691 -:10EF8000084D8446114620461A4600232B606446ED -:10EF9000FDF7B8F9431C00D038BD2B68002BFBD01F -:10EFA000236038BD082B0020014B1868704700BF54 -:10EFB000881A002070B50D4E0D4D761BB61006D088 -:10EFC000002455F8043B01349847A642F9D1094E74 -:10EFD000094D761B05F0C8F9B61006D0002455F887 -:10EFE000043B01349847A642F9D170BDD01D0060A2 -:10EFF000D01D0060481E0060D01D0060704700BF3B -:10F00000704700BF704700BF704700BF000000009E -:10F0100001F0FF01102A2BDB10F0070F08D010F8C9 -:10F02000013B013A8B422DD010F0070F42B3F6D1CD -:10F03000F0B441EA012141EA014122F007047FF0E6 -:10F0400000070023F0E80256083C85EA010586EA3D -:10F05000010685FA47F5A3FA87F586FA47F6A5FA79 -:10F0600087F68EB9EED1F0BC01F0FF0102F0070285 -:10F0700032B110F8013B013A83EA010313B1F8D130 -:10F080000020704701387047002D06BF3546033811 -:10F09000073815F0010F07D1013015F4807F02BF4A -:10F0A000013015F4C03F0130F0BC0138704700BF9B -:10F0B0000000000000000000000000000000000050 -:10F0C00090F800F06DE9024520F007016FF0000CA8 -:10F0D00010F0070491F820F040F049804FF0000450 -:10F0E0006FF00700D1E9002391F840F000F108002B -:10F0F00082FA4CF2A4FA8CF283FA4CF3A2FA8CF363 -:10F100004BBBD1E9022382FA4CF200F10800A4FAC9 -:10F110008CF283FA4CF3A2FA8CF3E3B9D1E904231D -:10F1200082FA4CF200F10800A4FA8CF283FA4CF354 -:10F13000A2FA8CF37BB9D1E9062301F1200182FA0E -:10F140004CF200F10800A4FA8CF283FA4CF3A2FA14 -:10F150008CF3002BC6D0002A04BF04301A4612BA22 -:10F16000B2FA82F2FDE8024500EBD2007047D1E925 -:10F17000002304F00305C4F100004FEAC50514F0B4 -:10F18000040F91F840F00CFA05F562EA05021CBF85 -:10F1900063EA050362464FF00004A9E72DE9F04752 -:10F1A000DFF87CA00646DAF8000098460F46914644 -:10F1B000FFF728FF184B1C6824B365681F2D24DC5B -:10F1C0005EB96B1C0235DAF80000636044F8257004 -:10F1D000FFF71AFF0020BDE8F08704EB850101234B -:10F1E000C1F88890D4F88821AB401A43022EC4F8A5 -:10F1F0008821C1F80881E4D1D4F88C211A43C4F8DD -:10F200008C21DEE7054C1C60D7E7DAF80000FFF739 -:10F21000FBFE4FF0FF30DEE7E8270020EC27002060 -:10F22000F4140020F8B5244F0C460646FFF74CF9BD -:10F23000BB685D68C4F57E610F3125F003054B198D -:10F2400023F47F6323F00F03A3F58054B4F5805FAC -:10F2500007DB00213046FFF77FFEBB682B44984256 -:10F2600004D03046FFF736F90020F8BD6142304641 -:10F27000FFF772FE01300DD0104ABB682D1B45F020 -:10F2800001055D60136830461B1B1360FFF722F910 -:10F290000120F8BD00213046FFF75EFEBA68831AF0 -:10F2A0000F2BDEDD43F001035360054B03491B6860 -:10F2B000C01A0860D5E700BF6C160020882900201E -:10F2C000741A0020002961D0F8B50C460646FFF7F5 -:10F2D000FBF854F8042C7B4FA4F1080522F001013F -:10F2E00005EB010CB868DCF80430604523F003033B -:10F2F00000F08B80D207CCF8043032D454F8082CBC -:10F30000AD1A1144AA6807F1080082426AD00CEBDA -:10F310000304D4F804E0EC68D4601EF0010FA2608E -:10F3200000F0978041F001036B60CCF80010B1F55C -:10F33000007F35D27868CB080122490901338A4021 -:10F34000024357F833107A6007EBC302083AC5E965 -:10F35000021247F83350CD603046BDE8F840FFF761 -:10F36000B9B80CEB03025268D00710D4194407F166 -:10F370000800DCF80830834273D0DCF80C20DA6037 -:10F38000936041F001036B606950D0E7704741F032 -:10F390000103B1F5007F44F8043CCCF80010C9D358 -:10F3A000B1F5206F4FEA512348D28B0903F13900A0 -:10F3B00003F13802C300F818FB580838984259D0B6 -:10F3C0005A6822F003028A4202D99B689842F7D118 -:10F3D000D868C5E902308560DD603046BDE8F84098 -:10F3E000FFF778B80CEB03025268D20763D40B44E2 -:10F3F000DCE90212CA60916043F001026A603046A3 -:10F40000EB50BDE8F840FFF765B80B44D10707D4CF -:10F4100054F8082CAD1A1344D5E90212CA60916061 -:10F4200043F001026A60284ABD6012689A4293D88C -:10F43000264B30461968FFF7F5FE8DE7142B0AD9E5 -:10F44000542B1FD80B0B03F16F0003F16E02C300A6 -:10F45000B1E719448DE703F15C0003F15B02C300DF -:10F46000A9E741F00103C7E90455C5E902006B6053 -:10F47000695071E779689210012404FA02F20A4394 -:10F480007A60A6E7B3F5AA7F06D8CB0B03F1780024 -:10F4900003F17702C3008EE740F25452934206D83C -:10F4A0008B0C03F17D0003F17C02C30083E74FF472 -:10F4B0007E737E227FE741F001036B60CCF8001081 -:10F4C0004AE700BF6C160020781A0020B8290020F7 -:10F4D00082B049B15AB16BB113780B601278101E2B -:10F4E00018BF012002B0704701A9002AF3D11046CD -:10F4F00002B070476FF00100F4E700BF436C70B5D5 -:10F5000005460C464BB153F8240080B1026843F81D -:10F5100024200023C0E9033370BD2122042102F01E -:10F52000DFFA034668640028EDD1002070BD012198 -:10F5300001FA04F6721D9200284602F0D1FA002862 -:10F54000F3D0C0E90146E4E731B1436C4A6853F8AF -:10F550002200086043F82210704700BF2DE9F041F7 -:10F560000E6980460F461D4601F1140E0020DEF89C -:10F5700000108CB202FB0453090C4FEA134C02FB3F -:10F5800001CC01309CB204EB0C4486424EF8044B93 -:10F590004FEA1C45EBDC3DB1BB68B34207DD07EB2E -:10F5A000860301365D613E613846BDE8F0817968C9 -:10F5B00040460131FFF7A2FF0446B0B13A6902327A -:10F5C00007F10C0192000C30FDF72AF9D8F844300D -:10F5D0007A6853F82210396043F82270274607EB07 -:10F5E000860301365D613E61DEE7034B0348224638 -:10F5F000BA2102F055FA00BFA0090020B40900208A -:10F60000030C1B04D3B90004102310F07F4F04BF78 -:10F610000002083310F0704F04BF0001043310F0F3 -:10F62000404F04BF80000233002805DB10F0804FFC -:10F6300003F1010308BF2023184670470023E4E7C5 -:10F64000036813F0070208D0D9071FD49A0722D500 -:10F650005B08036001221046704799B209B91B0C80 -:10F660001022D9B209B908321B0A190704BF1B09B5 -:10F670000432990704BF9B080232D90703D45B0800 -:10F6800002F1010205D003601046704700221046C7 -:10F6900070472022DFE79B08022203601046704774 -:10F6A00038B5436C04460D464BB15868B0B102689A -:10F6B0005A6000220123C0E90435C26038BD21220E -:10F6C000042102F00DFA034660640028EDD1094BD5 -:10F6D0000948002240F2451102F0E2F91C22012102 -:10F6E000204602F0FDF90028F1D001220223C0E9F2 -:10F6F0000123DEE7A0090020B40900202DE9F04F26 -:10F700000E691569AE4285B08846144605DB2A4667 -:10F71000234635460C4616469846A3686168AF19DD -:10F72000BB42B8BF0131FFF7E9FE0190002800F0AD -:10F730008780019B03F1140909EB870AD14505D2A3 -:10F740004B46002243F8042B9A45FBD808F11408D5 -:10F7500008EB860B04F11403D8451A4603EB850524 -:10F760005FD22B1B153B23F0030304331534A54252 -:10F7700038BF0423CDE902A7AC461F46924605E0F8 -:10F78000090C29D1C34509F1040948D958F8041BCB -:10F790008DB2002DF4D056464C46002356F8041B7B -:10F7A00022681FFA81FE90B2090C05FB0E00120CB4 -:10F7B000034405FB012202EB13429BB243EA0243DE -:10F7C000B44544F8043B4FEA1243E7D849F8073000 -:10F7D00058F8041C090CD5D0D9F8003050461A4608 -:10F7E0004C4600260588120C01FB052216449BB2EC -:10F7F00043EA064344F8043B50F8045B22682D0CAE -:10F8000093B201FB053303EB164384454FEA1346DD -:10F81000E8D8C34549F8073009F10409B6D8DDE94D -:10F8200002A7002F02DC05E0013F03D05AF8043D97 -:10F83000002BF9D0019B18461F6105B0BDE8F08F81 -:10F84000034B0448019A4FF4B17102F029F900BF4B -:10F85000A0090020B409002012F003032DE9F041B3 -:10F860001446064632D10D46A41020D0D6F840806A -:10F87000B8F1000F33D0E3074FF0000707D464104E -:10F8800015D0D8F80000A8B18046E307F7D5424666 -:10F8900029463046FFF732FFB5B16968736C6410D2 -:10F8A00053F821202A6043F821500546E9D1284623 -:10F8B000BDE8F081424641463046FFF71FFFC8F8D9 -:10F8C000000007608046E0E70546D8E7013B0F4AA5 -:10F8D00052F823200023FFF741FE0546C4E701212B -:10F8E0003046FFF70BFE804640B1012340F2712203 -:10F8F000C0E90432002330640360BCE7044B0548D0 -:10F90000424640F2451102F0CBF800BFB40E002091 -:10F91000A0090020B40900202DE9F0470D46144647 -:10F920002F69AB68496807EB62177E1C9E428046D0 -:10F930004FEA621904DD5B009E4201F10101FADC2D -:10F940004046FFF7DBFD8446002852D0B9F1000F96 -:10F9500000F114020EDD09F105014FEA810E134694 -:10F9600000EB8101002043F8040B8B42FBD1AEF188 -:10F9700014031A44296905F1140314F01F0E03EB54 -:10F9800081012ED0CEF1200910464FF0000A1C68EC -:10F9900004FA0EF444EA0A0440F8044B53F8044B0A -:10F9A000994224FA09FAF2D84B1B153B23F00303C2 -:10F9B000043305F11500814238BF0423BAF1000F6A -:10F9C00018BF374642F803A0D8F844306A68CCF82C -:10F9D000107053F822102960604643F82250BDE8A9 -:10F9E000F087043A53F8040B42F8040F9942F9D80F -:10F9F000EAE7034B034862464FF4EF7102F050F818 -:10FA0000A0090020B40900200B6984460069C01ACF -:10FA100016D10CF1140C14310CEB830210B401EB71 -:10FA2000830301E0944508D252F8044D53F8041DB5 -:10FA30008C42F7D005D24FF0FF305DF8044B704791 -:10FA4000704701205DF8044B704700BF2DE9F84F67 -:10FA50000F691369FF1A002F0E4690467FD101F1FE -:10FA60001405143202EB830205EB830301E09D428F -:10FA700078D253F8041D52F8044DA142F7D069D34F -:10FA80007168FFF73BFD8146002877D03569D8F8CB -:10FA90001020C76008F1140E06F1140009F1140AD1 -:10FAA00006F110010EEB820200EB850756464FF07F -:10FAB000000C5EF8044B51F804BFA3B21CFA8BFC97 -:10FAC000ACEB03034FEA144CCCEB1B4C0CEB234C7C -:10FAD0009BB243EA0C43724546F8043B4FEA2C4C78 -:10FAE000E7D8A2EB0801153908F11508424521F0C5 -:10FAF000030404F1040438BF0424204421F0030269 -:10FB000038BF002287425244544418D92646014641 -:10FB100051F8043B1CFA83FC4FEA2C4202EB1342DF -:10FB20001FFA8CFC4CEA02438F4246F8043B4FEA32 -:10FB3000224CEDD8013F3F1A27F00307E21923B901 -:10FB400052F8043D013D002BFAD0C9F81050484648 -:10FB5000BDE8F88F334601274646984690E7F9DB23 -:10FB600000278DE70021FFF7C9FC814668B101221B -:10FB70000023C9E904234846BDE8F88F064B07482F -:10FB80004A4640F2452101F08BFF034B03484A46A9 -:10FB900040F2372101F084FFA0090020B4090020C1 -:10FBA0002DE9F043884683B0012157EC106B1546D0 -:10FBB000FFF7A4FC0446002851D0C7F30A59C7F345 -:10FBC0001303B9F1000F01D043F48013002E019309 -:10FBD00018D101A8FFF734FD019A6261012200F1FA -:10FBE00020032261B9F1000F25D0A9F2334909EBB6 -:10FBF00003022046C3F13503C8F800202B6003B090 -:10FC0000BDE8F08368460096FFF71AFD034610B37F -:10FC1000DDE90002C3F1200102FA01F10143DA40FB -:10FC200061610192002AA26114BF022201222261B5 -:10FC3000B9F1000FD9D1A3F23243C8F8003004EB78 -:10FC400082031869FFF7DCFCC0EB421320462B60EF -:10FC500003B0BDE8F083009A6261019AE2E7034BCA -:10FC60000348224640F20F3101F01AFFA00900209C -:10FC7000B409002049B1FF2A02D80A700120704758 -:10FC80008A2303604FF0FF3070470846704700BF7B -:10FC90002DE9F04F2DED088BD1B00C460BEE101A6C -:10FCA00090460893834601F0BBFE03681293184602 -:10FCB000FFF706FA20AF1090082200213846FFF720 -:10FCC0003DF8A3891B0603D52369002B00F0558757 -:10FCD00000239FED838B9FED849BCDE92533CDE9F8 -:10FCE0001333CDE9153327AA0E932492924611932C -:10FCF00004934446A1467E4BD3F8E450FFF7E8F85E -:10FD00004A4603461CA900975846A847002800F019 -:10FD1000B080C0F2A6801C9A252A034601D09944DF -:10FD2000E9E7B9EB0405064640F0A78000234FF051 -:10FD3000FF328DF867309846069309F1010999F86A -:10FD4000003003922B25202609F10109A3F120029E -:10FD50005A2A00F2CF80DFE812F0E802CD00CD0091 -:10FD6000E302CD00CD00CD006A00CD00CD0005023C -:10FD70008402CD001002C902CD00BD025B005B0011 -:10FD80005B005B005B005B005B005B005B00CD0029 -:10FD9000CD00CD00CD00CD00CD00CD005301CD0074 -:10FDA00083011A02530153015301CD00CD00CD0050 -:10FDB000CD001502CD00CD009602CD00CD00CD00C6 -:10FDC000AB01CD00AA02CD00CD00E306CD00CD00F1 -:10FDD000CD00CD00CD00CD00CD00CD005301CD0034 -:10FDE0008301DE015301530153017702DE017F00DD -:10FDF000CD008902CD005F02E0062F027F00CD001A -:10FE0000AB017C00B806CD00CD00BD06CD007C0066 -:10FE1000A3F13002002119F8013B01EB810102EB53 -:10FE20004101A3F13002092AF5D906918EE758461F -:10FE300001F0F6FD436815931846FFF741F9169057 -:10FE4000584601F0EDFD83681393169B002B40F09C -:10FE50002D8699F8003077E799F8003048F02008AF -:10FE600072E7082200213846FEF768FF0123994413 -:10FE700041E7B9EB0405064611D0269B2B44269397 -:10FE8000259B0133072BCAE9004525931CDC0AF1A9 -:10FE9000080A049B2B440493002E7FF447AF269B53 -:10FEA000002B41F00B821BEE103AB3F90C3013F02B -:10FEB000400F049B18BF4FF0FF330493049851B0D8 -:10FEC000BDEC088BBDE8F08F1BEE101A24AA584633 -:10FED00002F092FD0028E6D10DF19C0AD9E700BF9F -:10FEE0000000000000000000FFFFFFFFFFFFEF7FAA -:10FEF000001500200B93002BD1D00021CDE90C116F -:10FF00008DF8DC3001238DF867100293079105937B -:10FF100003910F9137AC18F00203099302D0029BB2 -:10FF20000233029318F084030A9305D1069B029AC8 -:10FF30009D1A002D00F36983269A89B125990DF148 -:10FF4000670001310132CAF8000007294FF00100B3 -:10FF500026922591CAF8040000F3A2830AF1080A48 -:10FF6000099B83B1259B1AA901330232CAF80010FC -:10FF7000072B4FF0020126922593CAF8041000F3D4 -:10FF8000A3830AF1080A0A9B802B00F06C82039B72 -:10FF900005995D1A002D00F3A58218F4807F40F0CA -:10FFA0000D82059BCAF804301A44259BCAF800400C -:10FFB0000133072B2692259300F31B830AF1080ACD -:10FFC00018F0040F05D0069B02995C1A002C00F370 -:10FFD0008883049B069902988142ACBF5B181B186A -:10FFE0000493002A40F0B08200232593079B1BB1A5 -:10FFF00007995846FFF766F90DF19C0A4C4679E6D9 -:02000004600199 -:100000000B93089B073323F00703B3EC028BB0EE8E -:10001000C87BB4EE497BF1EE10FA089340F3E98413 -:10002000B5EEC08BF1EE10FA01F159809DF8671022 -:10003000AB4CAC4B28F080080B9A472AC8BF1C4633 -:100040000023CDE90C330322079302920592039318 -:100050000F9300293FF45FAF029B013302935AE7ED -:10006000432B0B9303D018F0100F00F05D85089D13 -:100070000822002122A837ACFEF760FE22AB55F81B -:10008000042B2146584602F071FC034601330590CB -:1000900001F0EE82059B089523EAE37302930021A9 -:1000A000CDE90C118DF86710079103910F9132E79C -:1000B0000B93089B1A4600238DF86730134653F8BC -:1000C000044B0893002C00F048850B9B532B00F049 -:1000D000EC8618F010030C9340F0E786039B5D1C40 -:1000E00001F0E5800C991A462046FEF791FF079033 -:1000F000002801F02883079B1A1B05920C9B039391 -:1001000022EAE2720F930D93079373239DF8671011 -:1001100002920B939DE718F0200F0B93089B3DD0A4 -:10012000073323F007031A4611465B6851F8082B82 -:1001300008911946002BC0F20C84039B013300F098 -:100140009E8228F0800052EA0103029040F09982DA -:10015000039B002B40F09A82804600230393059373 -:1001600050AC06E1089B53F8042B0692002A80F25B -:100170001984069A08935242069299F8003048F082 -:100180000408E1E599F8003048F00808DCE548F09B -:10019000100818F0200F0B93089BC1D118F0100F16 -:1001A00040F00B8418F0400F00F0038433F9042B67 -:1001B0000893D1170B46BDE7089B48F00202029254 -:1001C00053F8042B089347F63003ADF868307820D5 -:1001D000454B1193002102230B900020039C8DF8C6 -:1001E0006700601C00F0AD80029820F0800852EAA1 -:1001F000010040F0A480002C40F0AE86002BACD172 -:10020000029B13F00103059300F0D18330238DF896 -:100210003F310DF23F14ACE018F0200F40F0D483D2 -:1002200018F0100F40F09F8618F0400F40F09787AD -:1002300018F4007F00F09786089B049953F8042B6C -:10024000089311704C4655E599F80030682B03BFB0 -:1002500099F8013048F4007809F1010948F04008A4 -:1002600072E599F800308DF867506DE599F8003027 -:100270006C2B03BF99F8013048F0200809F10109FF -:1002800048F0100860E50B9348F0100818F02001C2 -:1002900000F05183089B073323F00703596853F894 -:1002A000082B089328F480630293002395E70B93AF -:1002B00048F010030293029B13F0200100F0298301 -:1002C000089B073323F00703596853F8082B08935A -:1002D000012382E799F8003048F0800834E500BF38 -:1002E000800B0020840B0020900B0020494611F861 -:1002F000013B2A2B01F04982A3F13002092A8946E9 -:1003000098BF002101F2448119F8013B01EB810102 -:1003100002EB4101A3F13002092AF5D9039115E559 -:1003200099F8003048F001080EE59DF86730002B81 -:100330007FF48FAD99F800308DF8676004E5CDF853 -:100340000880012B00F09D81022B50AC20D1119828 -:1003500002F00F031209C35C04F8013D42EA017286 -:10036000090952EA0103F3D150AB1B1BDDF80880E9 -:100370000593059A03989DF8671082424FF0000399 -:10038000B8BF0246CDE90C33079302920F9360E6A3 -:1003900002F00703D20842EA4172C908303352EA38 -:1003A0000105204604F8013DF2D1029AD10700F17F -:1003B0004D8250AB1B1B90460593DAE70B9B652BD8 -:1003C00040F3D480B5EE408BF1EE10FA40F0C181DD -:1003D000259BBA49CAF80010013301320121072BCD -:1003E00026922593CAF8041000F351850AF1080AF1 -:1003F0001B9B0E998B4280F2D082109B12991A445B -:10040000CAE90013259B26920133072B259300F39D -:1004100097830AF1080A0E9B5C1E002C7FF7D0AD73 -:10042000102C259B40F36E851BEE106A102505E00D -:100430000AF1080A103C102C40F364850133A049EE -:100440001032072BCAE90015CDE92532F0DD24AAC8 -:100450003146584602F0D0FA00287ED1DDE9253237 -:100460000DF19C0AE6E7069B02995D1A002D7FF7C5 -:100470008EAD102D259B21DD099410261BEE104A10 -:1004800004E0103D102D0AF1080A16DD01338C49F5 -:100490001032072BCAE90016CDE92532F1DD24AA76 -:1004A000214658460DF19C0A02F0A6FA002854D1C4 -:1004B000103D102DDDE92532E8DC099C8049CAF8A1 -:1004C000045001332A44072BCDE92532CAF8001025 -:1004D00000F32685039B05995D1A002D0AF1080A91 -:1004E0007FF75BAD102D259B1FDD514610261BEEBF -:1004F00010AA04E0103D102D01F1080114DD0133B4 -:100500006F481032072BC1E90006CDE92532F1DD35 -:1005100024AA5146584602F06FFAF0B9103D102D4A -:10052000DDE9253227A9EADC8A4601336449CAF8A5 -:1005300004502A44072BCDE92532CAF8001000F3F5 -:10054000DA810AF1080A28E51BEE101A24AA584697 -:1005500002F052FA00283FF447AD079B002B3FF40E -:10056000A2AC07995846FEF7ADFE9CE40E9B012B0A -:1005700040F37A81259BCAF8004001330132012102 -:10058000072B26922593CAF8041000F3F8810AF18C -:10059000080A1099129801330A44072BCAE900018E -:1005A000CDE9253200F3DD810AF1080AB5EE408B72 -:1005B000F1EE10FA00F077810E9901330139013420 -:1005C0000A44072BCAF800402593CAF80410269263 -:1005D00000F35B810AF1080A1499CAF80410013388 -:1005E0000A44072B1EA9CDE92532CAF800107FF76F -:1005F000E5AC1BEE101A24AA584602F0FDF90028BB -:10060000ABD1269A0DF19C0ADAE4102DDDE9251212 -:100610002C4E24DD179410231BEE104A084604E0EC -:10062000103D102D0AF1080A17DD0130103207289D -:10063000CAE90063CDE92502F2DD24AA2146584625 -:100640000DF19C0A02F0D8F9002886D1103D102D3A -:10065000DDE925024FF01003E7DC179C014601316C -:100660002A440729CDE92512CAF80060CAF80450C7 -:1006700000F3BD839DF867100AF1080A5DE4CDF828 -:1006800008800A2A71F1000380F04583303201238B -:10069000DDF808808DF83F2105930DF23F1468E6E0 -:1006A0001BEE101A24AA584602F0A6F900287FF47F -:1006B00054AF269A0DF19C0A52E400BFC00B0020F3 -:1006C000880F0020C40B00201BEE101A24AA5846E5 -:1006D00002F092F900287FF440AF269A0DF19C0AAF -:1006E00051E4102C259BBE4E1FDD1BEE108A1025F9 -:1006F00004E0103C102C0AF1080A16DD0133103218 -:10070000072BCAE90065CDE92532F2DD24AA41466E -:1007100058460DF19C0A02F06FF900287FF41DAFD6 -:10072000103C102CDDE92532E8DC01332244072B94 -:10073000CAE90064CDE925327FF74BAC1BEE101AF5 -:1007400024AA584602F058F900287FF406AF269AEA -:100750003FE41B99002940F35A830C9E0E9B9E4256 -:10076000A8BF1E46002E0BDD259B01333244072B0C -:10077000CAE900462692259300F389860AF1080A01 -:100780000C9D002EA8BFAD1B002D00F303820C9B17 -:1007900018F4806F2344059340F01F821B9B0E9931 -:1007A0008B4203DB18F0010F00F0CF8410991298F0 -:1007B0000A44CAE9000125992692013107292591A9 -:1007C00000F3A5860AF1080A0E996518CC1A059B54 -:1007D000ED1AA542A8BF2546002D0DDDCAF8003050 -:1007E000259BCAF8045001332A44072B26922593EF -:1007F00000F3BB860AF1080A002DA8BF641B002C79 -:100800007FF7DEAB102C259B40F37C831BEE106A38 -:10081000102505E00AF1080A103C102C40F3728301 -:10082000013370491032072BCAE90015CDE9253292 -:10083000F0DD24AA3146584602F0DEF800287FF4A5 -:100840008CAEDDE925320DF19C0AE5E7302B3FF453 -:100850008BAD3023023804F8013C50AB1B1ADDF895 -:1008600008800593044684E518F0010F7FF482AEFA -:10087000259BCAF80040013301320121072B269243 -:100880002593CAF804107FF7A5AE1BEE101A24AA10 -:10089000584602F0B1F800287FF45FAEDDE925325A -:1008A0000DF19C0A98E60E994C1E002C7FF794AE31 -:1008B000102C40F361831BEE106A102505E00AF14D -:1008C000080A103C102C40F357830133454910327D -:1008D000072BCAE90015CDE92532F0DD24AA3146FF -:1008E000584602F089F800287FF437AEDDE925325A -:1008F0000DF19C0AE5E71BEE101A24AA584602F0F7 -:100900007BF800287FF429AE269A0DF19C0AFFF7A8 -:1009100044BB029B13F0100340F0C180029A12F016 -:10092000400200F07A83089850F8042B089019468A -:1009300092B2012351E418F0100355D118F040028F -:1009400000F05D83089850F8042B0890194692B285 -:10095000A8E4524261EB4101CDF808802D2001232B -:100960003CE41BEE101A24AA584602F045F8002871 -:100970007FF4F3ADDDE925320DF19C0A16E61BEE9E -:10098000101A24AA584602F037F800287FF4E5AD83 -:10099000DDE925320DF19C0AFBE518F0010F3FF46B -:1009A0000FAB2AE5089399F80030FFF7CDB950ACAA -:1009B000DFE418F4007F40F0DB8353F8042B089346 -:1009C000D1170B46FFF7B6BB089B049853F8041BDE -:1009D0000893C217C1E900024C46FFF78BB900BF6C -:1009E000C40B0020880F0020089B53F8042B0893A9 -:1009F00058E4B4EE488BF1EE10FA80F194860B9B2C -:100A0000612B00F05285412B00F0C085039B013320 -:100A10000B9B23F0200500F08084472D04D1039B1D -:100A2000002B08BF0123039318EE903A002B48F4E3 -:100A300080724646C0F21886B0EE48AB002390465E -:100A4000099307930B9B413B252B00F29883DFE82A -:100A500013F06F0496039603960368046C049603E0 -:100A600096039603960396039603960396039603BE -:100A700096039603960396039603960396039603AE -:100A8000960396039603960396039603960396039E -:100A90009603960396039603960368046C04089BDA -:100AA00053F8042B08930123FFF797BB139B002BEC -:100AB0003FF4CFA9139B1B78002B3FF4CAA999F8E8 -:100AC000003048F48068FFF73FB90B93CDF80880F9 -:100AD000FFF7F1BB0B939A4B119318F0200100F034 -:100AE0000581089B073323F00703596853F8082B47 -:100AF000089318F0010F0AD052EA010307D00B9BAC -:100B00008DF86930302348F002088DF8683028F4F9 -:100B1000806302930223FFF760BB0B93FFF7B6BB22 -:100B20000B93884B1193D8E7089B012153F8042BB2 -:100B300002918DF8DC200893059137ACFFF7AFBA2E -:100B40001BEE101A24AA584601F056FF00287FF425 -:100B500004AD269A0DF19C0A5DE4039B0794062BD5 -:100B6000224628BF062303942146CDE90C22764C69 -:100B7000029305930F92FFF76CBA40215846FDF798 -:100B8000F3F920602061002800F00F8640236361A4 -:100B9000FFF79EB8102D259B40F35D82514610262D -:100BA0001BEE10AA04E00831103D102D40F35282D4 -:100BB000013366481032072BC1E90006CDE9253222 -:100BC000F1DD24AA5146584601F016FF00287FF4B3 -:100BD000C4ACDDE9253227A9E6E70E9BCDF82490C9 -:100BE000E31803930D9BCDF82880139E059DDDF837 -:100BF0005890DDF83C800B941BEE101A5046002BE9 -:100C000034D0B8F1000F35D10D9B013B013E0D935F -:100C1000159BC0E90039259B01334A44072B2692D6 -:100C200025936CDC0830039B96F800C05B1B634582 -:100C3000A8BF6346002B9A460CDD259C01341A445C -:100C4000072CC0E900532692259400F3778196F88B -:100C500000C00830BAF1000FACBFACEB0A04644628 -:100C6000002C0ADC65440D9B002BCAD1B8F1000FA3 -:100C700000F0AC8308F1FF38CAE7102CDDF894C00F -:100C800024DD05954FF0100A63460D4604E0103C44 -:100C9000102C00F1080016DD01332C491032072B0F -:100CA000C0E9001ACDE92532F1DD24AA29465846CB -:100CB00001F0A2FE00287FF450AC103C102CDDE9BE -:100CC000253227A8E8DC2946059D9C460CF1010346 -:100CD00022444460072B1D4C0460CDE9253200F30B -:100CE000C68396F800C008306544BCE718F01003CE -:100CF00000F0C280089B53F8042B0893F9E624AA5D -:100D00005846059101F078FE00287FF426AC269A1B -:100D1000059927A887E70298CDF81CA050AC00F4ED -:100D2000806000250AEE10BA094BDDF84CA0CDF822 -:100D30001490A3464FF00508AC46044610E000BFEF -:100D4000900B0020A40B0020B80B0020880F00207F -:100D5000CDCCCCCC0A2A71F1000136D34A463146BB -:100D6000501840F10000A3FB005626F0030505EBE8 -:100D70009605401B151A4FF0CC3661F1000E06FBAC -:100D800005F6A5FB039503FB0E6609F0010E2E4444 -:100D9000AEFB085E2D184FEA590930350BF8015C9F -:100DA00049EAC6790CF1010C0BF1FF3B7608002CE7 -:100DB000D0D09AF800008445CCD1BCF1FF0FC9D047 -:100DC0000A2A71F1000180F08F815C4650AB1B1B39 -:100DD000DDF81490CDF84CA01AEE10BADDF81CA086 -:100DE000DDF80880CDF838C00593FFF7C2BA1BEED6 -:100DF000101A24AA584601F0FFFD00287FF4ADAB7D -:100E00009DF86710269A0DF19C0AFFF796B8259B6E -:100E1000BE48CAF80000013301320120072B269298 -:100E20002593CAF8040000F377810AF1080A002923 -:100E300040F0AF800E9908F001030B433FF4C0A8C7 -:100E4000109B12991A44CAE90013259B269201337C -:100E5000072B259300F352820AF1080A0E99CAF86B -:100E6000004001330A44072BCDE92532CAF80410AB -:100E70007FF7A4A8FFF7BDBB18F0400200F0DD80AB -:100E8000089850F8042B0890194692B231E61BEEF0 -:100E9000101A24AA584601F0AFFD00287FF45DAB7C -:100EA000269A0DF19C0AFFF7A3BA22AE0822002170 -:100EB00030461D94FDF742FF039B5A1C00F0DB8077 -:100EC0000025CDF80890CDF81C809946A8460CE086 -:100ED00037A9584601F04AFD431C404400F0C8833E -:100EE000484508DC00F0188480461D9A5259334664 -:100EF0000435002AECD1CDF81480DDF80890DDF837 -:100F00001C80C5E001338249CAF804402244072B03 -:100F1000CAF80010CDE925327FF750A8FFF769BB6A -:100F20001BEE101A24AA584601F066FD00287FF433 -:100F300014AB269A0DF19C0AFFF729B824AA58464B -:100F4000059101F059FD00287FF407AB96F800C029 -:100F5000269A059927A87DE6012BCDF808807FF415 -:100F6000F3A9FFF793BB089B049953F8042B4C4655 -:100F700011600893FEF7BEBE01336549CAF804400C -:100F80002244072BCDE92532CAF800107FF722ABA7 -:100F90007BE4109B12981A44CAE90003259B269211 -:100FA0000133072B259300F3A9810AF1080A0029D0 -:100FB000BFF654AF4D42103180F20F831BEE101A72 -:100FC000102605E00AF1080A103D102D40F30583B4 -:100FD00001334F481032072BCAE90006CDE925320C -:100FE000F0DD24AA5846039101F006FD00287FF4A5 -:100FF000B4AADDE9253203990DF19C0AE4E7089BC8 -:1010000018F400711ABF114653F8042B53F8042B3F -:10101000089318BFD2B2FFF745B9029B13F40071D1 -:10102000089B1ABF114653F8042B53F8042B08935E -:1010300018BFD2B20123FFF7D0B8089B18F4007193 -:101040001ABF114653F8042B53F8042B089318BF0A -:10105000D2B24EE58A4601332D49CAF804502A44DB -:10106000072BCDE92532CAF8001000F339810AF1C7 -:10107000080AFFF78CBB0023194600961DAA5846A4 -:1010800001F09AFC03460133059000F0F1821D94B3 -:10109000059B002B4ED0632B00F318810023079390 -:1010A00037AC082200213046FDF748FE059D00962A -:1010B0002B461DAA2146584601F07EFC854240F091 -:1010C0007C83059A0023A35422EAE272CDE90C3313 -:1010D0009DF86710039302920F93FEF7BABF2D217C -:1010E0008DF86710FEF7A4BF169B1599ABEB030BA9 -:1010F0001A465846FDF7BAFE9AF80120054B0AB188 -:101100000AF1010A4FF0000C28E600BFC00B0020D6 -:10111000880F0020CDCCCCCC1BEE101A24AA584648 -:1011200001F06AFC00287FF418AA1B99269A0DF199 -:101130009C0A7CE6059B9DF867100F93CDE902336E -:10114000CDE90C330793FEF784BF0E990598651817 -:101150002D1ACC1AA542A8BF2546FFF74DBB089B08 -:10116000049953F8042B089311804C46FEF7C2BD36 -:1011700013F9042B0893D1170B46FEF7DBBF039A34 -:10118000022122AB01931DAB009358461BABB0EE7E -:101190004A0B029200F074FD472D029A044600F0BB -:1011A0006181462D104405D12378302B00F06F82E9 -:1011B0001B9A1044B5EE40ABF1EE10FA40F04681B8 -:1011C00003461B1B0E93472D00F01081462D00F0A7 -:1011D000B5811B9B0C930C9B412D03F1FF331B939B -:1011E00000F0E5819DF82C200021002BB8BF0C9B5E -:1011F0008DF87820BABFC3F101032D222B22092BD1 -:101200008DF8792040F3DA810DF18F05DFF81CC4E9 -:101210002A4610468CFB0321DA17C2EBA10202EB2F -:101220008201A3EB4101303100F8011C194663290A -:10123000134600F1FF32ECDC3033D9B2831E9D42FD -:1012400002F8011C40F28B8213460DF17A0201E094 -:1012500013F8011B02F8011B9D42F9D10DF1910316 -:101260000DF17A021B1A13441EAA9B1A14930E9BAB -:10127000149A012B1A44059240F30382059B109A9D -:101280001344059326F48063059A43F48078002381 -:10129000CDE90C3322EAE2720F930292099B002BF4 -:1012A00040F0B1809DF867100393FEF7D2BE204650 -:1012B000FDF706FF02460590FEF720BF1BEE101A51 -:1012C00024AA584601F098FBFEF7EDBD591C58467C -:1012D000FCF74AFE0446002800F0CA810790E0E6C9 -:1012E0001BEE101A24AA584601F086FB00287FF452 -:1012F00034A9269A0DF19C0AFFF749BA1BEE101A81 -:1013000024AA584601F078FB00287FF426A9DDE9DD -:1013100025321B990DF19C0A49E606230393FFF73A -:1013200083BB039B02215A1C2BE7039A032128E766 -:101330001BA8B0EE4A0B00F077FBB4EE007B20EE6A -:10134000070BB5EE400BF1EE10FA01D101231B9310 -:10135000B348039BB3EE005B013B224604E0B5EECD -:10136000400BF1EE10FA13D020EE050BFDEEC07B22 -:10137000B3F1FF3F17EE901A415CB8EEE76B94466D -:1013800030EE460B02F8011B194603F1FF33E6D19C -:10139000B6EE006BB4EEC60BF1EE10FA00F3488126 -:1013A000B4EE460BF1EE10FA04D117EE903ADB07DB -:1013B00000F13E81002906DB4B1C1344302102F86A -:1013C000011B9342FBD1131B0E93FCE60B9C0E9B5F -:1013D000DDF82490DDF828801396E3189D42294615 -:1013E00028BF194682460591FFF7D8B91B9B0C937D -:1013F000DA1C02DB039A93420CDD0B9B023B0B933E -:1014000023F02005E7E62D2100238DF867100393D4 -:10141000FEF722BE0C9B0E9A9342C0F2BD80F007ED -:101420000C9B40F13281109A13440593710503D54A -:101430000C9B002B00F33581059B23EAE373029399 -:1014400067230B9300230F930D9327E7229B83427F -:10145000BFF4B7AE30215A1C22921970229B9842D9 -:10146000F9D8AEE6F30700F1A780229BA9E624AAEB -:101470005846059101F0C0FA00287FF46EA896F84E -:1014800000C0269A059927A86544FFF7ECBB1BEE20 -:10149000101A24AA584601F0AFFA00287FF45DA87C -:1014A000269A0DF19C0AFFF76BB978238DF8693005 -:1014B00030238DF86830039B632B48F0020600F35D -:1014C000A6800023079337AC18EE903A002B48F41F -:1014D00081782BDBB0EE48AB0B9B23F0200500237B -:1014E00009930B9B612B7FF4ADAAB0EE4A0B1BA8AE -:1014F00000F09AFAB4EE007B20EE070BB5EE400B3D -:10150000F1EE10FA01D101231B93464821E71BEEAF -:10151000101A24AA584601F06FFA00287FF41DA87B -:101520001B9B269A0DF19C0AFFF74EB90B9B23F0EB -:1015300020052D230993B1EE48ABD2E71B9A0C92FC -:10154000002A06F0010340F30D8103990B4340F09C -:10155000CF800C9B059366230B93720500F1A3804B -:10156000059B23EAE37302936CE71BEE101A24AA8F -:10157000584601F041FA00287EF4EFAF1B9C0E9B09 -:10158000269A1C1B0DF19C0AFFF736B958238DE7EC -:1015900000220392FEF7DABB0E9B109A9A180C9B5E -:1015A0000592002B40F3AB8067230B93D5E70B9A92 -:1015B0000F32D2B2012118E6A018FBE5002940F055 -:1015C000A88030228DF87A200DF17B02303302F8AA -:1015D000013B1EABD31A149349E601331249CAF8F2 -:1015E00004502A44072BCDE92532CAF800107FF7B2 -:1015F00033AC1BEE101A24AA584601F0FDF900285E -:101600007EF4ABAFDDE925320DF19C0A26E4591CCE -:101610005846FCF7A9FC044650B3079054E700BFB6 -:10162000A40B0020900B0020880F002067666666E0 -:10163000CDF888C012F8011C90F80FC06145134620 -:101640000AD14FF0300E03F801EC229B591E229173 -:1016500013F8011C8C45F6D0392916BF0131817A67 -:10166000C9B203F8011CAEE600239046079360E779 -:101670001BEE102AB2F90C3043F040039381FEF7C1 -:1016800016BCF5077FF5FEADF8E50593CEE6B5EEA1 -:1016900040ABF1EE10FA3FF48BADC2F101021B92A8 -:1016A00087E567230B9313990B78FF2B79D00025DF -:1016B0000C9A284603E001300131FF2B08D09342F9 -:1016C00006DAD21A4B78002BF5D10B780135F4E706 -:1016D0000C9213910D900F950F9A0D9B1699134430 -:1016E000059A01FB0323059323EAE3730293D5E5EF -:1016F000109BD3181944662305910B932DE7C3F172 -:1017000001031A4422EAE2730293672305920B93C2 -:1017100098E60DF17A0259E7039BDDF80890DDF8B1 -:101720001C800593B4E418EE903A002BB4BF2D2131 -:101730009DF86710254C264BB8BF8DF8671028F030 -:101740008008FEF779BC039B0293059373239DF8F1 -:10175000671003900F900D900B93FEF77ABC022355 -:10176000149384E5039A134305D10123662202935F -:101770000B92059366E6109B01331A4422EAE2734A -:101780000293662305920B935CE6089A99F8013060 -:10179000894652F8041B089241EAE1710391FEF771 -:1017A000D3BA00230F930D9396E70C23CBF80030A8 -:1017B0004FF0FF330493FEF781BB1BEE102A938991 -:1017C00043F040039381FEF7C8BE00BF880B0020A2 -:1017D0008C0B002070B500294BD006460C4610B18A -:1017E000436B002B48D0636ED80734D5B4F90C3066 -:1017F000002B3ED02146304600F050F8E36A054603 -:1018000033B1E169304698470028B8BF4FF0FF3543 -:10181000A3891A063CD4216B41B104F140039942DB -:1018200002D03046FDF74EFD00232363616C21B1E9 -:101830003046FDF747FD00236364FDF7F7F8636E5C -:101840000022DB07A2811FD5A06DFDF7D9FBFDF7B4 -:10185000F3F8284670BDA3899905CBD4A06DFDF798 -:10186000D1FBB4F90C30002BC4D1656E15F0010525 -:1018700005D00025284670BDFDF7BAF8B3E7A06D86 -:10188000FDF7C2FB284670BDA06DFDF7BDFBDBE791 -:1018900021693046FDF716FDBDE700BFB1F90C2008 -:1018A0002DE9F0410C461107804647D4636842F4A5 -:1018B0000062002BA2815EDDA56A002D58D00023B6 -:1018C000D8F80060C8F8003093B212F4805256D1B4 -:1018D0000123E1694046A847431C67D0A389A56A54 -:1018E0005F0705D56368C01A236B0BB1E36BC01AA1 -:1018F000E169024600234046A847411C41D1D8F87F -:101900000030002B3DD01D2B01D0162B56D1A389C2 -:101910002269226023F4006300216160A381216BAE -:10192000C8F8006021B304F14003994202D0404658 -:10193000FDF7C8FC00202063BDE8F0812669BEB138 -:1019400093B2256826609A070CBF63690023AD1B1C -:10195000A3600BE02B463246E169676A4046B84710 -:10196000B0F1000CA5EB0C05664417DD002DF1DC91 -:101970000020BDE8F081E36B002B9DDCF8E7206DD3 -:10198000AEE7B4F90C302269226023F40063A3812E -:101990000022DB046260C2D52065C0E7A38943F062 -:1019A00040034FF0FF30A381BDE8F081D8F800304C -:1019B000002B93D01D2B06D0162B04D0A38943F007 -:1019C0004003A381D5E7C8F80060D1E738B50C46DD -:1019D000054608B1436B03B3B4F90C0088B1636EDC -:1019E000DB0701D481050FD528462146FFF756FFB6 -:1019F000636EDA07054602D4A3899B0508D52846FD -:101A000038BD0546284638BDA06DFDF7FBFAEBE76B -:101A1000A06DFDF7F9FA284638BDFCF7E9FFDBE7D2 -:101A200000487047F015002030B482B08DED000BF7 -:101A3000019A194C22F000430021A342016021DCED -:101A4000009C1C431ED0154C144054B99FED107BD4 -:101A500020EE077B8DED007B019A6FF0350122F0BF -:101A6000004322F0FF42DDE9004522F4E00242F0AB -:101A70007F551B1545F40015A3F2FE33CDE9004553 -:101A80000B4403609DED000B02B030BC704700BFFB -:101A90000000000000005043FFFFEF7F0000F07FD8 -:101AA00000B50B4C25681446EE681A4685B003460F -:101AB0000D464CB107490095CDE901143046064961 -:101AC00000F086FFFBF73AF904490C46F3E700BF44 -:101AD000881A002060090020700900209C05002061 -:101AE00038B5A1FB02148CBBFCF73EFA0546E0B109 -:101AF00050F8042C22F00302043A242A17D8132A9F -:101B00001AD91B2AC0E900441DD9242A14BF00F1A8 -:101B1000100200F118024FF00003C0E9024404BFB4 -:101B200004614461C2E900339360284638BD214610 -:101B3000FDF704F9284638BD02460023C2E9003308 -:101B40009360284638BD00F10802F6E7FDF72CFA4D -:101B50000C2300250360E8E72DE9F04F03690C69C9 -:101B6000A34283B0C0F28780013C01F11405A300B9 -:101B700000F11408009355F8243058F8242001335C -:101B800081469A4208EB840005EB84070190B2FB82 -:101B9000F3F63BD34FF0000CAE464046E2466346B8 -:101BA0005EF804BB02681FFA8BFC06FB0C334FEA9D -:101BB000134C4FEA1B4B06FB0BCC9BB2AAEB030367 -:101BC0001FFA8CFA13FA82F3CAEB124202EB234299 -:101BD0009BB243EA0243774540F8043B4FEA224A6E -:101BE0004FEA1C43DCD2009B58F8033073B9019BC9 -:101BF000043B984504D307E0984504F1FF3403D231 -:101C000053F80429002AF7D0C9F810404846FDF7D8 -:101C1000FBFE00282BDB01364146002355F8040B60 -:101C2000D1F800C082B29A1A030C12FA8CF2C3EBFC -:101C30001C4303EB224392B242EA0342AF4241F813 -:101C4000042B4FEA2343E9D258F8242008EB8403FD -:101C50006AB9043B984504D307E0984504F1FF3482 -:101C600003D253F80429002AF7D0C9F810403046AF -:101C700003B0BDE8F08F002003B0BDE8F08F00BFD7 -:101C80002DE9F04F2DED028B8FB08DED020B019100 -:101C9000816B1A9D059357EC106B0446934641B136 -:101CA000C26B4A60012393408B60FDF74DFC00231B -:101CB000A363B7F10008B4BF012300232B60BE4B20 -:101CC000BCBF28F00048CDF80C8033EA080300F0D0 -:101CD0009F809DED028BB5EE408BF1EE10FA11D195 -:101CE000059A012313601B9B002B00F03F82B34B2E -:101CF0001B9A1360013B009300980FB0BDEC028B60 -:101D0000BDE8F08F0CAA0DA92046B0EE480BFDF7F8 -:101D100047FF5FEA1853054640F09280DDE90C1357 -:101D20000B4403F23242202A40F3FA82C2F140020D -:101D300008FA02F803F21242D64048EA060207EE19 -:101D4000102AB8EE477B581E17EE906A53EC172BFB -:101D50004FF0010AA6F1F8739FED913B9FED927B46 -:101D60009FED935B06EE900A43EC122BB8EEE64B28 -:101D7000B7EE086B32EE466BA6EE037BA4EE057B56 -:101D8000FDEEC76BB5EEC07BF1EE10FA16EE907A61 -:101D900008D5B8EEE66BB4EE476BF1EE10FA18BF5B -:101DA00007F1FF37162F00F24581854B03EBC70380 -:101DB00093ED007BB4EEC78BF1EE10FA57D5091AFC -:101DC0000023B1F1010807F1FF370A9300F13981CF -:101DD00000230693002F52DA069B0497DB1B069321 -:101DE0007B420893019B092B4FF000074ED8052B2F -:101DF00040F39D82043B01930026019B9A1E032A17 -:101E000000F22581DFE812F0AA03A7039D037E03F9 -:101E1000059AC8F3130842F20F7358EA06081360D4 -:101E20001ED11B9B002B00F09185664B009308335D -:101E30001B9A009813600FB0BDEC028BBDE8F08FC9 -:101E400018EE906AC6F31306A3F2FF3053EC182B7A -:101E500046F07F530C994FF0000A43F440137BE7A0 -:101E60001B9B002B40F03B83574B009344E7091A20 -:101E70000023B1F101080A9300F1E38006930023E7 -:101E80000893019B0497092BB844B0D9002301267D -:101E9000019307964FF0FF399B460021E163CDF88F -:101EA0002C902046FDF72AFB0090002800F040858A -:101EB000009BA363B9F10E0F00F2DC80002E00F04E -:101EC000D980049B002B40F3DE833D4A03F00F01D1 -:101ED00002EBC10292ED007B1A11DB0540F1828317 -:101EE0003A4991ED086B02F00F02032088EE065B81 -:101EF0005AB13649D60704D591ED006B013027EE73 -:101F0000067B521001F10801F4D185EE076B0A9BA4 -:101F10003BB1B7EE007BB4EEC76BF1EE10FA00F107 -:101F2000AE8407EE900AB8EEE75BB1EE0C7BA5EE4F -:101F3000067B17EE902A51EC170BA2F15071B9F104 -:101F4000000F00F08883049E4A46079B002B00F098 -:101F50004784B6EE003B1A4BFDEEC64B03EBC20CBA -:101F6000B8EEE47B36EE477B1CED026B83EE065B3E -:101F700041EC160B14EE900A35EE465B0099B4EE78 -:101F8000C75B3030F1EE10FA01F8010B00F3AC84BE -:101F9000B7EE002BB2EE044B4FF0000C31E000BF67 -:101FA00061436F63A787D23FB3C8608B288AC63F5F -:101FB000FB799F501344D33F0000F07FC10B0020FA -:101FC000A8020020140B0020200B0020800200201B -:101FD0000CF1010C94454DDA27EE047B25EE045BF1 -:101FE000FDEEC76B16EE903AB8EEE63B303337EEB7 -:101FF000437BB4EEC57BF1EE10FA01F8013B00F132 -:10200000738432EE476BB4EEC56BF1EE10FADFD598 -:10201000009A049602E08A4200F05084894611F842 -:10202000013D392BF7D00133DBB20B70049B013338 -:10203000049355E1091A0123B1F101080A937FF5D0 -:10204000C7AEC1F1010306934FF00008C2E60026B7 -:10205000E66331462046FDF751FA0090002800F073 -:102060006784009BA3634FF0FF330B9399460123D2 -:10207000B34607930D9A002A55DB04990E2952DCCA -:10208000B74BBBF1000F03EBC10393ED006B15DA07 -:10209000B9F1000F12DC40F0F282B1EE047B26EEC3 -:1020A000077BB4EEC78BF1EE10FACA464E4600F23B -:1020B0006D82DDF800806FEA0B0B70E288EE067B24 -:1020C000BDEEC77B009917EE103AB9F1010F03F18D -:1020D0003003B8EEC75B01F8013BA5EE468B00F07C -:1020E0003483B2EE044B012311E088EE067BBDEE93 -:1020F000C77B013317EE102A4B4502F13002B8EED0 -:10210000C75B01F8012BA5EE468B00F01E8328EE7D -:10211000048BB5EE408BF1EE10FAE6D1049B01334F -:1021200004938946DCE0079B43B3019B012B40F3FA -:102130007682089B09F1FF3A534580F23F82089B63 -:10214000CDF820A0AAEB030217444FF0000AB9F122 -:10215000000FC0F22583069B09934B44C8440693A5 -:1021600001212046FDF79CFA06460CE07D4B0093CA -:1021700000980FB0BDEC028BBDE8F08F069BDDF838 -:1021800020A0079E0993099B6BB1B8F1000F0ADDEF -:10219000434506991A46A8BF4246891A9B1A0691DA -:1021A0000993A8EB0208089B63B1079B002B00F082 -:1021B000A782BAF1000F00F30482089BB3EB0A0276 -:1021C00040F0FF8201212046FDF76AFA002F824687 -:1021D00000F3AF80019B012B40F38781002308931C -:1021E0000120002F40F0B180404410F01F0000F0AB -:1021F0007A81C0F12002042A00F3888040F0F68141 -:10220000069B002B05DD29461A462046FDF784FB78 -:102210000546B8F1000F05DD514642462046FDF760 -:102220007BFB82460A9B002B40F03F81B9F1000FF7 -:1022300040F32581079B002B40F0A380049B0133D2 -:102240000493DDF80080012707E0294600230A22D5 -:102250002046FDF783F90137054651462846FFF72A -:102260007BFCB94500F1300008F8010BEDDCB9F159 -:10227000000F009ACCBFCB464FF0010B03469344AE -:1022800000272946012220460193FDF745FB5146D0 -:102290000546FDF7B9FB002840F3AF811BF8013C70 -:1022A000009A0BF1FF3B04E05A4500F0B1811BF8A6 -:1022B000013D392B0BF10109F6D001338BF80030C9 -:1022C00051462046FDF740F956B12FB1B74203D031 -:1022D00039462046FDF738F931462046FDF734F9F6 -:1022E00029462046FDF730F9002389F80030DDE962 -:1022F00004231A601B9B002B3FF4FEAC0098C3F82C -:1023000000900FB0BDEC028BBDE8F08FC0F11C0057 -:10231000069B03440693099B0344099380446FE79B -:10232000C2F1200206FA02F207EE102A09E50126A0 -:1023300063E501463A462046FDF78EFA019B012BE4 -:10234000824640F3C58100230893DAF810200AEB97 -:1023500082021069FDF754F9C0F1200044E700BF84 -:10236000A8020020C00B0020314600230A2220468C -:10237000FDF7F4F80B9B002B064640F3CE82049742 -:102380009946099B002B05DD31461A462046FDF78C -:10239000C3FA0646089B002B40F0EB81B046029B37 -:1023A000009F03F001027B1E4B440893019B0A929D -:1023B0001343099351462846FFF7CEFB3146834627 -:1023C0002846FDF721FB4246514681462046FDF74F -:1023D0003DFBC26801460BF13003002A42D1CDE932 -:1023E00006032846FDF710FB069902902046FDF7EC -:1023F000ABF8029A079B1AB90999002900F07E826E -:10240000B9F1000FC0F28381019949EA01090A99E3 -:1024100051EA090900F07B81002A00F3C681089A7D -:102420003B7007F101099742CB4600F0C481294671 -:1024300000230A222046FDF791F84645054631461D -:102440004FF000034FF00A02204612D0FDF786F845 -:102450004146064600230A222046FDF77FF84F46F4 -:102460008046A7E720460293FDF76EF8029B012203 -:10247000C6E7FDF773F84F46064680469AE7019B8C -:10248000022B71DC079B002B7FF47BAF049B514632 -:10249000013328460493FFF75FFBDDF800B000F13D -:1024A00030030BF8013B0027EBE651462846FDF7C9 -:1024B000ABFA0028BFF6BAAE294600230A2220460E -:1024C000FDF74CF8049B5F1E079B0546002B7FF42D -:1024D0004BAF0B9B002B40F318829946B1E6BC4BE7 -:1024E00000930333A4E41C2012E7DDE90201002875 -:1024F0007FF474AEC1F31302002A00F0F480029B53 -:1025000008936DE601230793049B5B4403F10109E3 -:10251000B9F1010FCC460B93B8BF4FF0010C00216D -:10252000BCF1170FE1637FF7BCAC0120042252001D -:1025300002F114036345014600F10100F7D9E1639C -:10254000AFE401230793BBF1000F52DDCDF82CB0AF -:10255000D946DC46E3E700230793D5E7002307933A -:10256000F1E7DDF82C900497B9F1000F7FF4A1ADED -:1025700051464B4605222046FCF7F0FF01468246B5 -:102580002846FDF741FA00287FF793AD049B03F13D -:10259000010B009B3122984603F8012B0093514612 -:1025A0002046FCF7D1FF0BF10103DDF80090049306 -:1025B000CDF80080002E7FF48FAE91E6A3EB0A0ADF -:1025C000C5E5314652462046FDF746F92A46014602 -:1025D00006462046FDF792F8294605462046FCF7B8 -:1025E000B3FFEAE50220B0EE485B81E4C0F13C00B5 -:1025F0008EE64FF0010BD9464FE403D1019BDB0778 -:102600003FF54CAED9461BF8013D302BFAD057E6CA -:10261000049B009A013304933123137050E6BAF1FE -:10262000000F00F0238102F23342069B099313440A -:10263000DDF820A00693904492E507EE900AB1EEF3 -:102640000C5BB8EEE77BA6EE075B15EE902A51EC2B -:10265000150BA2F1507141EC150BB1EE047B36EE77 -:10266000477BB4EEC57BF1EE10FA00F33781B1EE93 -:10267000455BB4EEC57BF1EE10FA7FF5FBAC4FF095 -:10268000000A564615E500F0F580049B51495A4270 -:1026900002F00F0001EBC00191ED006B121128EE6A -:1026A000066B00F04281B0EE467B4B4900260220CB -:1026B000D30705D591ED005B0130012627EE057BA0 -:1026C000521001F10801F3D1002E06FE076B1EE443 -:1026D000029B002B7FF437AEDDE90201C1F3130248 -:1026E000002A40F037813D4A0A40002A00F0FA8073 -:1026F000069B01330693012308F1010808936FE557 -:102700002946089A2046FDF7A7F805465AE5002A0B -:1027100012DD2946012220460193FDF7FDF85146BE -:102720000546FDF771F90028019B40F3E180392B44 -:1027300000F0CA800BF13103B94609F8013B049B54 -:102740000133374604934646BAE538EE088BB4EEBB -:10275000C68BF1EE10FA0ADCB4EE468BF1EE10FAFD -:102760007FF4DCAC17EE103AD8077FF5D7AC009AAF -:1027700054E471682046FCF7C1FE0746002800F0CB -:10278000DE80336902339A0006F10C010C30FAF74F -:1027900047F8394601222046FDF7BEF88046FEE59F -:1027A000069BA3EB09030993DAE4392B00F08C8034 -:1027B000B9460133C1E7049A0132374604924646CE -:1027C0005FE529462046FDF747F80546FAE400BFD5 -:1027D000200B0020A8020020800200200000F07FD3 -:1027E0005E4BFDEEC65B03EBC20C1CED023BB8EE8C -:1027F000E57B36EE477B41EC160B15EE901A23EE87 -:10280000063B00983031012A00F8011B00F083805C -:10281000B2EE044B009B991827EE047BFDEEC76BCC -:1028200016EE903A303300F8013B8142B8EEE65B99 -:1028300037EE457BF0D1B6EE006B33EE065BB4EEBF -:10284000C75BF1EE10FA3FF5E3AB36EE436BB4EE47 -:10285000C76BF1EE10FA7FF70DAC8946013919F814 -:10286000013C302BF9D0731C049339E50C9AC2F16A -:102870003602DAE60220B0EE486BFFF748BBB9F14A -:10288000000F3FF4DAAE0B9A002A7FF7F3ABB2EEFB -:10289000044B26EE046B013007EE900A049BB8EE61 -:1028A000E75BB1EE0C7BA6EE057B17EE90CA51EC10 -:1028B000170B5E1EACF15071FFF747BB049B013351 -:1028C00004933123FFF7B1BB049BBB460133049350 -:1028D000392337460BF8013B4646E1E44FF0000A46 -:1028E000564653E608927BE4731C04938946F7E44A -:1028F0007FF422AFDA077FF51FAF18E7392BE3D05B -:10290000B9F1000F3FF716AF16E7019B022B3FF717 -:1029100028AE0497BAE501468DE7019B022B3FF7ED -:1029200020AEDDF82C9004972BE50220FFF7EFBADC -:102930000B4B0C48002240F2AF11FFF7B1F8084BE7 -:1029400008483A4640F2EF21FFF7AAF8064B0093F9 -:10295000FFF7D2B9029B0893F7E400BFA80200205A -:10296000A0090020240B0020140B002070B50546A0 -:1029700084B05BB11C4669B10E4B2846D3F8E060C9 -:102980002346B047431C0FD004B070BD00F58274DD -:102990000029F1D1074A2346D2F8E06028460A46CA -:1029A00001A9B047431CEFD100228A2322602B608B -:1029B00004B070BD0015002010B582B0049CCDE9B4 -:1029C00000344FF0FF3301F0C7FB02B010BD00BF71 -:1029D0000EB410B583B005AB064C53F8042B01932D -:1029E0000146206800F0C4F803B0BDE8104003B011 -:1029F000704700BF881A00202DE9F04F93681768D0 -:102A000083B09246002B70D081468A6808680C46D5 -:102A1000083743E0A38913F4906F2ED0D4E904164D -:102A2000A0EB010806EB460606EBD67608F101009E -:102A300076102844B042324684BF064632465B05D3 -:102A400037D511464846FBF78FFA019000283AD057 -:102A500042462169F9F7E4FEA289019B22F49062C3 -:102A600042F08002A281A6EB080203EB0800666137 -:102A7000A260236120602E46A84642465946FCF7D4 -:102A8000E1F8DAF80830A2682068921B40445B1B2A -:102A9000A2602060CAF808303BB3083757E902B596 -:102AA000002DFAD0AA4216469046B3D92E46A84623 -:102AB000E3E74846FBF714FD03460028D3D121691C -:102AC0004846FCF7FFFBA3890C2243F04003C9F8FA -:102AD00000204FF0FF30A38100220023CAF8082015 -:102AE000CAF8043003B0BDE8F08F00200023CAF814 -:102AF000043003B0BDE8F08F2DE9F84F4B6E9C0415 -:102B000090462DD59368126843B38B46064602F172 -:102B1000080959E9025A5FEA9A0715D0043D0024D2 -:102B200001E0A7420ED055F8041F5A46304601F086 -:102B30005BFA431C04F10104F3D10023C8E901331B -:102B4000BDE8F88FD8F808302AF0030AA3EB0A038F -:102B5000C8F8083009F10809002BDAD10020ECE7A9 -:102B600001F00CF80023C8E90133BDE8F88F00BF7D -:102B70002DE9F04F2DED028BC5B00DF1500A8346C3 -:102B800008EE101A16460021082250461C460793EC -:102B9000FCF7D4F8BBF1000F04D0DBF83430002B85 -:102BA00000F0A08618EE102A536EDB0740F1138563 -:102BB000B2F90C108AB295040BD418EE103A41F415 -:102BC000005199815B6E8AB218EE101A23F40053FB -:102BD0004B66100740F1058118EE103A1B69002B77 -:102BE00000F0FF8002F01A030A2B00F00A81002394 -:102BF000CDE91933CDE90D331BAA0C9318929146F8 -:102C00000B930593B0464446A84BD3F8E450FCF729 -:102C10005FF92246034612A9CDF800A05846A847FE -:102C2000002800F04581C0F23981129A252A034616 -:102C300001D01C44E8E7B4EB0806054640F03C81AF -:102C4000002361788DF8433004F1010806934FF0BA -:102C5000FF371E462B2408F10108A1F120035A2B4F -:102C600000F27881DFE813F0B50276017601B00258 -:102C70007601760176016A00760176017D028D0289 -:102C8000760188029702760192025B005B005B008E -:102C90005B005B005B005B005B005B007601760124 -:102CA00076017601760176017601760176015C0285 -:102CB000840076017601760176017601760176014F -:102CC000760176017601E80076017601760133021D -:102CD0007601DA02760176018B05760176017601BE -:102CE00076017601760176017601760176015C0245 -:102CF0008600760176017601CD0286007F0076019E -:102D0000C0027601FD02EA00ED027F007601330287 -:102D10007C006905760176016B0576017C00A1F1E6 -:102D20003003002218F8011B02EB820203EB42027F -:102D3000A1F13003092BF5D906928EE75846FEF72C -:102D40006FFE43680D931846FCF7BAF90E900546DE -:102D50005846FEF765FE83680B93002D40F0D6843D -:102D600098F8001077E798F8001046F0200672E710 -:102D700046F01006B40640F18E81079B073323F01E -:102D800007031A46596852F8083B07920A46002979 -:102D9000C0F27084791C00F0A28526F080010391B6 -:102DA00053EA020100F03F840A2B72F1000180F027 -:102DB000418530338DF80F31039E012304930DF2CA -:102DC0000F14049BBB42B8BF3B46039300230893F8 -:102DD0009DF84330002B00F0CB80039B013303931D -:102DE000C6E018EE101A584618EE105A01F040F8D6 -:102DF000002840F05286AA8902F01A030A2B7FF4B9 -:102E0000F6AE18EE101AB1F90E30002BFFF6EFAE49 -:102E10004B6EDB0702D4970540F1128618EE101AAC -:102E200023463246584600F069FE0590059845B0A5 -:102E3000BDEC028BBDE8F08F46F0100616F02002C4 -:102E400000F03681079B073323F0070319465A68C1 -:102E500051F8083B079126F480610391002100207E -:102E60008DF84300781C00F01082039820F0800653 -:102E700053EA020040F00882002F40F03885002914 -:102E800040F0D583039B13F00103049300F01184F9 -:102E900030238DF80F310DF20F1492E70822002134 -:102EA0005046FBF74BFF01231C44ADE60015002004 -:102EB000B4EB080605461BD0199B1A9A013332441D -:102EC000072BC9E900861A9219931CDD002A00F02D -:102ED000A68318EE101A18AA5846FFF70DFE20BB5D -:102EE0000DF16C09059B33440593002D7FF4A8AECA -:102EF0001A9B002B40F0C18518EE103A0022B3F95E -:102F00000C30199215E009F10809EBE718EE101AD8 -:102F100018AA5846FFF7F0FD002800F0A680089B8D -:102F20001BB108995846FCF7CDF918EE103AB3F9E1 -:102F30000C3018EE102A526E12F0010F9AB200F007 -:102F4000A080500600F1B285059845B0BDEC028B1B -:102F5000BDE8F08F0029CBD000238DF8433001234A -:102F6000CDE903338DF8AC102BAC002308931F463A -:102F700016F00203099302D0039B0233039316F069 -:102F800084030A9305D1069B039A9D1A002D00F332 -:102F90007B82DDE91903411C9DF8432082B10122A7 -:102FA0000133C9F8042007290DF14302CDE91913B3 -:102FB000C9F8002000F34A82084609F108090131E6 -:102FC000099AE2B111AA0233C9F8002007294FF08B -:102FD0000202CDE91913C9F8042040F35082002BF6 -:102FE00000F0438318EE101A18AA5846FFF784FD24 -:102FF000002894D1DDE919030DF16C09411C0A9AEE -:10300000802A00F08481049ABD1A002D00F3D78134 -:10301000049AC9F8004013440729CDE91913C9F8E7 -:10302000042040F36E81002B00F0758218EE101A18 -:1030300018AA5846FFF760FD00287FF470AF1A9B6E -:103040000DF16C09750705D5069A0399541A002CE1 -:1030500000F36B82DDE9052103988142ACBF521871 -:1030600012180592002B7FF451AF08990023199391 -:10307000002900F049815846FCF724F90DF16C094C -:10308000C1E59C053FF55DAF18EE104AA06DFBF75A -:10309000BBFFA28955E7F006079A00F11F8371066E -:1030A00040F1198332F9043B0792DA1711466EE6B4 -:1030B00016F01003079940F0098316F0400000F065 -:1030C00001831A4651F8043B07919BB2C3E6079B64 -:1030D0001A4600238DF84330134653F8044B0393EC -:1030E000002C00F01284532900F0658316F01005BF -:1030F00040F061837B1C00F0B3843A4629462046A9 -:10310000FBF786FF0890002800F09F84031B039ABA -:10311000049323EAE3732F4607920393089557E637 -:10312000432902D0F50640F12D83079D0822002196 -:1031300016A82BACFBF702FE16AB55F8042B214664 -:103140005846FFF713FC03460133049000F0B384A4 -:10315000049B079523EAE373039300238DF8433020 -:1031600003E7079B53F8042B0692002A80F29C8207 -:10317000069A5242CDE9062398F8001046F004065C -:1031800069E598F800108DF8434064E598F8001060 -:1031900046F080065FE5424612F8011B2A2900F03E -:1031A0009684A1F13003092B90464FF000073FF6BB -:1031B00054AD18F8011B07EB870703EB4707A1F194 -:1031C0003003092BF5D948E598F8001046F00106C0 -:1031D00041E59DF84330002B7FF4C2AD202398F8E1 -:1031E00000108DF8433036E598F800106C2903BFC5 -:1031F00098F8011046F0200608F1010846F0100684 -:1032000029E598F80010682903BF98F8011046F4E2 -:10321000007608F1010846F040061CE546F0100370 -:103220000393039B13F0200200F00682079B0733F1 -:1032300023F0070319465A6851F8083B079101210A -:103240000DE6079A46F00203039352F8043B0792F7 -:1032500047F63002ADF84420B84A0C920221002211 -:10326000FDE5B70600F14882F50600F146837406D5 -:1032700000F1D583B00540F14083079B059953F8D1 -:10328000042B07931170BEE4039601293FF48CAD23 -:10329000022944AC11D10C9803F00F011B09415CC9 -:1032A00004F8011D43EA0273120953EA0201F3D143 -:1032B000039E44AB1B1B049383E503F00701DB086B -:1032C00043EA4273D208303153EA0205204604F83B -:1032D000011DF2D1039EF307EBD53029E8D030234E -:1032E000023804F8013C44AB1B1A039E04930446C5 -:1032F00067E5049B1B9401221C931A9319920DF10C -:103300006C0909F108099DE60DF16C097BE4069A48 -:10331000039D551B002D7FF776AE102D40F3BB8328 -:10332000099418EE104A07E000F1020C09F10809AF -:103330001046103D102D1EDD8149C9F80010421CB9 -:1033400010331021072ACDE91923C9F80410EBDD49 -:1033500018AA002B74D0214658460DF16C09FFF7CE -:10336000CBFB00287FF4DBADDDE91903103D102D08 -:1033700000F1010CE0DC099C714AC9F804502B44AF -:10338000BCF1070FCDE919C3C9F8002040F39481BF -:10339000002B00F01F8318EE101A18AA5846FFF7EA -:1033A000ABFB00287FF4BBAD049ADDE91903BD1A1D -:1033B000002D00F101010DF16C097FF729AE102DF0 -:1033C00029DD0994102718EE104A07E000F1020CDD -:1033D00009F108091046103D102D1ADD421C58490C -:1033E0001033072AC9E90017CDE91923EEDD18AA21 -:1033F00003B3214658460DF16C09FFF77DFB002809 -:103400007FF48DADDDE91903103D102D00F1010CA5 -:10341000E4DC099C61464A4AC9F804502B44072958 -:10342000CDE91913C9F8002000F3E78009F1080974 -:103430000131EDE54FF0010C18460DF16C09CAE7BA -:103440004FF0010C18460DF16C0972E7002B00F0EB -:10345000048118EE101A18AA5846FFF74DFB0028F1 -:103460007FF45DADDDE919030DF16C09411CA7E5A1 -:10347000022311AA1C931B9201210DF16C0908462D -:1034800009F10809411CBAE5102D40F3E582DDE998 -:1034900019130F94084618EE104A07E000F1020CC9 -:1034A00009F108091046103D102D1DDD2549C9F808 -:1034B0000010421C10331021072ACDE91923C9F846 -:1034C0000410EBDD18AA03B3214658460DF16C0930 -:1034D000FFF712FB00287FF422ADDDE91903103D50 -:1034E000102D00F1010CE1DC0F9C6046154AC9F873 -:1034F00004502B440728CDE91903C9F8002000F334 -:10350000C18009F10809411C46E518464FF0010C3D -:103510000DF16C09C7E77607199353D5069A0399FD -:10352000541A002C4EDD0DF16C09102C40F3B082C2 -:10353000199918EE106A10250DE000BF900B0020BD -:10354000980F0020D40B0020881C09F108091146AF -:10355000103C102C1ADD4A1CB3481033072AC9E965 -:103560000005CDE91923EFDD18AA33B331465846DB -:10357000FFF7C2FA00287FF4D2ACDDE91913103C42 -:10358000102C01F101000DF16C09E4DCA64AC9F828 -:10359000044023440728CDE91903C9F800207FF728 -:1035A00059AD7BB118EE101A18AA5846FFF7A4FAC5 -:1035B00000287FF4B4AC1A9B4CE5012019460DF1AC -:1035C0006C09C5E7DDE9053203998A42ACBF9B1857 -:1035D0005B18059349E5B2F90C108F0518EE103A07 -:1035E0008AB23FF5E8AA18EE105A986DFBF70AFD6B -:1035F000B5F90C108AB2FFF7DEBA002B3FF479AEB2 -:1036000018EE101A18AA5846FFF776FA00287FF429 -:1036100086AC19991A9B01310DF16C09F8E41992E5 -:103620000DF16C095EE4002F7FF4C3AB039E00270D -:10363000049744ACFFF7C5BB039B13F0100354D1B0 -:10364000039A12F0400000F06B8107991A4651F876 -:10365000043B07919BB2012101E4099A002A64D13D -:10366000184601210DF16C09C9E4012118460DF13C -:103670006C09C4E45B4262EB420203962D200121F7 -:10368000FFF7EEBB002B00F0888018EE101A18AA86 -:103690005846FFF731FA00287FF441ACDDE9190301 -:1036A0000DF16C09411C77E498F800100793FFF7BF -:1036B000D2BA44ACFFF785BB09F108090CF101014E -:1036C0006046A0E416F4007240F0978151F8043B84 -:1036D0000791FFF7C0BBB30500F1888152F8043BA6 -:1036E0000792DA171146FFF752BB079951F8043BCE -:1036F00007910121FFF7B3BB079B059853F8041B03 -:103700000793C217C1E90002FFF77DBA0B9B002B9C -:103710003FF426AB0B9B1B78002B3FF421AB98F8B2 -:10372000001046F48066FFF796BA022311AA1C9394 -:103730001B9201200DF16C09A2E6039671E53B4B4B -:103740000C9316F0200259D0079B073323F0070390 -:1037500018465A6850F8083B0790F40709D553EA11 -:10376000020006D08DF84510302146F002068DF893 -:10377000441026F4806103910221FFF770BB2C4BAB -:103780000C93DEE7079B012153F8042B03918DF87E -:10379000AC20079304912BACDFE49DF84320002A72 -:1037A00040F03281099A002A7FF462AE1846012166 -:1037B0000DF16C0927E40021082216A81394FBF7E9 -:1037C000BDFA791C00F0BC80002507942C460CE063 -:1037D0002BA95846FFF7CAF8421C204400F06B8121 -:1037E000B84208DC00F070810446139A525916ABB7 -:1037F0000435002AECD10494079CAFE016F01003C6 -:1038000007980CD116F0400405D01A4650F8043B36 -:1038100007909BB2A1E716F4007240F0E18050F8E7 -:10382000043B079099E700BFD40B0020900B0020C9 -:10383000A40B00200399049744AC9E4608EE90BA6E -:1038400001F480664FF0000C234606E0BEF10A0F3B -:1038500072F1000239D3A6462A46A6491EEB0200A1 -:1038600040F100000F46A1FB001424F0030101EB1E -:103870009401401ABEEB00014FF0CC3562F1000418 -:1038800005FB01F507FB0455A1FB07410D44052786 -:1038900004F00101A1FB071B09186408303103F88B -:1038A000011C44EAC5740CF1010C013B6D08002EAB -:1038B000CCD00B9909786145C8D1BCF1FF0FC5D0B8 -:1038C000BEF10A0F72F100026CD21C4644AB1B1B06 -:1038D000049F039E049318EE90BAFFF772BA039602 -:1038E000FFF762BA5846FBF783F8FFF75BB9012987 -:1038F00003967FF4CDACFFF75CBA079B059953F8AC -:10390000042B11600793FFF77EB9062F3B46039AFD -:10391000794C079228BF062304930393FFF725BB36 -:10392000039B079913F4007214BF51F8043B51F83C -:10393000043B07911CBF0246DBB20121FFF78FBA9F -:1039400016AB00930023194613AA5846FFF734F824 -:1039500003460133049000F0AE801394049B002BC7 -:1039600030D0632B63DC002308932BAC08220021AA -:1039700016A8FBF7E3F9049D16AB009313AA2B4698 -:1039800021465846FFF718F8854240F0AB80039B6C -:10399000049A07930023A3541F4622EAE273039379 -:1039A000FFF716BA0E9A0D999B1A18460893FBF763 -:1039B0005DFA0B99089B4A780AB101310B914FF0DF -:1039C000000C48E7039B0793049B03931F4608934F -:1039D000FFF7FEB9012118460DF16C09FFF713BB83 -:1039E00050F8043B07902246DBB2B6E612F9043BDE -:1039F0000792DA171146FFF7CAB951F8043B07914D -:103A00000246DBB2FFF727BA01231C9301210DF117 -:103A100043031B930DF16C090B46FFF7CDBA079BCF -:103A2000059953F8042B07931180FFF7ECB8591C44 -:103A30005846FAF799FA044600283CD0089095E7D2 -:103A4000886DFBF7E1FAFFF7E9B9039B0793CDE92E -:103A50000377089FFFF7BCB919981A9B013045E519 -:103A6000039B07932046FBF72BFB20EAE0732F46CE -:103A7000049003930895FFF7ABB918EE101A18AA33 -:103A80005846FFF739F800283FF436AAFFF74DBA39 -:103A9000199801307AE58C466EE46B6ED90705D42F -:103AA000AB899A0502D4A86DFBF7AEFA4FF0FF334D -:103AB0000593FFF749BA18EE102AB2F90C3043F01B -:103AC00040039381FFF735BA079C049746E7079BAD -:103AD00098F8011053F8047B0793904647EAE7777C -:103AE000FFF7B9B818EE102A938943F04003938189 -:103AF000FFF715BACDCCCCCCB80B002070B50C4676 -:103B00008989ADF58E6D21F00201ADF81410616E5A -:103B10001B91E189ADF81610E1690991616A0B9179 -:103B20001CA9029106914FF4806106460491079109 -:103B300018A80021CDE900320891FBF75FFADDE912 -:103B4000003202A93046FFF713F8051E07DB02A971 -:103B50003046FDF73BFF002818BF4FF0FF35BDF89A -:103B600014305B0603D5A38943F04003A381189862 -:103B7000FBF746FA28460DF58E6D70BD9368002B55 -:103B800000F085802DE9F04FB1F90C300C46190793 -:103B9000804683B0174698B225D523691BB310F031 -:103BA00002033D682DD04FF0000ADFF8C0B2564640 -:103BB000B9465E453346524628BF5B464046002E16 -:103BC00052D0E169676AB847002856DDD9F8083055 -:103BD0001B1A8244361AC9F80830002BE9D100209C -:103BE00003B0BDE8F08F2146404600F041F90028BF -:103BF00040F03881B4F90C303D6898B210F00203FF -:103C0000D1D110F0010944D14E46009746B3820548 -:103C1000D4F808B040F18580B3455A4600F2B4802C -:103C200010F4906F40F0C180206801924946FBF784 -:103C300009F8A368019AA3EB0B012368A160134460 -:103C4000B24623600026009A9368A3EB0A03D1448E -:103C50009360002BC3D0B4F90C0080B2002ED6D1F3 -:103C6000D5E900960835D1E7D5E900A60835A0E7E3 -:103C700021464046FDF7AAFE88B3B4F90C3043F064 -:103C800040034FF0FF30A38103B0BDE8F08F002068 -:103C900070471E46BA469946184600951F4666B3B9 -:103CA000002832D04A46D4E904132068A568B242FD -:103CB00028BF3246884204D905EB030B5A4500F36E -:103CC000A780934264DCE169656A3A464046A847AA -:103CD000B0F1000BD1DDB9EB0B09C9D00120DAF846 -:103CE0000830A3EB0B035F44A6EB0B06CAF80830C1 -:103CF000002B3FF474AF002ED2D1009A56681346C1 -:103D000008320092002EF8D01F6832460A21384649 -:103D1000FBF77EF9002800F09C800130A0EB07093A -:103D2000C0E720682369984216D86269B24213D866 -:103D30006FF00043B34228BF3346E16993FBF2F3CF -:103D4000676A02FB03F340464A46B847B0F1000AEF -:103D500093DDA6EB0A0676E7B345DA4628BFB246FE -:103D600052464946FAF76EFFA3682268A3EB0A039E -:103D70005244A3602260002BEBD121464046FDF760 -:103D800025FE0028E5D078E72068B34632464CE7A8 -:103D900039460192FAF756FF019AA3689B1AA3606D -:103DA000236813442360934695E723682169A3EBB6 -:103DB000010B636903EB430A0AEBDA7A0BF10103A7 -:103DC0004FEA6A0A33445345524684BF9A465246E4 -:103DD00043052CD511464046FAF7C6F800283BD0DB -:103DE0005A4621690190F8F71BFDA289019B22F434 -:103DF000906242F08002A28103EB0B002361AAEBE8 -:103E00000B03C4F814A0A3602060B34632460CE74D -:103E100039465A46FAF716FF23685B442360214669 -:103E20004046FDF7D3FD00283FF455AF25E7404657 -:103E3000FAF756FB03460028DED121694046FBF71E -:103E400041FAB4F90C300C2223F08003C8F80020AA -:103E500015E7721C914626E70C22B4F90C30C8F81D -:103E600000200CE74FF0FF30BAE600BF00FCFF7FF8 -:103E700038B5314B1B6805460C4613B15A6B002A06 -:103E80004ED0B4F90C3018079AB21CD5216929B369 -:103E900012F0010007D00020A06060694042A061DC -:103EA00039B1002038BD950758BF6069A06000296E -:103EB000F7D1120658BF0846F4D543F04003A3815A -:103EC0004FF0FF3038BDD1062ED5520714D42169EA -:103ED00043F00803A3819AB20029D9D102F42070DB -:103EE000B0F5007FD4D02146284600F047F9B4F958 -:103EF0000C3021699AB2CBE7216B51B104F1400239 -:103F0000914204D02846FBF7DDF9B4F90C300022C9 -:103F1000226321690022C4E9001223F02403D7E7B9 -:103F20001846FAF765FDACE7092243F040032A6022 -:103F30004FF0FF30A38138BD881A00202DE9F047EB -:103F400082B0824688461446FAF7C2FF012803D1A0 -:103F500008F1FF33FE2B36D90DF10409424604F176 -:103F60005C0349465046FEF701FD421C064632D02E -:103F700020B39DF804C0002509E023685A1C226084 -:103F800083F800C00135B54218D219F801CFA368F3 -:103F9000013B002BA360F0DAA769BB4261462246D1 -:103FA000504602DBBCF10A0FE7D100F053F9431C85 -:103FB000E8D10646304602B0BDE8F08746463046B6 -:103FC00002B0BDE8F0875FFA88FC8DF804C00646B1 -:103FD0000DF10409CFE7A389304643F04003A381E4 -:103FE00002B0BDE8F08700BF30B5536E13F0010F8B -:103FF000B2F90C30144683B005469AB201D1980547 -:104000001CD5900406D4626E43F4005342F400526F -:10401000A381626622462846FFF790FF636EDA07A7 -:10402000054602D4A3899B0502D5284603B030BDBE -:10403000A06DFAF7E9FF284603B030BDA06D0191ED -:10404000FAF7E0FFB4F90C3001999AB2D9E700BF52 -:104050002DE9F04F8BB0DDE9158A149F039181465D -:1040600005921E46B8F1000F5CD0039B002B5ED07A -:10407000059B1D68002F6AD0741E4EB3039B0493EA -:10408000043D002601950BE0039B2BBB019B1A68A6 -:10409000002A3AD0BC455CD2013C631C664617D06E -:1040A000D8F800300293019BDAF8E05053F8042F5F -:1040B000019307A943464846D8F804B0A847421CD4 -:1040C0003AD000EB060CBC45DED9029BC8E9003BA8 -:1040D00030460BB0BDE8F08F00280EDD049B019D3B -:1040E00018445A1E07A900F1FF3E11F8013B02F8DF -:1040F000013F7245F9D101950490059B1A6804327D -:104100001A60019B1A68002AC4D1039B0BB1059B5E -:104110001A600CF1FF3600223046C8F800200BB0C0 -:10412000BDE8F08F039B00F58678002BA0D1059B9E -:104130004FF0FF371D689FE706468A210022304670 -:10414000C9F80010C8F800200BB0BDE8F08F3E465B -:10415000BEE76646BCE700BF10B584B0054C0698C4 -:10416000009007980190044800680294FFF770FFE0 -:1041700004B010BD00150020881A00202DE9F04180 -:104180008B890C46990796B008D504F143030122A8 -:10419000C4E90432236016B0BDE8F081B4F90E1012 -:1041A0000029064625DB6A4600F0ACF800281FDB34 -:1041B000019D05F47045A5F50055B5FA85F54FF458 -:1041C00080686D094FF4006741463046F9F7CCFE30 -:1041D000E0B1B4F90C30C4F8148043F080032060DF -:1041E0002061A38135BB3B43A38116B0BDE8F081BC -:1041F000A38913F0800519D04FF0400800254146EF -:1042000030462F46F9F7B0FE0028E2D1B4F90C3061 -:104210009A05C0D423F0030304F1430243F00203E0 -:104220000121C4E90421A3812260B4E74FF480682E -:104230002F46C9E7B4F90E10304600F079F810B9EE -:10424000B4F90C30CFE7A38923F0030343F0010353 -:104250001BB2C8E7F8B50D461446064610B1436BCD -:10426000002B4CD0B4F90C20A369A360170790B2BF -:104270001BD52369CBB1EDB281042F4622D522682C -:104280006169D31A994229DD0133A1680139A1601E -:10429000511C2160157062699A4227D0A389DB07FF -:1042A00001D50A2D22D03846F8BD21463046FFF709 -:1042B000DFFD08BBB4F90C20236990B2EDB2810494 -:1042C0002F46DCD442F40052A281626E616922F46E -:1042D000005262662268D31A9942D5DC21463046E4 -:1042E000FDF774FB40B922680123CEE72146304632 -:1042F000FDF76CFB0028D6D04FF0FF37D3E7FAF775 -:1043000077FBAFE770B50C46084D03460026204604 -:1043100011461C462E60F8F703FD431C00D070BD0B -:104320002B68002BFBD0236070BD00BF082B002042 -:1043300038B5074D0022044608462A60F8F7F6FC17 -:10434000431C00D038BD2B68002BFBD0236038BD48 -:10435000082B0020000000005FF800F071160060DC -:104360005FF800F0CD1C00605FF800F0751D006084 -:104370005FF800F0D91700605FF800F041180060A6 -:04438000F8B500BFCD -:08438400B89BFF7F010000005F -:10438C000000000000000000000000000000000021 -:10439C000000000000000000000000000000000011 -:1043AC000000000000000000000000000000000001 -:1043BC0000000000000000000000000000000000F1 -:1043CC0000000000000000000000000000000000E1 -:1043DC0000000000000000000000000000000000D1 -:1043EC0000000000000000000000000000000000C1 -:1043FC0000000000000000000000000000000000B1 -:10440C0000000000000000000000000000000000A0 -:10441C000000000000000000000000000000000090 -:10442C000000000000000000000000000000000080 -:10443C000000000000000000000000000000000070 -:10444C000000000000000000000000000000000060 -:10445C000000000000000000000000000000000050 -:10446C000000000000000000000000000000000040 -:10447C000000000000000000000000000000000030 -:10448C000000000000000000000000000000000020 -:10449C000000000000000000000000000000000010 -:1044AC000000000000000000000000000000000000 -:1044BC0000000000000000000000000000000000F0 -:1044CC0000000000000000000000000000000000E0 -:1044DC0000000000000000000000000000000000D0 -:1044EC0000000000000000000000000000000000C0 -:1044FC0000000000000000000000000000000000B0 -:10450C00000000000000000000000000000000009F -:10451C00000000000000000000000000000000008F -:10452C00000000000000000000000000000000007F -:10453C00000000000000000000000000000000006F -:10454C00000000000000000000000000000000005F -:10455C00000000000000000000000000000000004F -:10456C00000000000000000000000000000000003F -:10457C00000000000000000000000000000000002F -:10458C00000000000000000000000000000000001F -:10459C00000000000000000000000000000000000F -:1045AC0000000000000000000000000000000000FF -:1045BC0000000000000000000000000000000000EF -:1045CC0000000000000000000000000000000000DF -:1045DC0000000000000000000000000000000000CF -:1045EC0000000000000000000000000000000000BF -:1045FC0000000000000000000000000000000000AF -:10460C000080E03779C34143176E05B5B5B89346C2 -:10461C00F5F93FE9034F384D321D30F94877825A8E -:10462C003CBF737FDD4F1575000000000000F03FAC -:10463C000000000000002440000000000000594071 -:10464C000000000000408F40000000000088C340C4 -:10465C0000000000006AF8400000000080842E4139 -:10466C0000000000D01263410000000084D7974185 -:10467C000000000065CDCD41000000205FA002428B -:10468C00000000E876483742000000A2941A6D4200 -:10469C00000040E59C30A2420000901EC4BCD642F3 -:1046AC0000003426F56B0C430080E03779C341439E -:1046BC0000A0D8855734764300C84E676DC1AB4314 -:1046CC00003D9160E458E143408CB5781DAF154432 -:1046DC0050EFE2D6E41A4B4492D54D06CFF080440D -:1046EC00F64AE1C7022DB544B49DD9794378EA4422 -:1046FC000000C0410000C8418FC2EF41FF007801AB -:10470C0080014302880187018C018B019201910188 -:10471C009501F601990198019A013D029E01200232 -:10472C00A801A701AD01AC01B001AF01B901B801FD -:10473C00BD01BC01BF01F701C601C401C901C7011C -:10474C00CC01CA01DD018E01F301F101F501F40187 -:10475C003A02652C3C023B023E02662C42024102AC -:10476C0053028101540286015602890157028A01C3 -:10477C0059028F015B029001600293016302940164 -:10478C0068029701690296016B02622C6F029C0110 -:10479C0072029D0175029F017D02642C8002A601AC -:1047AC008302A9018802AE01890244028A02B10186 -:1047BC008B02B2018C0245029202B7017B03FD030E -:1047CC007C03FE037D03FF03AC038603C203A30338 -:1047DC00CC038C03CD038E03CE038F03F203F903BA -:1047EC00F803F703FB03FA03CF04C0047D1D632C0D -:1047FC00511F591F531F5B1F551F5D1F571F5F1FF5 -:10480C00781FF81F791FF91FB31FBC1FCC1FC31FC4 -:10481C00E51FEC1FFC1FF31F4E2132218421832145 -:10482C00612C602C762C752CD007000064000000E5 -:10483C00F40100006100E01AE000E017F800E00766 -:10484C000001013032010106390101104A01012E2B -:10485C007901010682010104A0010106B3010104E2 -:10486C00CD010110DE010112F80101282202011212 -:10487C004602010AAD03DB03B103E011C303E009F7 -:10488C00D80301183004E0205004B0106004012259 -:10489C008A040136C104010ED00401446105D026FE -:1048AC00001E0196A01E015A001F0808101F0806C2 -:1048BC00201F0808301F0808401F0806601F080842 -:1048CC00701F4A02721F5604761F64027A1F700210 -:1048DC007C1F7E02801F0808901F0808A01F080874 -:1048EC00B01F0802D01F0802E01F08027021F01050 -:1048FC00D024E61A302CD02F672C0106802C0164B2 -:10490C00002D002641FFE01A436172642069732078 -:10491C00746F6F20736D616C6C2E0D0A00000000BB -:10492C00466F726D617420446F6E650D0A00000055 -:10493C00466F726D6174204661696C65640D0A0086 -:10494C0042616420636C757374657220636F756E5D -:10495C00740D0A0044657669636520697320746F71 -:10496C006F20736D616C6C0D0A00000057726974D6 -:10497C00696E672046415420000000002E000000A4 -:10498C0057726974696E6720757063617365207402 -:10499C0061626C650D0A000057726974696E67205C -:1049AC00726F6F740D0A0000466F726D6174206433 -:1049BC006F6E650D0A000000466F726D61742066A3 -:1049CC0061696C65640D0A0045584641540000004D -:1049DC0089A000008DA0000091A0000095A000000F -:1049EC006CC00F40C0000000504F00005519000073 -:1049FC000C000000130000000000000024851F4084 -:104A0C000B000000130000000000000028851F4070 -:104A1C000D000000130000000000000020851F4066 -:104A2C000A00000013000000010000001C851F405C -:104A3C000000000000000000F9140000E514000064 -:104A4C007D0F000065140000811500001914000092 -:104A5C00C11300000000000000000000F9AC0000D1 -:104A6C000000000000000000C50A0000000000006B -:104A7C0000000000AD9300000000000000000000EA -:104A8C00096E0000156E00000D6E0000156F000021 -:104A9C0085760000B575000011760000B174000039 -:104AAC0091700000C57A0000256E0000996D000021 -:104ABC0055770000856D0000896D0000916D000038 -:104ACC00956D0000A9700000E57800006D7800007D -:104ADC00C57300007D6D00008D6D0000C579000070 -:104AEC00ED760000896E0000000000000000000060 -:104AFC006DA20000C9B60000C5B60000C1B600002A -:104B0C00BDB60000B9B60000B5B60000B1B60000E5 -:104B1C000000000000000000C5070000590500005F -:104B2C00510800005D050000F507000000000000C2 -:104B3C000000000019160000C91100007D0F0000D4 -:104B4C006D1200000D120000791400009512000087 -:104B5C00851700002D180000000000000000000068 -:104B6C00F9140000E51400007D0F0000651400002E -:104B7C008115000019140000C11300000000000092 -:104B8C00000000006D160000AD16000001140000BE -:104B9C00D1140000CD150000A91300005114000021 -:104BAC0011100000F5160000C1120000DD1200000B -:104BBC00990F0000850F0000C10F0000D9130000F1 -:104BCC00F9120000A110000059110000E9100000BA -:104BDC002D1500004D10000000000000000000002A -:104BEC00F9AC000075A200007D0F0000810F0000E1 -:104BFC00F9AC0000F9AC0000F9AC000000000000BA -:104C0C0000000000B91C0000C91E00008D1E000031 -:104C1C00D51D0000391E0000811D0000011F000081 -:104C2C00F11F00002D2000000921000000000000F1 -:104C3C0000000000DD950000099600007D0F0000CB -:104C4C00D995000095950000A1950000C195000034 -:104C5C000000000000000000A57C0000A97C000002 -:104C6C00157B000099800000E18C0000618600003B -:104C7C00C5630000D57C0000B18C0000F18D0000F4 -:104C8C00E98600001D5C000009840000357C0000F2 -:104C9C00417C0000097B00000D7B0000117B0000B3 -:104CAC004D7C0000717C0000957C0000158100009B -:104CBC00B97C0000ED7E00006181000035820000AF -:104CCC002D9B0000319B0000399B0000419B000094 -:104CDC00D8399D270054EA2A00A4781F007B9A1724 -:104CEC002C2066756E6374696F6E3A2000000000AC -:104CFC00617373657274696F6E202225732220664E -:104D0C0061696C65643A2066696C652022257322A2 -:104D1C002C206C696E65202564257325730A0000B0 -:104D2C0042616C6C6F632073756363656564656465 -:104D3C00000000002F646174612F6A656E6B696EF0 -:104D4C00732F776F726B73706163652F474E552DA0 -:104D5C00746F6F6C636861696E2F61726D2D313188 -:104D6C002F7372632F6E65776C69622D6379677729 -:104D7C00696E2F6E65776C69622F6C6962632F7335 -:104D8C0074646C69622F6D707265632E6300000031 -:104D9C0000202020202020202020282828282820FF -:104DAC0020202020202020202020202020202020F7 -:104DBC00208810101010101010101010101010105F -:104DCC00100404040404040404040410101010104F -:104DDC001010414141414141010101010101010119 -:104DEC00010101010101010101010101101010106B -:104DFC0010104242424242420202020202020202EB -:104E0C00020202020202020202020202101010103E -:104E1C002000000000000000000000000000000066 -:104E2C000000000000000000000000000000000076 -:104E3C000000000000000000000000000000000066 -:104E4C000000000000000000000000000000000056 -:104E5C000000000000000000000000000000000046 -:104E6C000000000000000000000000000000000036 -:104E7C000000000000000000000000000000000026 -:104E8C000000000000000000000000000000000016 -:104E9C0000000000496E66696E69747900000000BC -:104EAC004E614E002F646174612F6A656E6B696E82 -:104EBC00732F776F726B73706163652F474E552D2F -:104ECC00746F6F6C636861696E2F61726D2D313117 -:104EDC002F7372632F6E65776C69622D63796777B8 -:104EEC00696E2F6E65776C69622F6C6962632F73C4 -:104EFC0074646C69622F64746F612E63000000002F -:104F0C00494E4600696E66004E414E006E616E0061 -:104F1C003031323334353637383961626364656623 -:104F2C0000000000303132333435363738394142E5 -:104F3C004344454600000000286E756C6C29000047 -:104F4C0030000000202020202020202020202020A5 -:104F5C002020202020202020202020202020202045 -:104F6C002020202000000042C8801F40B8821F4033 -:104F7C000800000000000042C4801F40B4821F40A3 -:104F8C000400000000C0004224801F4014821F4017 -:104F9C001000000000C0004228801F4018821F40F3 -:104FAC002000000000C000422C801F401C821F40CB -:104FBC004000000000C0004234801F4024821F408B -:104FCC00000100000040004264811F4054831F40D8 -:104FDC00000400000040004280811F4070831F408D -:104FEC0000000200004000427C811F406C831F4087 -:104FFC00000001000040004268811F4058831F40A0 -:10500C0000080000004000423C811F402C831F40E0 -:10501C00010000000040004244811F4034831F40C7 -:10502C00040000000040004240811F4030831F40BC -:10503C00020000000040004248811F4038831F409E -:10504C00080000000000004204811F40F4821F4051 -:10505C00000004000000004208811F40F8821F403D -:10506C00000008000000004218811F4008831F4008 -:10507C00000080000000004214811F4004831F4088 -:10508C00000040000000004200811F40F0821F40E1 -:10509C000000020000000042FC801F40EC821F4018 -:1050AC00000001000000004224811F4014831F40B7 -:1050BC00000000040000004228811F4018831F409C -:1050CC0000000008000000421C811F400C831F40A0 -:1050DC00000000010000004220811F4010831F408F -:1050EC000000000200000042EC801F40DC821F40E8 -:1050FC000010000000000042F0801F40E0821F40C2 -:10510C00002000000000004234811F4024831F4017 -:10511C00000000400000004238811F4028831F40DF -:10512C00000000800080004294801F4084821F4059 -:10513C000000040000C0004290801F4080821F408D -:10514C000000008000800042A8801F4098821F4011 -:10515C000000800000800042A4801F4094821F4009 -:10516C0000004000004000426C811F405C831F40E7 -:10517C000010000000C0004230801F4020821F4001 -:10518C008000000000800042C8811F40B8831F408F -:10519C000080000000800042C4811F40B4831F4087 -:1051AC000040000000800042C0811F40B0831F40BF -:1051BC000020000000800042BC811F40AC831F40D7 -:1051CC000010000000800042D0811F40C0831F40AF -:1051DC000000020000800042CC811F40BC831F40B5 -:1051EC00000001005B4C4F434B5D20253032643A8C -:1051FC00253032643A253032642563253032642000 -:10520C007C20252E32666670730D0A005B46524573 -:10521C00455D20253032643A253032643A253032EF -:10522C00643A25303264207C20252E3266667073F9 -:10523C000D0A000005000000190000007D000000B0 -:10524C004C435F434F4C4C41544500004C435F432F -:10525C0054595045000000004C435F4D4F4E45548F -:10526C00415259004C435F4E554D45524943000045 -:10527C004C435F54494D45004C435F4D455353419E -:10528C004745530000010000901A00201200000056 -:10529C0000060000342000600A000000000200003C -:1052AC00D01F006062000000000700006C1F00604F -:1052BC0062000000EE030000CC1A00201200000077 -:1052CC00000004EEA41A00202800000000030000D7 -:1052DC00681F00600000000001030904501F0060FB -:1052EC000000000002030904381F006000000000E9 -:1052FC0003030904E01A0020000000000000000075 -:10530C000000000000000000303030303030303011 -:10531C003030303030303030303030303030303081 -:10532C00303030303030303000000000BC290020EC -:10533C00242A00208C2A002000000000000000001D -:10534C000000000000000000000000000000000051 -:10535C000000000000000000000000000000000041 -:10536C000000000000000000000000000000000031 -:10537C000000000000000000000000000000000021 -:10538C000000000000000000000000000000000011 -:10539C000000000000000000000000000000000001 -:1053AC0000000000000000000000000000000000F1 -:1053BC0000000000000000000000000000000000E1 -:1053CC0001000000000000000E33CDAB34126DE67E -:1053DC00ECDE05000B0000000000000000000000E7 -:1053EC0000000000000000000000000000000000B1 -:1053FC0000000000000000000000000000000000A1 -:10540C000000000000000000000000000000000090 -:10541C000000000000000000000000000000000080 -:10542C000000000000000000000000000000000070 -:10543C000000000000000000000000000000000060 -:10544C0000000000000000000029DE07007B9A1716 -:10545C0000003A4060060020000000000000000040 -:10546C000000000000000000000000000000000030 -:10547C000000000000000000000000000000000020 -:10548C000000000000000000000000000000000010 -:10549C000000000000000000000000000000000000 -:1054AC007007002000000000E8030000000000006E -:1054BC00B408002000000000E80300000000000019 -:1054CC0000003F40E81E00600000000000000000EB -:1054DC0000000000000000000000000000000000C0 -:1054EC0000000000000000000000000000000000B0 -:1054FC0000000000000000000000000000000000A0 -:10550C00000000000000000000000000000000008F -:10551C00000000000000000000000000000000007F -:10552C00000000000000000000000000000000006F -:10553C00000000000000000000000000000000005F -:10554C00000000000000000000000000000000004F -:10555C00000000000000000000000000000000003F -:10556C00000000000000000000000000000000002F -:10557C00000000000000000000000000000000001F -:10558C00000000000000000000000000000000000F -:10559C0000000000000000000000000000000000FF -:1055AC0000000000000000000000000000000000EF -:1055BC0000000000000000000000000000000000DF -:1055CC0000000000000000000000000000000000CF -:1055DC0000000000000000000000000000000000BF -:1055EC0000000000000000000000000000000000AF -:1055FC00B408002000000000E803000000000000D8 -:10560C0000803F40981E0060000000000000000079 -:10561C00000000000000000000000000000000007E -:10562C00000000000000000000000000000000006E -:10563C00000000000000000000000000000000005E -:10564C00000000000000000000000000000000004E -:10565C00000000000000000000000000000000003E -:10566C00000000000000000000000000000000002E -:10567C00000000000000000000000000000000001E -:10568C00000000000000000000000000000000000E -:10569C0000000000000000000000000000000000FE -:1056AC0000000000000000000000000000000000EE -:1056BC0000000000000000000000000000000000DE -:1056CC0000000000000000000000000000000000CE -:1056DC0000000000000000000000000000000000BE -:1056EC0000000000000000000000000000000000AE -:1056FC00000000000000000000000000000000009E -:10570C00000000000000000000000000000000008D -:10571C00000000000000000000000000000000007D -:10572C00000000000000000000000000000000006D -:10573C00B408002000000000E80300000000000096 -:10574C0000C03F40481E0060000000000000000048 -:10575C00000000000000000000000000000000003D -:10576C00000000000000000000000000000000002D -:10577C00000000000000000000000000000000001D -:10578C00000000000000000000000000000000000D -:10579C0000000000000000000000000000000000FD -:1057AC0000000000000000000000000000000000ED -:1057BC0000000000000000000000000000000000DD -:1057CC0000000000000000000000000000000000CD -:1057DC0000000000000000000000000000000000BD -:1057EC0000000000000000000000000000000000AD -:1057FC00000000000000000000000000000000009D -:10580C00000000000000000000000000000000008C -:10581C00000000000000000000000000000000007C -:10582C00000000000000000000000000000000006C -:10583C00000000000000000000000000000000005C -:10584C00000000000000000000000000000000004C -:10585C00000000000000000000000000000000003C -:10586C00000000000000000000000000000000002C -:10587C00FFFFFFFF7C290020C03E2020000000001D -:10588C0043000000000000000000000000000000C9 -:10589C0000000000000000000000000000000000FC -:1058AC0043000000000000000000000000000000A9 -:1058BC0000000000000000000000000000000000DC -:1058CC004300000000000000000000000000000089 -:1058DC0000000000000000000000000000000000BC -:1058EC004300000000000000000000000000000069 -:1058FC00000000000000000000000000000000009C -:10590C004300000000000000000000000000000048 -:10591C00000000000000000000000000000000007B -:10592C004300000000000000000000000000000028 -:10593C00000000000000000000000000000000005B -:10594C004300000000000000000000000000000008 -:10595C00000000000000000000000000000000003B -:10596C0035DC000091D4000000000000100A00207B -:10597C00FC0500209C0500209C0500209C050020B7 -:10598C009C0500209C0500209C0500209C05002007 -:10599C009C0500209C050020FFFFFFFFFFFFFFFF81 -:1059AC00FFFFFFFFFFFF0000010041534349490087 -:1059BC0000000000000000000000000000000000DB -:1059CC000000000000000000000041534349490062 -:1059DC0000000000000000000000000000000000BB -:1059EC0000000000000000000000000000000000AB -:1059FC00000000006C1600206C16002074160020AD -:105A0C00741600207C1600207C16002084160020C2 -:105A1C00841600208C1600208C1600209416002072 -:105A2C00941600209C1600209C160020A416002022 -:105A3C00A4160020AC160020AC160020B4160020D2 -:105A4C00B4160020BC160020BC160020C416002082 -:105A5C00C4160020CC160020CC160020D416002032 -:105A6C00D4160020DC160020DC160020E4160020E2 -:105A7C00E4160020EC160020EC160020F416002092 -:105A8C00F4160020FC160020FC1600200417002041 -:105A9C00041700200C1700200C17002014170020EE -:105AAC00141700201C1700201C170020241700209E -:105ABC00241700202C1700202C170020341700204E -:105ACC00341700203C1700203C17002044170020FE -:105ADC00441700204C1700204C17002054170020AE -:105AEC00541700205C1700205C170020641700205E -:105AFC00641700206C1700206C170020741700200E -:105B0C00741700207C1700207C17002084170020BD -:105B1C00841700208C1700208C170020941700206D -:105B2C00941700209C1700209C170020A41700201D -:105B3C00A4170020AC170020AC170020B4170020CD -:105B4C00B4170020BC170020BC170020C41700207D -:105B5C00C4170020CC170020CC170020D41700202D -:105B6C00D4170020DC170020DC170020E4170020DD -:105B7C00E4170020EC170020EC170020F41700208D -:105B8C00F4170020FC170020FC170020041800203C -:105B9C00041800200C1800200C18002014180020E9 -:105BAC00141800201C1800201C1800202418002099 -:105BBC00241800202C1800202C1800203418002049 -:105BCC00341800203C1800203C18002044180020F9 -:105BDC00441800204C1800204C18002054180020A9 -:105BEC00541800205C1800205C1800206418002059 -:105BFC00641800206C1800206C1800207418002009 -:105C0C00741800207C1800207C18002084180020B8 -:105C1C00841800208C1800208C1800209418002068 -:105C2C00941800209C1800209C180020A418002018 -:105C3C00A4180020AC180020AC180020B4180020C8 -:105C4C00B4180020BC180020BC180020C418002078 -:105C5C00C4180020CC180020CC180020D418002028 -:105C6C00D4180020DC180020DC180020E4180020D8 -:105C7C00E4180020EC180020EC180020F418002088 -:105C8C00F4180020FC180020FC1800200419002037 -:105C9C00041900200C1900200C19002014190020E4 -:105CAC00141900201C1900201C1900202419002094 -:105CBC00241900202C1900202C1900203419002044 -:105CCC00341900203C1900203C19002044190020F4 -:105CDC00441900204C1900204C19002054190020A4 -:105CEC00541900205C1900205C1900206419002054 -:105CFC00641900206C1900206C1900207419002004 -:105D0C00741900207C1900207C19002084190020B3 -:105D1C00841900208C1900208C1900209419002063 -:105D2C00941900209C1900209C190020A419002013 -:105D3C00A4190020AC190020AC190020B4190020C3 -:105D4C00B4190020BC190020BC190020C419002073 -:105D5C00C4190020CC190020CC190020D419002023 -:105D6C00D4190020DC190020DC190020E4190020D3 -:105D7C00E4190020EC190020EC190020F419002083 -:105D8C00F4190020FC190020FC190020041A002032 -:105D9C00041A00200C1A00200C1A0020141A0020DF -:105DAC00141A00201C1A00201C1A0020241A00208F -:105DBC00241A00202C1A00202C1A0020341A00203F -:105DCC00341A00203C1A00203C1A0020441A0020EF -:105DDC00441A00204C1A00204C1A0020541A00209F -:105DEC00541A00205C1A00205C1A0020641A00204F -:105DFC00641A0020FFFFFFFF0000020000000000FB -:105E0C0003000000BC290020A80F00200000C8419E -:105E1C0012010002EF020140C01683047902010254 -:105E2C000301000028000000000104000100000034 -:105E3C0000000000020157494E555342000000007B -:105E4C0000000000000000000000000012034D00E4 -:105E5C00530046005400310030003000F8000000C0 -:105E6C000C03000000000000000000000000000017 -:105E7C0000000000000029010000000000000000EC -:105E8C000000000000000000000000000000000006 -:105E9C0000000000000000000000000000000000F6 -:105EAC0000000000000000000000000000000000E6 -:105EBC0000000000000000000000000000000000D6 -:105ECC0000000000000000000000000000000000C6 -:105EDC0000000000000000000000000000000000B6 -:105EEC0000000000000000000000000000000000A6 -:105EFC000000000000000000000000000000000096 -:105F0C000000000000000000000000000000000085 -:105F1C000000000000000000000000000000000075 -:105F2C000000000000000000000000000000000065 -:105F3C000000000000000000000000000000000055 -:105F4C000000000000000000000000000000000045 -:105F5C000000000000000000000000000000000035 -:105F6C000000000000000000000000000000000025 -:105F7C000000000000000000000000000000000015 -:105F8C000000000000000000000000000000000005 -:105F9C0000000000000000000000000000000000F5 -:105FAC0000000000000000000000000000000000E5 -:105FBC0000000000000000000000000000000000D5 -:105FCC0000000000000000000000000000000000C5 -:105FDC0000000000000000000000000000000000B5 -:105FEC0000000000000000000000000000000000A5 -:105FFC000000000000000000000000000000000095 -:10600C000000000000000000000000000000000084 -:10601C000000000000000000000000000000000074 -:10602C000000000000000000000000000000000064 -:10603C000000000000000000000000000000000054 -:10604C000000000000000000000000000000000044 -:10605C000000000000000000000000000000000034 -:10606C000000000000000000000000000000000024 -:10607C000000000000000000000000000000000014 -:10608C000000000000000000000000000000000004 -:10609C0000000000000000000000000000000000F4 -:1060AC0000000000000000000000000000000000E4 -:1060BC0000000000000000000000000000000000D4 -:1060CC0000000000000000000000000000000000C4 -:1060DC0000000000000000000000000000000000B4 -:1060EC0000000000000000000000000000000000A4 -:1060FC000000000000000000000000000000000094 -:10610C000000000000000000000000000000000083 -:10611C000000000000000000000000000000000073 -:10612C000000000000000000000000000000000063 -:10613C000000000000000000000000000000000053 -:10614C000000000000000000000000000000000043 -:10615C000000000000000000000000000000000033 -:10616C000000000000000000000000000000000023 -:10617C000000000000000000000000000000000013 -:10618C000000000000000000000000000000000003 -:10619C0000000000000000000000000000000000F3 -:1061AC0000000000000000000000000000000000E3 -:1061BC0000000000000000000000000000000000D3 -:1061CC0000000000000000000000000000000000C3 -:1061DC0000000000000000000000000000000000B3 -:1061EC0000000000000000000000000000000000A3 -:1061FC000000000000000000000000000000000093 -:10620C000000000000000000000000000000000082 -:10621C000000000000000000000000000000000072 -:10622C000000000000000000000000000000000062 -:10623C000000000000000000000000000000000052 -:10624C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52 -:10625C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42 -:10626C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32 -:10627C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:10628C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:10629C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:1062AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:1062BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:1062CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:1062DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:1062EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2 -:1062FC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2 -:10630C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91 -:10631C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF81 -:10632C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71 -:10633C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF61 -:10634C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF51 -:10635C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 -:10636C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF31 -:10637C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF21 -:10638C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11 -:10639C00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 -:1063AC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 -:1063BC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 -:1063CC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1 -:1063DC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1 -:1063EC00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1 -:1063FC00FFFFFFFF00000000000000000000000095 -:10640C000000000000000000000000000000000080 -:10641C000000000000000000000000000000000070 -:10642C000000000000000000000000000000000060 -:10643C000000000000000000000000000000000050 -:10644C000000000000000000000000000000000040 -:10645C000000000000000000000000000000000030 -:10646C000000000000000000000000000000000020 -:10647C000000000000000000000000000000000010 -:10648C000000000000000000000000000000000000 -:10649C0000000000000000000000000000000000F0 -:1064AC0000000000000000000000000000000000E0 -:1064BC0000000000000000000000000000000000D0 -:1064CC0000000000000000000000000000000000C0 -:1064DC0000000000000000000000000000000000B0 -:1064EC0000000000000000000000000000000000A0 -:1064FC000000000000000000000000000000000090 -:10650C00000000000000000000000000000000007F -:10651C00000000000000000000000000000000006F -:10652C00000000000000000000000000000000005F -:10653C00000000000000000000000000000000004F -:10654C00000000000000000000000000000000003F -:10655C00000000000000000000000000000000002F -:10656C00000000000000000000000000000000001F -:10657C00000000000000000000000000000000000F -:10658C0000000000000000000000000000000000FF -:10659C0000000000000000000000000000000000EF -:1065AC0000000000000000000000000000000000DF -:1065BC0000000000000000000000000000000000CF -:1065CC0000000000000000000000000000000000BF -:1065DC0000000000000000000000000000000000AF -:1065EC00000000000000000000000000000000009F -:1065FC00000000000000000000000000000000008F -:10660C00000000000000000000000000000000007E -:10661C00000000000000000000000000000000006E -:10662C00000000000000000000000000000000005E -:10663C00000000000000000000000000000000004E -:10664C00000000000000000000000000000000003E -:10665C00000000000000000000000000000000002E -:10666C00000000000000000000000000000000001E -:10667C00000000000000000000000000000000000E -:10668C0000000000000000000000000000000000FE -:10669C0000000000000000000000000000000000EE -:1066AC0000000000000000000000000000000000DE -:1066BC0000000000000000000000000000000000CE -:1066CC0000000000000000000000000000000000BE -:1066DC0000000000000000000000000000000000AE -:1066EC00000000000000000000000000000000009E -:1066FC00000000000000000000000000000000008E -:10670C00000000000000000000000000000000007D -:10671C00000000000000000000000000000000006D -:10672C00000000000000000000000000000000005D -:10673C00000000000000000000000000000000004D -:10674C00000000000000000000000000000000003D -:10675C00000000000000000000000000000000002D -:10676C00000000000000000000000000000000001D -:10677C00000000000000000000000000000000000D -:10678C0000000000000000000000000000000000FD -:10679C0000000000000000000000000000000000ED -:1067AC0000000000000000000000000000000000DD -:1067BC0000000000000000000000000000000000CD -:1067CC0000000000000000000000000000000000BD -:1067DC0000000000000000000000000000000000AD -:1067EC00000000000000000000000000000000009D -:1067FC00000000000000000000000000000000008D -:10680C00000000000000000000000000000000007C -:10681C00000000000000000000000000000000006C -:10682C00000000000000000000000000000000005C -:10683C00000000000000000000000000000000004C -:10684C00000000000000000000000000000000003C -:10685C00000000000000000000000000000000002C -:10686C00000000000000000000000000000000001C -:10687C00000000000000000000000000000000000C -:10688C0000000000000000000000000000000000FC -:10689C0000000000000000000000000000000000EC -:1068AC0000000000000000000000000000000000DC -:1068BC0000000000000000000000000000000000CC -:1068CC0000000000000000000000000000000000BC -:1068DC0000000000000000000000000000000000AC -:1068EC00000000000000000000000000000000009C -:1068FC00000000000000000000000000000000008C -:10690C00000000000000000000000000000000007B -:10691C00000000000000000000000000000000006B -:10692C00000000000000000000000000000000005B -:10693C00000000000000000000000000000000004B -:10694C00000000000000000000000000000000003B -:10695C00000000000000000000000000000000002B -:10696C00000000000000000000000000000000001B -:10697C00000000000000000000000000000000000B -:10698C0000000000000000000000000000000000FB -:10699C0000000000000000000000000000000000EB -:1069AC0000000000000000000000000000000000DB -:1069BC0000000000000000000000000000000000CB -:1069CC0000000000000000000000000000000000BB -:1069DC0000000000000000000000000000000000AB -:1069EC00000000000000000000000000000000009B -:1069FC00000000000000000000000000000000008B -:106A0C00000000000000000000000000000000007A -:106A1C00000000000000000000000000000000006A -:106A2C00000000000000000000000000000000005A -:106A3C00000000000000000000000000000000004A -:106A4C00000000000000000000000000000000003A -:106A5C00000000000000000000000000000000002A -:106A6C00000000000000000000000000000000001A -:106A7C00000000000000000000000000000000000A -:106A8C0000000000000000000000000000000000FA -:106A9C0000000000000000000000000000000000EA -:106AAC0000000000000000000000000000000000DA -:106ABC0000000000000000000000000000000000CA -:106ACC0000000000000000000000000000000000BA -:106ADC0000000000000000000000000000000000AA -:106AEC00000000000000000000000000000000009A -:106AFC00000000000000000000000000000000008A -:106B0C000000000000000000000000000000000079 -:106B1C000000000000000000000000000000000069 -:106B2C000000000000000000000000000000000059 -:106B3C000000000000000000000000000000000049 -:106B4C000000000000000000000000000000000039 -:106B5C000000000000000000000000000000000029 -:106B6C000000000000000000000000000000000019 -:106B7C000000000000000000000000000000000009 -:106B8C0000000000000000000000000000000000F9 -:106B9C0000000000000000000000000000000000E9 -:106BAC0000000000000000000000000000000000D9 -:106BBC0000000000000000000000000000000000C9 -:106BCC0000000000000000000000000000000000B9 -:106BDC0000000000000000000000000000000000A9 -:106BEC000000000000000000000000000000000099 -:106BFC000000000000000000000000000000000089 -:106C0C000000000000000000000000000000000078 -:106C1C000000000000000000000000000000000068 -:106C2C000000000000000000000000000000000058 -:106C3C000000000000000000000000000000000048 -:106C4C000000000000000000000000000000000038 -:106C5C000000000000000000000000000000000028 -:106C6C000000000000000000000000000000000018 -:106C7C000000000000000000000000000000000008 -:106C8C0000000000000000000000000000000000F8 -:106C9C0000000000000000000000000000000000E8 -:106CAC0000000000000000000000000000000000D8 -:106CBC0000000000000000000000000000000000C8 -:106CCC0000000000000000000000000000000000B8 -:106CDC0000000000000000000000000000000000A8 -:106CEC000000000000000000000000000000000098 -:106CFC000000000000000000000000000000000088 -:106D0C000000000000000000000000000000000077 -:106D1C000000000000000000000000000000000067 -:106D2C000000000000000000000000000000000057 -:106D3C000000000000000000000000000000000047 -:106D4C000000000000000000000000000000000037 -:106D5C000000000000000000000000000000000027 -:106D6C000000000000000000000000000000000017 -:106D7C000000000000000000000000000000000007 -:106D8C0000000000000000000000000000000000F7 -:106D9C0000000000000000000000000000000000E7 -:106DAC0000000000000000000000000000000000D7 -:106DBC0000000000000000000000000000000000C7 -:106DCC0000000000000000000000000000000000B7 -:106DDC0000000000000000000000000000000000A7 -:106DEC000000000000000000000000000000000097 -:106DFC000000000000000000000000000000000087 -:106E0C000000000000000000000000000000000076 -:106E1C000000000000000000000000000000000066 -:106E2C000000000000000000000000000000000056 -:106E3C000000000000000000000000000000000046 -:106E4C000000000000000000000000000000000036 -:106E5C000000000000000000000000000000000026 -:106E6C000000000000000000000000000000000016 -:106E7C000000000000000000000000000000000006 -:106E8C0000000000000000000000000000000000F6 -:106E9C0000000000000000000000000000000000E6 -:106EAC0000000000000000000000000000000000D6 -:106EBC0000000000000000000000000000000000C6 -:106ECC0000000000000000000000000000000000B6 -:106EDC0000000000000000000000000000000000A6 -:106EEC000000000000000000000000000000000096 -:106EFC000000000000000000000000000000000086 -:106F0C000000000000000000000000000000000075 -:106F1C000000000000000000000000000000000065 -:106F2C000000000000000000000000000000000055 -:106F3C000000000000000000000000000000000045 -:106F4C000000000000000000000000000000000035 -:106F5C000000000000000000000000000000000025 -:106F6C000000000000000000000000000000000015 -:106F7C000000000000000000000000000000000005 -:106F8C0000000000000000000000000000000000F5 -:106F9C0000000000000000000000000000000000E5 -:106FAC0000000000000000000000000000000000D5 -:106FBC0000000000000000000000000000000000C5 -:106FCC0000000000000000000000000000000000B5 -:106FDC0000000000000000000000000000000000A5 -:106FEC000000000000000000000000000000000095 -:046FFC000000000091 -:040000056000100087 -:00000001FF diff --git a/firmware/ltc_audiohat_lock_v2.ino b/firmware/ltc_audiohat_lock_v2.ino deleted file mode 100644 index 67e31a6..0000000 --- a/firmware/ltc_audiohat_lock_v2.ino +++ /dev/null @@ -1,174 +0,0 @@ -/* Linear Timecode for Audio Library for Teensy 3.x / 4.x - Copyright (c) 2019, Frank BΓΆsing, f.boesing (at) gmx.de - - Development of this audio library was funded by PJRC.COM, LLC by sales of - Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop - open source software by purchasing Teensy or other PJRC products. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice, development funding notice, and this permission - notice shall be included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* - - https://forum.pjrc.com/threads/41584-Audio-Library-for-Linear-Timecode-(LTC) - - LTC example audio at: https://www.youtube.com/watch?v=uzje8fDyrgg - - Adapted by Chris Frankland-Wright 2025 for Teensy Audio Shield Input with autodetect FPS for the NTP-TimeTurner Project - -*/ - -#include -#include -#include "analyze_ltc.h" - -// β€”β€” Configuration β€”β€” -const float FORCE_FPS = 0.0f; // 0 β†’ auto‑detect -const int FRAME_OFFSET = 4; // compensation in frames -const unsigned long LOSS_TIMEOUT = 1000UL; // ms before we go into LOST -const unsigned long BLINK_PERIOD[3] = {2000,100,500}; // NO_LTC, ACTIVE, LOST - -AudioInputI2S i2s1; -AudioAnalyzeLTC ltc1; -AudioControlSGTL5000 sgtl5000; -AudioConnection patchCord(i2s1, 0, ltc1, 0); - -enum State { NO_LTC=0, LTC_ACTIVE, LTC_LOST }; -State ltcState = NO_LTC; -bool ledOn = false; -unsigned long lastDecode = 0; -unsigned long lastBlink = 0; - -// FPS detection -float currentFps = 25.0f; -float periodMs = 0; -const float SMOOTH_ALPHA = 0.1f; -unsigned long lastDetectTs = 0; - -// free‑run -long freeAbsFrame = 0; -unsigned long lastFreeRun = 0; - -void setup() { - Serial.begin(115200); - AudioMemory(12); - sgtl5000.enable(); - sgtl5000.inputSelect(AUDIO_INPUT_LINEIN); - pinMode(LED_BUILTIN, OUTPUT); -} - -void loop() { - unsigned long now = millis(); - // compute framePeriod from currentFps - unsigned long framePeriod = (unsigned long)(1000.0f / currentFps + 0.5f); - - // 1) If in ACTIVE and we've gone > LOSS_TIMEOUT w/o decode, enter LOST - if (ltcState == LTC_ACTIVE && (now - lastDecode) >= LOSS_TIMEOUT) { - ltcState = LTC_LOST; - // bump freeAbsFrame by 1β€―second worth of frames: - int nominal = (currentFps>29.5f) ? 30 : int(currentFps+0.5f); - long dayFrames= 24L*3600L*nominal; - freeAbsFrame = (freeAbsFrame + nominal) % dayFrames; - // reset free‑run timer so we start next tick fresh - lastFreeRun = now; - } - - // 2) Handle incoming LTC frame - if (ltc1.available()) { - ltcframe_t frame = ltc1.read(); - int h = ltc1.hour(&frame), - m = ltc1.minute(&frame), - s = ltc1.second(&frame), - f = ltc1.frame(&frame); - - // β€” FPS detect or force β€” - if (FORCE_FPS > 0.0f) { - currentFps = FORCE_FPS; - } else { - if (lastDetectTs) { - float dt = now - lastDetectTs; - periodMs = periodMs==0 ? dt : (SMOOTH_ALPHA*dt + (1-SMOOTH_ALPHA)*periodMs); - float meas = 1000.0f/periodMs; - const float choices[3] = {24.0f,25.0f,29.97f}; - float bestD=1e6, pick=25.0f; - for (auto c: choices) { - float d = fabs(meas-c); - if (d < bestD) { bestD=d; pick=c; } - } - currentFps = pick; - } - lastDetectTs = now; - } - - // β€” pack + offset + wrap β€” - int nominal = (currentFps>29.5f) ? 30 : int(currentFps+0.5f); - long dayFrames = 24L*3600L*nominal; - long absF = ((long)h*3600 + m*60 + s)*nominal + f + FRAME_OFFSET; - absF = (absF % dayFrames + dayFrames) % dayFrames; - - // β€” reset anchors & state β€” - freeAbsFrame = absF; - lastFreeRun = now; - lastDecode = now; - ltcState = LTC_ACTIVE; - - // β€” print LOCK β€” - long totSec = absF/nominal; - int outF = absF % nominal; - int outS = totSec % 60; - long totMin = totSec/60; - int outM = totMin % 60; - int outH = (totMin/60) % 24; - bool isDF = ltc1.bit10(&frame); - char sep = isDF?';':':'; - Serial.printf("[LOCK] %02d:%02d:%02d%c%02d | %.2ffps\r\n", - outH,outM,outS,sep,outF,currentFps); - - // β€” LED β†’ ACTIVE immediately β€” - lastBlink = now; - ledOn = true; - digitalWrite(LED_BUILTIN, HIGH); - } - // 3) If in LOST, do free‑run printing - else if (ltcState == LTC_LOST) { - if ((now - lastFreeRun) >= framePeriod) { - freeAbsFrame = (freeAbsFrame + 1) % (24L*3600L*((int)(currentFps+0.5f))); - lastFreeRun += framePeriod; - - // β€” print FREE β€” - int nominal = (currentFps>29.5f) ? 30 : int(currentFps+0.5f); - long totSec = freeAbsFrame/nominal; - int outF = freeAbsFrame % nominal; - int outS = totSec % 60; - long totMin = totSec/60; - int outM = totMin % 60; - int outH = (totMin/60)%24; - Serial.printf("[FREE] %02d:%02d:%02d:%02d | %.2ffps\r\n", - outH,outM,outS,outF,currentFps); - } - } - - // 4) LED heartbeat - unsigned long bp = BLINK_PERIOD[ltcState]; - if ((now - lastBlink) >= (bp/2)) { - ledOn = !ledOn; - digitalWrite(LED_BUILTIN, ledOn); - lastBlink = now; - } -} \ No newline at end of file diff --git a/setup.sh b/setup.sh index 0b68c12..efef9d9 100644 --- a/setup.sh +++ b/setup.sh @@ -1,280 +1,125 @@ #!/bin/bash set -e -echo "--- TimeTurner Setup ---" +echo "" +echo "─────────────────────────────────────────────" +echo " Welcome to the NTP TimeTurner Installer" +echo "─────────────────────────────────────────────" +echo "" +echo "\"It's a very complicated piece of magic...\" – Hermione Granger" +echo "Preparing the Ministry-grade temporal interface..." +echo "" -# Check if TimeTurner is already installed. -INSTALL_DIR="/opt/timeturner" -if [ -f "${INSTALL_DIR}/timeturner" ]; then - echo "βœ… TimeTurner is already installed." - # Ask the user what to do - read -p "Do you want to (U)pdate, (R)einstall, or (A)bort? [U/r/a] " choice - case "$choice" in - r|R ) - echo "Proceeding with full re-installation..." - # Stop the service to allow overwriting the binary, ignore errors if not running - echo "Stopping existing TimeTurner service..." - sudo systemctl stop timeturner.service || true - # The script will continue to the installation steps below. - ;; - a|A ) - echo "Aborting setup." - exit 0 - ;; - * ) # Default to Update - echo "Attempting to run the update script..." - # Ensure we are in a git repository and the update script exists - if [ -d ".git" ] && [ -f "update.sh" ]; then - chmod +x update.sh - ./update.sh - # Exit cleanly after the update - exit 0 - else - echo "⚠️ Could not find 'update.sh' or not in a git repository." - echo "Please re-clone the repository to get the update script, or remove the existing installation to run setup again:" - echo " sudo rm -rf ${INSTALL_DIR}" - exit 1 - fi - ;; - esac +# --------------------------------------------------------- +# Step 1: Update and upgrade packages +# --------------------------------------------------------- +echo "Step 1: Updating package lists and upgrading..." +sudo apt update && sudo apt upgrade -y + +# --------------------------------------------------------- +# Step 2: Install core tools and Python dependencies +# --------------------------------------------------------- +echo "Step 2: Installing required tools..." +sudo apt install -y git curl python3 python3-pip build-essential cmake \ + python3-serial libusb-dev + +# --------------------------------------------------------- +# Step 2.5: Install teensy-loader-cli from source +# --------------------------------------------------------- +echo "Installing teensy-loader-cli manually from source..." +cd "$HOME" +if [ ! -d teensy_loader_cli ]; then + git clone https://github.com/PaulStoffregen/teensy_loader_cli.git fi +cd teensy_loader_cli +make +sudo install -m 755 teensy_loader_cli /usr/local/bin/teensy-loader-cli +echo "Verifying teensy-loader-cli..." +teensy-loader-cli --version || echo "⚠️ teensy-loader-cli failed to install properly" -# Determine package manager -PKG_MANAGER="" -if command -v apt &> /dev/null; then - PKG_MANAGER="apt" -elif command -v dnf &> /dev/null; then - PKG_MANAGER="dnf" -elif command -v pacman &> /dev/null; then - PKG_MANAGER="pacman" +# --------------------------------------------------------- +# Step 2.6: Install udev rules for Teensy +# --------------------------------------------------------- +echo "Installing udev rules for Teensy access..." +cd "$HOME" +wget -O 49-teensy.rules https://www.pjrc.com/teensy/49-teensy.rules +sudo cp 49-teensy.rules /etc/udev/rules.d/ +sudo udevadm control --reload-rules +sudo udevadm trigger +echo "βœ… Teensy udev rules installed. Reboot required to take full effect." + +# --------------------------------------------------------- +# Step 3: Install Arduino CLI manually (latest version) +# --------------------------------------------------------- +echo "Step 3: Downloading and installing arduino-cli..." +cd "$HOME" +curl -fsSL https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_ARM64.tar.gz -o arduino-cli.tar.gz +tar -xzf arduino-cli.tar.gz +sudo mv arduino-cli /usr/local/bin/ +rm arduino-cli.tar.gz + +echo "Verifying arduino-cli install..." +arduino-cli version || echo "⚠️ arduino-cli install failed or not found in PATH" + +# --------------------------------------------------------- +# Step 4: Download and apply splash screen +# --------------------------------------------------------- +echo "Step 4: Downloading and applying splash screen..." +cd "$HOME" +wget -O splash.png https://raw.githubusercontent.com/cjfranko/NTP-Timeturner/master/splash.png + +if [ -f splash.png ]; then + sudo cp splash.png /usr/share/plymouth/themes/pix/splash.png + sudo chmod 644 /usr/share/plymouth/themes/pix/splash.png + echo "βœ… Splash screen applied." else - echo "Error: No supported package manager (apt, dnf, pacman) found. Please install dependencies manually." - exit 1 + echo "⚠️ splash.png not found β€” skipping." fi -echo "Detected package manager: $PKG_MANAGER" +# --------------------------------------------------------- +# Step 4.5: Configure Plymouth to stay on screen longer +# --------------------------------------------------------- +echo "Step 4.5: Configuring splash screen timing..." -# --- Update System Packages --- -echo "Updating system packages..." -if [ "$PKG_MANAGER" == "apt" ]; then - sudo apt update - sudo DEBIAN_FRONTEND=noninteractive apt upgrade -y -o Dpkg::Options::="--force-confold" -elif [ "$PKG_MANAGER" == "dnf" ]; then - sudo dnf upgrade -y -elif [ "$PKG_MANAGER" == "pacman" ]; then - sudo pacman -Syu --noconfirm -fi -echo "System packages updated." +# Ensure 'quiet splash' is in /boot/cmdline.txt +sudo sed -i 's/\(\s*\)console=tty1/\1quiet splash console=tty1/' /boot/cmdline.txt +echo "βœ… Set 'quiet splash' in /boot/cmdline.txt" -# --- Install Rust/Cargo if not installed --- -if ! command -v cargo &> /dev/null; then - echo "Rust/Cargo not found. Installing Rustup..." - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - # Source cargo's env for the current shell session - # This is for the current script's execution path, typically rustup adds to .bashrc/.profile for future sessions. - # We need it now, but for non-interactive script, sourcing won't affect parent shell. - # However, cargo build below will rely on it being in PATH. rustup makes sure of this if it installs. - # For safety, ensure PATH is updated. - export PATH="$HOME/.cargo/bin:$PATH" - echo "Rust/Cargo installed successfully." -else - echo "Rust/Cargo is already installed." -fi - -# --- Install common build dependencies for Rust --- -echo "Installing common build dependencies..." -if [ "$PKG_MANAGER" == "apt" ]; then - sudo apt update - sudo apt install -y build-essential libudev-dev pkg-config curl wget -elif [ "$PKG_MANAGER" == "dnf" ]; then - sudo dnf install -y gcc make perl-devel libudev-devel pkg-config curl wget -elif [ "$PKG_MANAGER" == "pacman" ]; then - sudo pacman -Sy --noconfirm base-devel libudev pkg-config curl -fi -echo "Common build dependencies installed." - -# --- Install Python dependencies for testing --- -echo "🐍 Installing Python dependencies for test scripts..." -if [ "$PKG_MANAGER" == "apt" ]; then - # We no longer need hotspot dependencies - sudo apt install -y python3 python3-pip python3-serial -elif [ "$PKG_MANAGER" == "dnf" ]; then - # python3-pyserial is the name for pyserial in dnf - sudo dnf install -y python3 python3-pip python3-pyserial -elif [ "$PKG_MANAGER" == "pacman" ]; then - # python-pyserial is the name for pyserial in pacman - sudo pacman -Sy --noconfirm python python-pip python-pyserial -fi -# sudo pip3 install pyserial # This is replaced by the native package manager installs above -echo "βœ… Python dependencies installed." - -# --- Apply custom splash screen --- -if [[ "$(uname)" == "Linux" ]]; then - echo "πŸ–ΌοΈ Applying custom splash screen..." - SPLASH_URL="https://raw.githubusercontent.com/cjfranko/NTP-Timeturner/refs/heads/main/splash.png" - PLYMOUTH_THEME_DIR="/usr/share/plymouth/themes/pix" - PLYMOUTH_IMAGE_PATH="${PLYMOUTH_THEME_DIR}/splash.png" - - sudo mkdir -p "${PLYMOUTH_THEME_DIR}" - echo "Downloading splash image from ${SPLASH_URL}..." - sudo curl -L "${SPLASH_URL}" -o "${PLYMOUTH_IMAGE_PATH}" - - if [ -f "${PLYMOUTH_IMAGE_PATH}" ]; then - echo "Splash image downloaded. Updating Plymouth configuration..." - # Set 'pix' as the default plymouth theme if not already. - # This is a common theme that expects splash.png. - sudo update-alternatives --install /usr/share/plymouth/themes/default.plymouth default.plymouth "${PLYMOUTH_THEME_DIR}/pix.plymouth" 100 || true - # Ensure the pix theme exists and is linked - if [ ! -f "${PLYMOUTH_THEME_DIR}/pix.plymouth" ]; then - echo "Creating dummy pix.plymouth for update-initramfs" - echo "[Plymouth Theme]" | sudo tee "${PLYMOUTH_THEME_DIR}/pix.plymouth" > /dev/null - echo "Name=Pi Splash" | sudo tee -a "${PLYMOUTH_THEME_DIR}/pix.plymouth" > /dev/null - echo "Description=TimeTurner Raspberry Pi Splash Screen" | sudo tee -a "${PLYMOUTH_THEME_DIR}/pix.plymouth" > /dev/null - echo "SpriteAnimation=/splash.png" | sudo tee -a "${PLYMOUTH_THEME_DIR}/pix.plymouth" > /dev/null - fi - - # Update the initial RAM filesystem to include the new splash screen - sudo update-initramfs -u - echo "βœ… Custom splash screen applied. Reboot may be required to see changes." - else - echo "❌ Failed to download splash image from ${SPLASH_URL}." - fi -else - echo "⚠️ Skipping splash screen configuration on non-Linux OS." -fi - -# --- Remove NTPD and install Chrony, NMTUI, Adjtimex --- -echo "Removing NTPD (if installed) and installing Chrony, NMTUI, Adjtimex..." - -# --- Remove NTPD and install Chrony, NMTUI, Adjtimex --- -echo "Removing NTPD (if installed) and installing Chrony, NMTUI, Adjtimex..." - -if [ "$PKG_MANAGER" == "apt" ]; then - sudo apt update - sudo apt remove -y ntp || true # Remove ntp if it exists, ignore if not - sudo apt install -y chrony network-manager adjtimex - sudo systemctl enable chrony --now -elif [ "$PKG_MANAGER" == "dnf" ]; then - sudo dnf remove -y ntp - sudo dnf install -y chrony NetworkManager-tui adjtimex - sudo systemctl enable chronyd --now -elif [ "$PKG_MANAGER" == "pacman" ]; then - sudo pacman -Sy --noconfirm ntp || true - sudo pacman -R --noconfirm ntp || true # Ensure ntp is removed - sudo pacman -Sy --noconfirm chrony networkmanager adjtimex - sudo systemctl enable chronyd --now - sudo systemctl enable NetworkManager --now # nmtui relies on NetworkManager -fi - -echo "NTPD removed (if present). Chrony, NMTUI, and Adjtimex installed and configured." - -# --- Configure Chrony to act as a local NTP server --- -echo "βš™οΈ Configuring Chrony to serve local time..." -# The path to chrony.conf can vary -if [ -f /etc/chrony/chrony.conf ]; then - CHRONY_CONF="/etc/chrony/chrony.conf" -elif [ -f /etc/chrony.conf ]; then - CHRONY_CONF="/etc/chrony.conf" -else - CHRONY_CONF="" -fi - -if [ -n "$CHRONY_CONF" ]; then - # Comment out any existing pool, server, or sourcedir lines to prevent syncing with external sources - echo "Disabling external NTP sources..." - sudo sed -i -E 's/^(pool|server|sourcedir)/#&/' "$CHRONY_CONF" - - # Add settings to the top of the file to serve local clock - # Using a temp file to prepend is safer than multiple sed calls - TEMP_CONF=$(mktemp) - cat < "$TEMP_CONF" -# Serve the system clock as a reference at stratum 1 -server 127.127.1.0 -allow 127.0.0.0/8 -local stratum 1 +# Update Plymouth config +sudo sed -i 's/^Theme=.*/Theme=pix/' /etc/plymouth/plymouthd.conf +sudo sed -i 's/^ShowDelay=.*/ShowDelay=0/' /etc/plymouth/plymouthd.conf || echo "ShowDelay=0" | sudo tee -a /etc/plymouth/plymouthd.conf +sudo sed -i 's/^DeviceTimeout=.*/DeviceTimeout=10/' /etc/plymouth/plymouthd.conf || echo "DeviceTimeout=10" | sudo tee -a /etc/plymouth/plymouthd.conf +sudo sed -i 's/^DisableFadeIn=.*/DisableFadeIn=true/' /etc/plymouth/plymouthd.conf || echo "DisableFadeIn=true" | sudo tee -a /etc/plymouth/plymouthd.conf +echo "βœ… Updated /etc/plymouth/plymouthd.conf" +# Create autostart delay to keep splash visible until desktop is ready +mkdir -p "$HOME/.config/autostart" +cat << EOF > "$HOME/.config/autostart/delayed-plymouth-exit.desktop" +[Desktop Entry] +Type=Application +Name=Delayed Plymouth Exit +Exec=/bin/sh -c "sleep 3 && /usr/bin/plymouth quit" +X-GNOME-Autostart-enabled=true EOF - # Append the rest of the original config file after our new lines - cat "$CHRONY_CONF" >> "$TEMP_CONF" - sudo mv "$TEMP_CONF" "$CHRONY_CONF" +echo "βœ… Splash screen will exit 3 seconds after desktop starts" +# --------------------------------------------------------- +# Step 5: Download Teensy firmware +# --------------------------------------------------------- +echo "Step 5: Downloading Teensy firmware..." +cd "$HOME" +wget -O ltc_audiohat_lock.ino.hex https://raw.githubusercontent.com/cjfranko/NTP-Timeturner/master/firmware/ltc_audiohat_lock.ino.hex - # Add settings to the bottom of the file to allow LAN clients - echo "Allowing LAN clients..." - sudo tee -a "$CHRONY_CONF" > /dev/null <, - hardware_offset_ms: i64, -} - -// AppState to hold shared data -pub struct AppState { - pub ltc_state: Arc>, - pub config: Arc>, - pub log_buffer: Arc>>, -} - -#[get("/api/status")] -async fn get_status(data: web::Data) -> impl Responder { - let state = data.ltc_state.lock().unwrap(); - let config = data.config.lock().unwrap(); - let hw_offset_ms = config.hardware_offset_ms; - - let ltc_status = state.latest.as_ref().map_or("(waiting)".to_string(), |f| f.status.clone()); - let ltc_timecode = state.latest.as_ref().map_or("…".to_string(), |f| { - let sep = if f.is_drop_frame { ';' } else { ':' }; - format!( - "{:02}:{:02}:{:02}{}{:02}", - f.hours, f.minutes, f.seconds, sep, f.frames - ) - }); - let frame_rate = state.latest.as_ref().map_or("…".to_string(), |f| { - format!("{:.2}fps", f.frame_rate.to_f64().unwrap_or(0.0)) - }); - - let now_local = Local::now(); - let system_clock = format!( - "{:02}:{:02}:{:02}.{:03}", - now_local.hour(), - now_local.minute(), - now_local.second(), - now_local.timestamp_subsec_millis(), - ); - let system_date = now_local.format("%Y-%m-%d").to_string(); - - let avg_delta = state.get_ewma_clock_delta(); - let mut delta_frames = 0; - if let Some(frame) = &state.latest { - let delta_ms_ratio = Ratio::new(avg_delta, 1); - let frames_ratio = delta_ms_ratio * frame.frame_rate / Ratio::new(1000, 1); - delta_frames = frames_ratio.round().to_integer(); - } - - let sync_status = sync_logic::get_sync_status(avg_delta, &config); - let jitter_status = sync_logic::get_jitter_status(state.average_jitter()); - let lock_ratio = state.lock_ratio(); - - let ntp_active = system::ntp_service_active(); - let interfaces = get_if_addrs() - .unwrap_or_default() - .into_iter() - .filter(|ifa| !ifa.is_loopback()) - .map(|ifa| ifa.ip().to_string()) - .collect(); - - HttpResponse::Ok().json(ApiStatus { - ltc_status, - ltc_timecode, - frame_rate, - system_clock, - system_date, - timecode_delta_ms: avg_delta, - timecode_delta_frames: delta_frames, - sync_status: sync_status.to_string(), - jitter_status: jitter_status.to_string(), - lock_ratio, - ntp_active, - interfaces, - hardware_offset_ms: hw_offset_ms, - }) -} - -#[post("/api/sync")] -async fn manual_sync(data: web::Data) -> impl Responder { - let state = data.ltc_state.lock().unwrap(); - let config = data.config.lock().unwrap(); - if let Some(frame) = &state.latest { - if system::trigger_sync(frame, &config).is_ok() { - HttpResponse::Ok().json(serde_json::json!({ "status": "success", "message": "Sync command issued." })) - } else { - HttpResponse::InternalServerError().json(serde_json::json!({ "status": "error", "message": "Sync command failed." })) - } - } else { - HttpResponse::BadRequest().json(serde_json::json!({ "status": "error", "message": "No LTC timecode available to sync to." })) - } -} - -#[get("/api/config")] -async fn get_config(data: web::Data) -> impl Responder { - let config = data.config.lock().unwrap(); - HttpResponse::Ok().json(&*config) -} - -#[get("/api/logs")] -async fn get_logs(data: web::Data) -> impl Responder { - let logs = data.log_buffer.lock().unwrap(); - HttpResponse::Ok().json(&*logs) -} - -#[derive(Deserialize)] -struct NudgeRequest { - microseconds: i64, -} - -#[post("/api/nudge_clock")] -async fn nudge_clock(req: web::Json) -> impl Responder { - if system::nudge_clock(req.microseconds).is_ok() { - HttpResponse::Ok().json(serde_json::json!({ "status": "success", "message": "Clock nudge command issued." })) - } else { - HttpResponse::InternalServerError().json(serde_json::json!({ "status": "error", "message": "Clock nudge command failed." })) - } -} - -#[derive(Deserialize)] -struct SetDateRequest { - date: String, -} - -#[post("/api/set_date")] -async fn set_date(req: web::Json) -> impl Responder { - if system::set_date(&req.date).is_ok() { - HttpResponse::Ok() - .json(serde_json::json!({ "status": "success", "message": "Date update command issued." })) - } else { - HttpResponse::InternalServerError() - .json(serde_json::json!({ "status": "error", "message": "Date update command failed." })) - } -} - -#[post("/api/config")] -async fn update_config( - data: web::Data, - req: web::Json, -) -> impl Responder { - let mut config = data.config.lock().unwrap(); - *config = req.into_inner(); - - if config::save_config("config.yml", &config).is_ok() { - log::info!("πŸ”„ Saved config via API: {:?}", *config); - - // If timeturner offset is active, trigger a sync immediately. - if config.timeturner_offset.is_active() { - let state = data.ltc_state.lock().unwrap(); - if let Some(frame) = &state.latest { - log::info!("Timeturner offset is active, triggering sync..."); - if system::trigger_sync(frame, &config).is_ok() { - log::info!("Sync triggered successfully after config change."); - } else { - log::error!("Sync failed after config change."); - } - } else { - log::warn!("Timeturner offset is active, but no LTC frame available to sync."); - } - } - - HttpResponse::Ok().json(&*config) - } else { - log::error!("Failed to write config.yml"); - HttpResponse::InternalServerError().json( - serde_json::json!({ "status": "error", "message": "Failed to write config.yml" }), - ) - } -} - -pub async fn start_api_server( - state: Arc>, - config: Arc>, - log_buffer: Arc>>, -) -> std::io::Result<()> { - let app_state = web::Data::new(AppState { - ltc_state: state, - config: config, - log_buffer: log_buffer, - }); - - log::info!("πŸš€ Starting API server at http://0.0.0.0:8080"); - - HttpServer::new(move || { - App::new() - .app_data(app_state.clone()) - .service(get_status) - .service(manual_sync) - .service(get_config) - .service(update_config) - .service(get_logs) - .service(nudge_clock) - .service(set_date) - // Serve frontend static files - .service(fs::Files::new("/", "static/").index_file("index.html")) - }) - .bind("0.0.0.0:8080")? - .run() - .await -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::config::TimeturnerOffset; - use crate::sync_logic::LtcFrame; - use actix_web::{test, App}; - use chrono::Utc; - use std::collections::VecDeque; - use std::fs; - - // Helper to create a default LtcState for tests - fn get_test_ltc_state() -> LtcState { - LtcState { - latest: Some(LtcFrame { - status: "LOCK".to_string(), - hours: 1, - minutes: 2, - seconds: 3, - frames: 4, - is_drop_frame: false, - frame_rate: Ratio::new(25, 1), - timestamp: Utc::now(), - }), - lock_count: 10, - free_count: 1, - offset_history: VecDeque::from(vec![1, 2, 3]), - ewma_clock_delta: Some(5.0), - last_match_status: "IN SYNC".to_string(), - last_match_check: Utc::now().timestamp(), - } - } - - // Helper to create a default AppState for tests - fn get_test_app_state() -> web::Data { - let ltc_state = Arc::new(Mutex::new(get_test_ltc_state())); - let config = Arc::new(Mutex::new(Config { - hardware_offset_ms: 10, - timeturner_offset: TimeturnerOffset::default(), - default_nudge_ms: 2, - auto_sync_enabled: false, - })); - let log_buffer = Arc::new(Mutex::new(VecDeque::new())); - web::Data::new(AppState { - ltc_state, - config, - log_buffer, - }) - } - - #[actix_web::test] - async fn test_get_status() { - let app_state = get_test_app_state(); - let app = test::init_service( - App::new() - .app_data(app_state.clone()) - .service(get_status), - ) - .await; - - let req = test::TestRequest::get().uri("/api/status").to_request(); - let resp: ApiStatus = test::call_and_read_body_json(&app, req).await; - - assert_eq!(resp.ltc_status, "LOCK"); - assert_eq!(resp.ltc_timecode, "01:02:03:04"); - assert_eq!(resp.frame_rate, "25.00fps"); - assert_eq!(resp.hardware_offset_ms, 10); - } - - #[actix_web::test] - async fn test_get_status_drop_frame() { - let app_state = get_test_app_state(); - // Set state to drop frame - app_state - .ltc_state - .lock() - .unwrap() - .latest - .as_mut() - .unwrap() - .is_drop_frame = true; - - let app = test::init_service( - App::new() - .app_data(app_state.clone()) - .service(get_status), - ) - .await; - - let req = test::TestRequest::get().uri("/api/status").to_request(); - let resp: ApiStatus = test::call_and_read_body_json(&app, req).await; - - assert_eq!(resp.ltc_timecode, "01:02:03;04"); - } - - #[actix_web::test] - async fn test_get_config() { - let app_state = get_test_app_state(); - app_state.config.lock().unwrap().hardware_offset_ms = 25; - - let app = test::init_service( - App::new() - .app_data(app_state.clone()) - .service(get_config), - ) - .await; - - let req = test::TestRequest::get().uri("/api/config").to_request(); - let resp: Config = test::call_and_read_body_json(&app, req).await; - - assert_eq!(resp.hardware_offset_ms, 25); - } - - #[actix_web::test] - async fn test_update_config() { - let app_state = get_test_app_state(); - let config_path = "config.yml"; - - // This test has the side effect of writing to `config.yml`. - // We ensure it's cleaned up after. - let _ = fs::remove_file(config_path); - - let app = test::init_service( - App::new() - .app_data(app_state.clone()) - .service(update_config), - ) - .await; - - let new_config_json = serde_json::json!({ - "hardwareOffsetMs": 55, - "defaultNudgeMs": 2, - "autoSyncEnabled": true, - "timeturnerOffset": { "hours": 1, "minutes": 2, "seconds": 3, "frames": 4, "milliseconds": 5 } - }); - - let req = test::TestRequest::post() - .uri("/api/config") - .set_json(&new_config_json) - .to_request(); - - let resp: Config = test::call_and_read_body_json(&app, req).await; - - assert_eq!(resp.hardware_offset_ms, 55); - assert_eq!(resp.auto_sync_enabled, true); - assert_eq!(resp.timeturner_offset.hours, 1); - assert_eq!(resp.timeturner_offset.milliseconds, 5); - let final_config = app_state.config.lock().unwrap(); - assert_eq!(final_config.hardware_offset_ms, 55); - assert_eq!(final_config.auto_sync_enabled, true); - assert_eq!(final_config.timeturner_offset.hours, 1); - assert_eq!(final_config.timeturner_offset.milliseconds, 5); - - // Test that the file was written - assert!(fs::metadata(config_path).is_ok()); - let contents = fs::read_to_string(config_path).unwrap(); - assert!(contents.contains("hardwareOffsetMs: 55")); - assert!(contents.contains("autoSyncEnabled: true")); - assert!(contents.contains("hours: 1")); - assert!(contents.contains("milliseconds: 5")); - - // Cleanup - let _ = fs::remove_file(config_path); - } - - #[actix_web::test] - async fn test_manual_sync_no_ltc() { - let app_state = get_test_app_state(); - // State with no LTC frame - app_state.ltc_state.lock().unwrap().latest = None; - - let app = test::init_service( - App::new() - .app_data(app_state.clone()) - .service(manual_sync), - ) - .await; - - let req = test::TestRequest::post().uri("/api/sync").to_request(); - let resp = test::call_service(&app, req).await; - - assert_eq!(resp.status(), 400); // Bad Request - } -} diff --git a/src/config.rs b/src/config.rs index 8669e62..a9bf931 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,138 +1,69 @@ -ο»Ώ// src/config.rs -use notify::{ - recommended_watcher, Event, EventKind, RecommendedWatcher, RecursiveMode, Result as NotifyResult, - Watcher, -}; -use serde::{Deserialize, Serialize}; -use std::{ - fs, - fs::File, - io::Read, - path::PathBuf, - sync::{Arc, Mutex}, -}; - -#[derive(Deserialize, Serialize, Clone, Debug, Default)] -#[serde(rename_all = "camelCase")] -pub struct TimeturnerOffset { - pub hours: i64, - pub minutes: i64, - pub seconds: i64, - pub frames: i64, - #[serde(default)] - pub milliseconds: i64, -} - -impl TimeturnerOffset { - pub fn is_active(&self) -> bool { - self.hours != 0 - || self.minutes != 0 - || self.seconds != 0 - || self.frames != 0 - || self.milliseconds != 0 - } -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct Config { - pub hardware_offset_ms: i64, - #[serde(default)] - pub timeturner_offset: TimeturnerOffset, - #[serde(default = "default_nudge_ms")] - pub default_nudge_ms: i64, - #[serde(default)] - pub auto_sync_enabled: bool, -} - -fn default_nudge_ms() -> i64 { - 2 // Default nudge is 2ms -} - -impl Config { - pub fn load(path: &PathBuf) -> Self { - let mut file = match File::open(path) { - Ok(f) => f, - Err(_) => return Self::default(), - }; - let mut contents = String::new(); - if file.read_to_string(&mut contents).is_err() { - return Self::default(); - } - serde_yaml::from_str(&contents).unwrap_or_else(|e| { - log::warn!("Failed to parse config, using default: {}", e); - Self::default() - }) - } - -} - -impl Default for Config { - fn default() -> Self { - Self { - hardware_offset_ms: 0, - timeturner_offset: TimeturnerOffset::default(), - default_nudge_ms: default_nudge_ms(), - auto_sync_enabled: false, - } - } -} - -pub fn save_config(path: &str, config: &Config) -> Result<(), Box> { - let mut s = String::new(); - s.push_str("# Hardware offset in milliseconds for correcting capture latency.\n"); - s.push_str(&format!("hardwareOffsetMs: {}\n\n", config.hardware_offset_ms)); - - s.push_str("# Enable automatic clock synchronization.\n"); - s.push_str("# When enabled, the system will perform an initial full sync, then periodically\n"); - s.push_str("# nudge the clock to keep it aligned with the LTC source.\n"); - s.push_str(&format!("autoSyncEnabled: {}\n\n", config.auto_sync_enabled)); - - s.push_str("# Default nudge in milliseconds for adjtimex control.\n"); - s.push_str(&format!("defaultNudgeMs: {}\n\n", config.default_nudge_ms)); - - s.push_str("# Time-turning offsets. All values are added to the incoming LTC time.\n"); - s.push_str("# These can be positive or negative.\n"); - s.push_str("timeturnerOffset:\n"); - s.push_str(&format!(" hours: {}\n", config.timeturner_offset.hours)); - s.push_str(&format!(" minutes: {}\n", config.timeturner_offset.minutes)); - s.push_str(&format!(" seconds: {}\n", config.timeturner_offset.seconds)); - s.push_str(&format!(" frames: {}\n", config.timeturner_offset.frames)); - s.push_str(&format!(" milliseconds: {}\n", config.timeturner_offset.milliseconds)); - - fs::write(path, s)?; - Ok(()) -} - -pub fn watch_config(path: &str) -> Arc> { - let initial_config = Config::load(&PathBuf::from(path)); - let config = Arc::new(Mutex::new(initial_config)); - - let watch_path = PathBuf::from(path); - let watch_path_for_cb = watch_path.clone(); - let config_for_cb = Arc::clone(&config); - - std::thread::spawn(move || { - let mut watcher: RecommendedWatcher = recommended_watcher(move |res: NotifyResult| { - if let Ok(evt) = res { - if matches!(evt.kind, EventKind::Modify(_)) { - let new_cfg = Config::load(&watch_path_for_cb); - let mut cfg = config_for_cb.lock().unwrap(); - *cfg = new_cfg; - log::info!("πŸ”„ Reloaded config.yml: {:?}", *cfg); - } - } - }) - .expect("Failed to create file watcher"); - - watcher - .watch(&watch_path, RecursiveMode::NonRecursive) - .expect("Failed to watch config.yml"); - - loop { - std::thread::sleep(std::time::Duration::from_secs(60)); - } - }); - - config -} +ο»Ώ// src/config.rs + +use notify::{ + recommended_watcher, Event, EventKind, RecommendedWatcher, RecursiveMode, Result as NotifyResult, + Watcher, +}; +use serde::Deserialize; +use std::{ + fs::File, + io::Read, + path::PathBuf, + sync::{Arc, Mutex}, +}; + +#[derive(Deserialize)] +pub struct Config { + pub hardware_offset_ms: i64, +} + +impl Config { + pub fn load(path: &PathBuf) -> Self { + let mut file = match File::open(path) { + Ok(f) => f, + Err(_) => return Self { hardware_offset_ms: 0 }, + }; + let mut contents = String::new(); + if file.read_to_string(&mut contents).is_err() { + return Self { hardware_offset_ms: 0 }; + } + serde_json::from_str(&contents).unwrap_or(Self { hardware_offset_ms: 0 }) + } +} + +pub fn watch_config(path: &str) -> Arc> { + let initial = Config::load(&PathBuf::from(path)).hardware_offset_ms; + let offset = Arc::new(Mutex::new(initial)); + + // Owned PathBuf for watch() call + let watch_path = PathBuf::from(path); + // Clone for moving into the closure + let watch_path_for_cb = watch_path.clone(); + let offset_for_cb = Arc::clone(&offset); + + std::thread::spawn(move || { + // Move `watch_path_for_cb` into the callback + let mut watcher: RecommendedWatcher = recommended_watcher(move |res: NotifyResult| { + if let Ok(evt) = res { + if matches!(evt.kind, EventKind::Modify(_)) { + let new_cfg = Config::load(&watch_path_for_cb); + let mut hw = offset_for_cb.lock().unwrap(); + *hw = new_cfg.hardware_offset_ms; + eprintln!("πŸ”„ Reloaded hardware_offset_ms = {}", *hw); + } + } + }) + .expect("Failed to create file watcher"); + + // Use the original `watch_path` here + watcher + .watch(&watch_path, RecursiveMode::NonRecursive) + .expect("Failed to watch config.json"); + + loop { + std::thread::sleep(std::time::Duration::from_secs(60)); + } + }); + + offset +} diff --git a/src/logger.rs b/src/logger.rs deleted file mode 100644 index 33c410e..0000000 --- a/src/logger.rs +++ /dev/null @@ -1,52 +0,0 @@ -use chrono::Local; -use log::{LevelFilter, Log, Metadata, Record}; -use std::collections::VecDeque; -use std::sync::{Arc, Mutex}; - -const MAX_LOG_ENTRIES: usize = 100; - -struct RingBufferLogger { - buffer: Arc>>, -} - -impl Log for RingBufferLogger { - fn enabled(&self, metadata: &Metadata) -> bool { - metadata.level() <= LevelFilter::Info - } - - fn log(&self, record: &Record) { - if self.enabled(record.metadata()) { - let msg = format!( - "{} [{}] {}", - Local::now().format("%Y-%m-%d %H:%M:%S"), - record.level(), - record.args() - ); - - // Also print to stderr for console/daemon logging - eprintln!("{}", msg); - - let mut buffer = self.buffer.lock().unwrap(); - if buffer.len() == MAX_LOG_ENTRIES { - buffer.pop_front(); - } - buffer.push_back(msg); - } - } - - fn flush(&self) {} -} - -pub fn setup_logger() -> Arc>> { - let buffer = Arc::new(Mutex::new(VecDeque::with_capacity(MAX_LOG_ENTRIES))); - let logger = RingBufferLogger { - buffer: buffer.clone(), - }; - - // We use `set_boxed_logger` to install our custom logger. - // The `log` crate will then route all log messages to it. - log::set_boxed_logger(Box::new(logger)).expect("Failed to set logger"); - log::set_max_level(LevelFilter::Info); - - buffer -} diff --git a/src/main.rs b/src/main.rs index 8006681..2464a0e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,402 +1,81 @@ -ο»Ώ// src/main.rs - -mod api; -mod config; -mod logger; -mod serial_input; -mod sync_logic; -mod system; -mod ui; - -use crate::api::start_api_server; -use crate::config::watch_config; -use crate::serial_input::start_serial_thread; -use crate::sync_logic::LtcState; -use crate::ui::start_ui; -use clap::Parser; -use daemonize::Daemonize; -use serialport; - -use std::{ - fs, - path::Path, - sync::{mpsc, Arc, Mutex}, - thread, -}; -use tokio::task::{self, LocalSet}; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - #[command(subcommand)] - command: Option, -} - -#[derive(clap::Subcommand, Debug)] -enum Command { - /// Run as a background daemon providing a web UI. - Daemon, - /// Stop the running daemon process. - Kill, -} - -/// Default config content, embedded in the binary. -const DEFAULT_CONFIG: &str = r#" -# Hardware offset in milliseconds for correcting capture latency. -hardwareOffsetMs: 20 - -# Enable automatic clock synchronization. -# When enabled, the system will perform an initial full sync, then periodically -# nudge the clock to keep it aligned with the LTC source. -autoSyncEnabled: false - -# Default nudge in milliseconds for adjtimex control. -defaultNudgeMs: 2 - -# Time-turning offsets. All values are added to the incoming LTC time. -# These can be positive or negative. -timeturnerOffset: - hours: 0 - minutes: 0 - seconds: 0 - frames: 0 - milliseconds: 0 -"#; - -/// If no `config.yml` exists alongside the binary, write out the default. -fn ensure_config() { - let p = Path::new("config.yml"); - if !p.exists() { - fs::write(p, DEFAULT_CONFIG.trim()) - .expect("Failed to write default config.yml"); - log::info!("βš™οΈ Emitted default config.yml"); - } -} - -fn find_serial_port() -> Option { - if let Ok(ports) = serialport::available_ports() { - for p in ports { - if p.port_name.starts_with("/dev/ttyACM") - || p.port_name.starts_with("/dev/ttyAMA") - || p.port_name.starts_with("/dev/ttyUSB") - { - return Some(p.port_name); - } - } - } - None -} - -#[tokio::main(flavor = "current_thread")] -async fn main() { - // This must be called before any logging statements. - let log_buffer = logger::setup_logger(); - let args = Args::parse(); - - if let Some(command) = &args.command { - match command { - Command::Daemon => { - log::info!("πŸš€ Starting daemon..."); - - // Create files for stdout and stderr in the current directory - let stdout = - fs::File::create("daemon.out").expect("Could not create daemon.out"); - let stderr = - fs::File::create("daemon.err").expect("Could not create daemon.err"); - - let daemonize = Daemonize::new() - .pid_file("ntp_timeturner.pid") // Create a PID file - .working_directory(".") // Keep the same working directory - .stdout(stdout) - .stderr(stderr); - - match daemonize.start() { - Ok(_) => { /* Process is now daemonized */ } - Err(e) => { - log::error!("Error daemonizing: {}", e); - return; // Exit if daemonization fails - } - } - } - Command::Kill => { - log::info!("πŸ›‘ Stopping daemon..."); - let pid_file = "ntp_timeturner.pid"; - match fs::read_to_string(pid_file) { - Ok(pid_str) => { - let pid_str = pid_str.trim(); - log::info!("Found daemon with PID: {}", pid_str); - match std::process::Command::new("kill").arg("-9").arg(format!("-{}", pid_str)).status() { - Ok(status) => { - if status.success() { - log::info!("βœ… Daemon stopped successfully."); - if fs::remove_file(pid_file).is_err() { - log::warn!("Could not remove PID file '{}'. It may need to be removed manually.", pid_file); - } - } else { - log::error!("'kill' command failed with status: {}. The daemon may not be running, or you may not have permission to stop it.", status); - log::warn!("Attempting to remove stale PID file '{}'...", pid_file); - if fs::remove_file(pid_file).is_ok() { - log::info!("Removed stale PID file."); - } else { - log::warn!("Could not remove PID file."); - } - } - } - Err(e) => { - log::error!("Failed to execute 'kill' command. Is 'kill' in your PATH? Error: {}", e); - } - } - } - Err(_) => { - log::error!("Could not read PID file '{}'. Is the daemon running in this directory?", pid_file); - } - } - return; - } - } - } - - // πŸ”„ Ensure there's always a config.yml present - ensure_config(); - - // 1️⃣ Start watching config.yml for changes - let config = watch_config("config.yml"); - - // 2️⃣ Channel for raw LTC frames - let (tx, rx) = mpsc::channel(); - - // 3️⃣ Shared state for UI and serial reader - let ltc_state = Arc::new(Mutex::new(LtcState::new())); - - // 4️⃣ Find serial port and spawn the serial reader thread - let serial_port_path = match find_serial_port() { - Some(port) => port, - None => { - log::error!("❌ No serial port found. Please connect the Teensy device."); - return; - } - }; - log::info!("Found serial port: {}", serial_port_path); - - { - let tx_clone = tx.clone(); - let state_clone = ltc_state.clone(); - let port_clone = serial_port_path.clone(); - thread::spawn(move || { - start_serial_thread( - &port_clone, - 115200, - tx_clone, - state_clone, - 0, // ignored in serial path - ); - }); - } - - // 5️⃣ Spawn UI or setup daemon logging. The web service is only started - // when running as a daemon. The TUI is for interactive foreground use. - if args.command.is_none() { - // --- Interactive TUI Mode --- - log::info!("πŸ”§ Watching config.yml..."); - log::info!("πŸš€ Serial thread launched"); - log::info!("πŸ–₯️ UI thread launched"); - let ui_state = ltc_state.clone(); - let config_clone = config.clone(); - let port = serial_port_path; - thread::spawn(move || { - start_ui(ui_state, port, config_clone); - }); - } else { - // --- Daemon Mode --- - // In daemon mode, logging is already set up to go to stderr. - // The systemd service will capture it. The web service (API and static files) - // is launched later in the main async block. - log::info!("πŸš€ Starting TimeTurner daemon..."); - } - - // 6️⃣ Spawn the auto-sync thread - { - let sync_state = ltc_state.clone(); - let sync_config = config.clone(); - thread::spawn(move || { - // Wait for the first LTC frame to arrive - loop { - if sync_state.lock().unwrap().latest.is_some() { - log::info!("Auto-sync: Initial LTC frame detected."); - break; - } - thread::sleep(std::time::Duration::from_secs(1)); - } - - // Initial sync - { - let state = sync_state.lock().unwrap(); - let config = sync_config.lock().unwrap(); - if config.auto_sync_enabled { - if let Some(frame) = &state.latest { - log::info!("Auto-sync: Performing initial full sync."); - if system::trigger_sync(frame, &config).is_ok() { - log::info!("Auto-sync: Initial sync successful."); - } else { - log::error!("Auto-sync: Initial sync failed."); - } - } - } - } - - thread::sleep(std::time::Duration::from_secs(10)); - - // Main auto-sync loop - loop { - { - let state = sync_state.lock().unwrap(); - let config = sync_config.lock().unwrap(); - - if config.auto_sync_enabled && state.latest.is_some() { - let delta = state.get_ewma_clock_delta(); - let frame = state.latest.as_ref().unwrap(); - - if delta.abs() > 40 { - log::info!("Auto-sync: Delta > 40ms ({}ms), performing full sync.", delta); - if system::trigger_sync(frame, &config).is_ok() { - log::info!("Auto-sync: Full sync successful."); - } else { - log::error!("Auto-sync: Full sync failed."); - } - } else if delta.abs() >= 1 { - // nudge_clock takes microseconds. A positive delta means clock is - // ahead, so we need a negative nudge. - let nudge_us = -delta * 1000; - log::info!("Auto-sync: Delta is {}ms, nudging clock by {}us.", delta, nudge_us); - if system::nudge_clock(nudge_us).is_ok() { - log::info!("Auto-sync: Clock nudge successful."); - } else { - log::error!("Auto-sync: Clock nudge failed."); - } - } - } - } // locks released here - - thread::sleep(std::time::Duration::from_secs(10)); - } - }); - } - - // 7️⃣ Set up a LocalSet for the API server and main loop - let local = LocalSet::new(); - local - .run_until(async move { - // 8️⃣ Spawn the API server task. - // This server provides the JSON API and serves the static web UI files - // from the `static/` directory. It runs in both TUI and daemon modes, - // but is primarily for the web UI used in daemon mode. - { - let api_state = ltc_state.clone(); - let config_clone = config.clone(); - let log_buffer_clone = log_buffer.clone(); - task::spawn_local(async move { - if let Err(e) = - start_api_server(api_state, config_clone, log_buffer_clone).await - { - log::error!("API server error: {}", e); - } - }); - } - - // 9️⃣ Main logic loop: process frames from serial and update state - let loop_state = ltc_state.clone(); - let loop_config = config.clone(); - let logic_task = task::spawn_blocking(move || { - for frame in rx { - let mut state = loop_state.lock().unwrap(); - let config = loop_config.lock().unwrap(); - - // Only calculate delta for LOCK frames - if frame.status == "LOCK" { - let target_time = system::calculate_target_time(&frame, &config); - let arrival_time_local: chrono::DateTime = - frame.timestamp.with_timezone(&chrono::Local); - let delta = arrival_time_local.signed_duration_since(target_time); - state.record_and_update_ewma_clock_delta(delta.num_milliseconds()); - } - - state.update(frame); - } - }); - - // 1️⃣0️⃣ Keep main thread alive - if args.command.is_some() { - // In daemon mode, wait forever. The logic_task runs in the background. - std::future::pending::<()>().await; - } else { - // In TUI mode, block until the logic_task finishes (e.g. serial port disconnects) - // This keeps the TUI running. - log::info!("πŸ“‘ Main thread entering loop..."); - let _ = logic_task.await; - } - }) - .await; -} - -#[cfg(test)] -mod tests { - use super::*; - use std::fs; - use std::path::Path; - - /// RAII guard to manage config file during tests. - /// It saves the original content of `config.yml` if it exists, - /// and restores it when the guard goes out of scope. - /// If the file didn't exist, it's removed. - struct ConfigGuard { - original_content: Option, - } - - impl ConfigGuard { - fn new() -> Self { - Self { - original_content: fs::read_to_string("config.yml").ok(), - } - } - } - - impl Drop for ConfigGuard { - fn drop(&mut self) { - if let Some(content) = &self.original_content { - fs::write("config.yml", content).expect("Failed to restore config.yml"); - } else { - let _ = fs::remove_file("config.yml"); - } - } - } - - #[test] - fn test_ensure_config() { - let _guard = ConfigGuard::new(); // Cleanup when _guard goes out of scope. - - // --- Test 1: File creation --- - // Pre-condition: config.yml does not exist. - let _ = fs::remove_file("config.yml"); - - ensure_config(); - - // Post-condition: config.yml exists and has default content. - let p = Path::new("config.yml"); - assert!(p.exists(), "config.yml should have been created"); - let contents = fs::read_to_string(p).expect("Failed to read created config.yml"); - assert_eq!(contents, DEFAULT_CONFIG.trim(), "config.yml content should match default"); - - // --- Test 2: File is not overwritten --- - // Pre-condition: config.yml exists with different content. - let custom_content = "hardwareOffsetMs: 999"; - fs::write("config.yml", custom_content) - .expect("Failed to write custom config.yml for test"); - - ensure_config(); - - // Post-condition: config.yml still has the custom content. - let contents_after = fs::read_to_string("config.yml") - .expect("Failed to read config.yml after second ensure_config call"); - assert_eq!(contents_after, custom_content, "config.yml should not be overwritten"); - } -} +ο»Ώ// src/main.rs + +mod config; +mod sync_logic; +mod serial_input; +mod ui; + +use crate::config::watch_config; +use crate::sync_logic::LtcState; +use crate::serial_input::start_serial_thread; +use crate::ui::start_ui; + +use std::{ + fs, + path::Path, + sync::{Arc, Mutex, mpsc}, + thread, +}; + +/// Embed the default config.json at compile time. +const DEFAULT_CONFIG: &str = include_str!("../config.json"); + +/// If no `config.json` exists alongside the binary, write out the default. +fn ensure_config() { + let p = Path::new("config.json"); + if !p.exists() { + fs::write(p, DEFAULT_CONFIG) + .expect("Failed to write default config.json"); + eprintln!("βš™οΈ Emitted default config.json"); + } +} + +fn main() { + // πŸ”„ Ensure there's always a config.json present + ensure_config(); + + // 1️⃣ Start watching config.json for changes + let hw_offset = watch_config("config.json"); + println!("πŸ”§ Watching config.json (hardware_offset_ms)..."); + + // 2️⃣ Channel for raw LTC frames + let (tx, rx) = mpsc::channel(); + println!("βœ… Channel created"); + + // 3️⃣ Shared state for UI and serial reader + let ltc_state = Arc::new(Mutex::new(LtcState::new())); + println!("βœ… State initialised"); + + // 4️⃣ Spawn the serial reader thread (no offset here) + { + let tx_clone = tx.clone(); + let state_clone = ltc_state.clone(); + thread::spawn(move || { + println!("πŸš€ Serial thread launched"); + start_serial_thread( + "/dev/ttyACM0", + 115200, + tx_clone, + state_clone, + 0, // ignored in serial path + ); + }); + } + + // 5️⃣ Spawn the UI renderer thread, passing the live offset Arc + { + let ui_state = ltc_state.clone(); + let offset_clone = hw_offset.clone(); + let port = "/dev/ttyACM0".to_string(); + thread::spawn(move || { + println!("πŸ–₯️ UI thread launched"); + start_ui(ui_state, port, offset_clone); + }); + } + + // 6️⃣ Keep main thread alive + println!("πŸ“‘ Main thread entering loop..."); + for _frame in rx { + // no-op + } +} diff --git a/src/serial_input.rs b/src/serial_input.rs index d1dea36..39e2be7 100644 --- a/src/serial_input.rs +++ b/src/serial_input.rs @@ -1,178 +1,56 @@ -ο»Ώ// src/serial_input.rs - -use std::io::BufRead; -use std::sync::{Arc, Mutex}; -use std::sync::mpsc::Sender; -use chrono::Utc; -use regex::Regex; -use crate::sync_logic::{LtcFrame, LtcState}; - -pub fn start_serial_thread( - port_path: &str, - baud_rate: u32, - sender: Sender, - state: Arc>, - _hardware_offset_ms: i64, // no longer used here -) { - println!("πŸ“‘ Opening serial port {} @ {} baud", port_path, baud_rate); - - let port = match serialport::new(port_path, baud_rate) - .timeout(std::time::Duration::from_millis(1000)) - .open() - { - Ok(p) => { - println!("βœ… Serial port opened"); - p - } - Err(e) => { - eprintln!("❌ Serial open failed: {}", e); - return; - } - }; - - let reader = std::io::BufReader::new(port); - let re = Regex::new( - r"\[(LOCK|FREE)\]\s+(\d{2}):(\d{2}):(\d{2})([:;])(\d{2})\s+\|\s+([\d.]+)fps", - ) - .unwrap(); - - println!("πŸ”„ Entering LTC read loop…"); - for line in reader.lines() { - if let Ok(text) = line { - if let Some(caps) = re.captures(&text) { - let arrival = Utc::now(); - if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { - // update LOCK/FREE counts & timestamp - { - let mut st = state.lock().unwrap(); - st.update(frame.clone()); - } - // forward raw frame - let _ = sender.send(frame); - } - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::sync::mpsc; - use crate::sync_logic::LtcState; - use num_rational::Ratio; - use regex::Regex; - - fn get_ltc_regex() -> Regex { - Regex::new( - r"\[(LOCK|FREE)\]\s+(\d{2}):(\d{2}):(\d{2})([:;])(\d{2})\s+\|\s+([\d.]+)fps", - ).unwrap() - } - - #[test] - fn test_process_lock_line() { - let (tx, rx) = mpsc::channel(); - let state = Arc::new(Mutex::new(LtcState::new())); - let re = get_ltc_regex(); - let line = "[LOCK] 10:20:30:00 | 25.00fps"; - - // Simulate the processing logic from start_serial_thread - if let Some(caps) = re.captures(line) { - let arrival = Utc::now(); - if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { - { - let mut st = state.lock().unwrap(); - st.update(frame.clone()); - } - let _ = tx.send(frame); - } - } - - let st = state.lock().unwrap(); - assert_eq!(st.lock_count, 1); - assert_eq!(st.free_count, 0); - let received_frame = rx.try_recv().unwrap(); - assert_eq!(received_frame.status, "LOCK"); - assert_eq!(received_frame.hours, 10); - } - - #[test] - fn test_process_free_line() { - let (tx, rx) = mpsc::channel(); - let state = Arc::new(Mutex::new(LtcState::new())); - let re = get_ltc_regex(); - let line = "[FREE] 01:02:03:04 | 29.97fps"; - - // Simulate the processing logic - if let Some(caps) = re.captures(line) { - let arrival = Utc::now(); - if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { - { - let mut st = state.lock().unwrap(); - st.update(frame.clone()); - } - let _ = tx.send(frame); - } - } - - let st = state.lock().unwrap(); - assert_eq!(st.lock_count, 0); - assert_eq!(st.free_count, 1); - let received_frame = rx.try_recv().unwrap(); - assert_eq!(received_frame.status, "FREE"); - assert_eq!(received_frame.frame_rate, Ratio::new(30000, 1001)); - } - - #[test] - fn test_ignore_non_matching_line() { - let (tx, rx) = mpsc::channel(); - let state = Arc::new(Mutex::new(LtcState::new())); - let re = get_ltc_regex(); - let line = "this is not a valid ltc line"; - - // Simulate the processing logic - if let Some(caps) = re.captures(line) { - let arrival = Utc::now(); - if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { - { - let mut st = state.lock().unwrap(); - st.update(frame.clone()); - } - let _ = tx.send(frame); - } - } - - let st = state.lock().unwrap(); - assert_eq!(st.lock_count, 0); - assert_eq!(st.free_count, 0); - assert!(rx.try_recv().is_err()); - } - - #[test] - fn test_ignore_line_with_bad_parseable_data() { - let (tx, rx) = mpsc::channel(); - let state = Arc::new(Mutex::new(LtcState::new())); - let re = get_ltc_regex(); - // The regex will match, but `from_regex` should fail to parse "1.2.3.4" as f64 - let line = "[LOCK] 10:20:30:00 | 1.2.3.4fps"; - - // Simulate the processing logic - if let Some(caps) = re.captures(line) { - let arrival = Utc::now(); - if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { - { - let mut st = state.lock().unwrap(); - st.update(frame.clone()); - } - let _ = tx.send(frame); - } - } else { - panic!("Regex should have matched"); - } - - let st = state.lock().unwrap(); - assert_eq!(st.lock_count, 0); - assert_eq!(st.free_count, 0); - assert!(rx.try_recv().is_err()); - } -} +ο»Ώ// src/serial_input.rs + +use std::io::BufRead; +use std::sync::{Arc, Mutex}; +use std::sync::mpsc::Sender; +use chrono::Utc; +use regex::Regex; +use crate::sync_logic::{LtcFrame, LtcState}; + +pub fn start_serial_thread( + port_path: &str, + baud_rate: u32, + sender: Sender, + state: Arc>, + _hardware_offset_ms: i64, // no longer used here +) { + println!("πŸ“‘ Opening serial port {} @ {} baud", port_path, baud_rate); + + let port = match serialport::new(port_path, baud_rate) + .timeout(std::time::Duration::from_millis(1000)) + .open() + { + Ok(p) => { + println!("βœ… Serial port opened"); + p + } + Err(e) => { + eprintln!("❌ Serial open failed: {}", e); + return; + } + }; + + let reader = std::io::BufReader::new(port); + let re = Regex::new( + r"\[(LOCK|FREE)\]\s+(\d{2}):(\d{2}):(\d{2})[:;](\d{2})\s+\|\s+([\d.]+)fps", + ) + .unwrap(); + + println!("πŸ”„ Entering LTC read loop…"); + for line in reader.lines() { + if let Ok(text) = line { + if let Some(caps) = re.captures(&text) { + let arrival = Utc::now(); + if let Some(frame) = LtcFrame::from_regex(&caps, arrival) { + // update LOCK/FREE counts & timestamp + { + let mut st = state.lock().unwrap(); + st.update(frame.clone()); + } + // forward raw frame + let _ = sender.send(frame); + } + } + } + } +} diff --git a/src/sync_logic.rs b/src/sync_logic.rs index c6a3e80..0afa002 100644 --- a/src/sync_logic.rs +++ b/src/sync_logic.rs @@ -1,22 +1,7 @@ -ο»Ώuse crate::config::Config; -use chrono::{DateTime, Local, Timelike, Utc}; -use num_rational::Ratio; +ο»Ώuse chrono::{DateTime, Local, Timelike, Utc}; use regex::Captures; use std::collections::VecDeque; -const EWMA_ALPHA: f64 = 0.1; - -fn get_frame_rate_ratio(rate_str: &str) -> Option> { - match rate_str { - "23.98" => Some(Ratio::new(24000, 1001)), - "24.00" => Some(Ratio::new(24, 1)), - "25.00" => Some(Ratio::new(25, 1)), - "29.97" => Some(Ratio::new(30000, 1001)), - "30.00" => Some(Ratio::new(30, 1)), - _ => None, - } -} - #[derive(Clone, Debug)] pub struct LtcFrame { pub status: String, @@ -24,8 +9,7 @@ pub struct LtcFrame { pub minutes: u32, pub seconds: u32, pub frames: u32, - pub is_drop_frame: bool, - pub frame_rate: Ratio, + pub frame_rate: f64, pub timestamp: DateTime, // arrival stamp } @@ -36,9 +20,8 @@ impl LtcFrame { hours: caps[2].parse().ok()?, minutes: caps[3].parse().ok()?, seconds: caps[4].parse().ok()?, - is_drop_frame: &caps[5] == ";", - frames: caps[6].parse().ok()?, - frame_rate: get_frame_rate_ratio(&caps[7])?, + frames: caps[5].parse().ok()?, + frame_rate: caps[6].parse().ok()?, timestamp, }) } @@ -58,8 +41,8 @@ pub struct LtcState { pub free_count: u32, /// Stores the last up-to-20 raw offset measurements in ms. pub offset_history: VecDeque, - /// EWMA of clock delta. - pub ewma_clock_delta: Option, + /// Stores the last up-to-20 timecode Ξ” measurements in ms. + pub clock_delta_history: VecDeque, pub last_match_status: String, pub last_match_check: i64, } @@ -71,7 +54,7 @@ impl LtcState { lock_count: 0, free_count: 0, offset_history: VecDeque::with_capacity(20), - ewma_clock_delta: None, + clock_delta_history: VecDeque::with_capacity(20), last_match_status: "UNKNOWN".into(), last_match_check: 0, } @@ -85,14 +68,12 @@ impl LtcState { self.offset_history.push_back(offset_ms); } - /// Update EWMA of clock delta. - pub fn record_and_update_ewma_clock_delta(&mut self, delta_ms: i64) { - let new_delta = delta_ms as f64; - if let Some(current_ewma) = self.ewma_clock_delta { - self.ewma_clock_delta = Some(EWMA_ALPHA * new_delta + (1.0 - EWMA_ALPHA) * current_ewma); - } else { - self.ewma_clock_delta = Some(new_delta); + /// Record one timecode Ξ” in ms. + pub fn record_clock_delta(&mut self, delta_ms: i64) { + if self.clock_delta_history.len() == 20 { + self.clock_delta_history.pop_front(); } + self.clock_delta_history.push_back(delta_ms); } /// Clear all stored jitter measurements. @@ -100,6 +81,11 @@ impl LtcState { self.offset_history.clear(); } + /// Clear all stored timecode Ξ” measurements. + pub fn clear_clock_deltas(&mut self) { + self.clock_delta_history.clear(); + } + /// Update LOCK/FREE counts and timecode-match status every 5 s. pub fn update(&mut self, frame: LtcFrame) { match frame.status.as_str() { @@ -121,7 +107,7 @@ impl LtcState { "FREE" => { self.free_count += 1; self.clear_offsets(); - self.ewma_clock_delta = None; + self.clear_clock_deltas(); self.last_match_status = "UNKNOWN".into(); } _ => {} @@ -143,17 +129,21 @@ impl LtcState { /// Convert average jitter into frames (rounded). pub fn average_frames(&self) -> i64 { if let Some(frame) = &self.latest { - let jitter_ms_ratio = Ratio::new(self.average_jitter(), 1); - let frames_ratio = jitter_ms_ratio * frame.frame_rate / Ratio::new(1000, 1); - frames_ratio.round().to_integer() + let ms_per_frame = 1000.0 / frame.frame_rate; + (self.average_jitter() as f64 / ms_per_frame).round() as i64 } else { 0 } } - /// Get EWMA of clock delta, in ms. - pub fn get_ewma_clock_delta(&self) -> i64 { - self.ewma_clock_delta.map_or(0, |v| v.round() as i64) + /// Average timecode Ξ” over stored history, in ms. + pub fn average_clock_delta(&self) -> i64 { + if self.clock_delta_history.is_empty() { + 0 + } else { + let sum: i64 = self.clock_delta_history.iter().sum(); + sum / self.clock_delta_history.len() as i64 + } } /// Percentage of samples seen in LOCK state versus total. @@ -171,33 +161,10 @@ impl LtcState { &self.last_match_status } } - -pub fn get_sync_status(delta_ms: i64, config: &Config) -> &'static str { - if config.timeturner_offset.is_active() { - "TIMETURNING" - } else if delta_ms.abs() <= 8 { - "IN SYNC" - } else if delta_ms > 10 { - "CLOCK AHEAD" - } else { - "CLOCK BEHIND" - } -} - -pub fn get_jitter_status(jitter_ms: i64) -> &'static str { - if jitter_ms.abs() < 10 { - "GOOD" - } else if jitter_ms.abs() < 40 { - "AVERAGE" - } else { - "BAD" - } -} // This module provides the logic for handling LTC (Linear Timecode) frames and maintaining state. #[cfg(test)] mod tests { use super::*; - use crate::config::{Config, TimeturnerOffset}; use chrono::{Local, Utc}; fn get_test_frame(status: &str, h: u32, m: u32, s: u32) -> LtcFrame { @@ -207,8 +174,7 @@ mod tests { minutes: m, seconds: s, frames: 0, - is_drop_frame: false, - frame_rate: Ratio::new(25, 1), + frame_rate: 25.0, timestamp: Utc::now(), } } @@ -325,63 +291,4 @@ mod tests { "Status should update after throttle period" ); } - - #[test] - fn test_ewma_clock_delta() { - let mut state = LtcState::new(); - assert_eq!(state.get_ewma_clock_delta(), 0); - - // First value initializes the EWMA - state.record_and_update_ewma_clock_delta(100); - assert_eq!(state.get_ewma_clock_delta(), 100); - - // Second value moves it - state.record_and_update_ewma_clock_delta(200); - // 0.1 * 200 + 0.9 * 100 = 20 + 90 = 110 - assert_eq!(state.get_ewma_clock_delta(), 110); - - // Third value - state.record_and_update_ewma_clock_delta(100); - // 0.1 * 100 + 0.9 * 110 = 10 + 99 = 109 - assert_eq!(state.get_ewma_clock_delta(), 109); - - // Reset on FREE frame - state.update(get_test_frame("FREE", 0, 0, 0)); - assert_eq!(state.get_ewma_clock_delta(), 0); - assert!(state.ewma_clock_delta.is_none()); - } - - #[test] - fn test_get_sync_status() { - let mut config = Config::default(); - assert_eq!(get_sync_status(0, &config), "IN SYNC"); - assert_eq!(get_sync_status(8, &config), "IN SYNC"); - assert_eq!(get_sync_status(-8, &config), "IN SYNC"); - assert_eq!(get_sync_status(9, &config), "CLOCK BEHIND"); - assert_eq!(get_sync_status(10, &config), "CLOCK BEHIND"); - assert_eq!(get_sync_status(11, &config), "CLOCK AHEAD"); - assert_eq!(get_sync_status(-9, &config), "CLOCK BEHIND"); - assert_eq!(get_sync_status(-100, &config), "CLOCK BEHIND"); - - // Test auto-sync status - config.auto_sync_enabled = true; - assert_eq!(get_sync_status(0, &config), "IN SYNC"); - - // Test TIMETURNING status takes precedence - config.timeturner_offset = TimeturnerOffset { hours: 1, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }; - assert_eq!(get_sync_status(0, &config), "TIMETURNING"); - assert_eq!(get_sync_status(100, &config), "TIMETURNING"); - } - - #[test] - fn test_get_jitter_status() { - assert_eq!(get_jitter_status(5), "GOOD"); - assert_eq!(get_jitter_status(-5), "GOOD"); - assert_eq!(get_jitter_status(9), "GOOD"); - assert_eq!(get_jitter_status(10), "AVERAGE"); - assert_eq!(get_jitter_status(39), "AVERAGE"); - assert_eq!(get_jitter_status(-39), "AVERAGE"); - assert_eq!(get_jitter_status(40), "BAD"); - assert_eq!(get_jitter_status(-40), "BAD"); - } } diff --git a/src/system.rs b/src/system.rs deleted file mode 100644 index 8db481d..0000000 --- a/src/system.rs +++ /dev/null @@ -1,262 +0,0 @@ -use crate::config::Config; -use crate::sync_logic::LtcFrame; -use chrono::{DateTime, Duration as ChronoDuration, Local, TimeZone}; -use num_rational::Ratio; -use std::process::Command; - -/// Check if Chrony is active -pub fn ntp_service_active() -> bool { - #[cfg(target_os = "linux")] - { - if let Ok(output) = Command::new("systemctl").args(&["is-active", "chrony"]).output() { - output.status.success() - && String::from_utf8_lossy(&output.stdout).trim() == "active" - } else { - false - } - } - #[cfg(not(target_os = "linux"))] - { - // systemctl is not available on non-Linux platforms. - false - } -} - -/// Toggle Chrony (not used yet) -#[allow(dead_code)] -pub fn ntp_service_toggle(start: bool) { - #[cfg(target_os = "linux")] - { - let action = if start { "start" } else { "stop" }; - let _ = Command::new("systemctl").args(&[action, "chrony"]).status(); - } - #[cfg(not(target_os = "linux"))] - { - // No-op on non-Linux. - // The parameter is unused, but the function is dead code anyway. - let _ = start; - } -} - -pub fn calculate_target_time(frame: &LtcFrame, config: &Config) -> DateTime { - let today_local = Local::now().date_naive(); - - // Total seconds from timecode components - let timecode_secs = - frame.hours as i64 * 3600 + frame.minutes as i64 * 60 + frame.seconds as i64; - - // Timecode is always treated as wall-clock time. NDF scaling is not applied - // as the LTC source appears to be pre-compensated. - let total_duration_secs = - Ratio::new(timecode_secs, 1) + Ratio::new(frame.frames as i64, 1) / frame.frame_rate; - - // Convert to milliseconds - let total_ms = (total_duration_secs * Ratio::new(1000, 1)) - .round() - .to_integer(); - - let naive_midnight = today_local.and_hms_opt(0, 0, 0).unwrap(); - let naive_dt = naive_midnight + ChronoDuration::milliseconds(total_ms); - - let mut dt_local = Local - .from_local_datetime(&naive_dt) - .single() - .expect("Ambiguous or invalid local time"); - - // Apply timeturner offset - let offset = &config.timeturner_offset; - dt_local = dt_local - + ChronoDuration::hours(offset.hours) - + ChronoDuration::minutes(offset.minutes) - + ChronoDuration::seconds(offset.seconds); - // Frame offset needs to be converted to milliseconds - let frame_offset_ms_ratio = Ratio::new(offset.frames * 1000, 1) / frame.frame_rate; - let frame_offset_ms = frame_offset_ms_ratio.round().to_integer(); - dt_local + ChronoDuration::milliseconds(frame_offset_ms + offset.milliseconds) -} - -pub fn trigger_sync(frame: &LtcFrame, config: &Config) -> Result { - let dt_local = calculate_target_time(frame, config); - - #[cfg(target_os = "linux")] - let (ts, success) = { - let ts = dt_local.format("%H:%M:%S.%3f").to_string(); - let success = Command::new("sudo") - .arg("date") - .arg("-s") - .arg(&ts) - .status() - .map(|s| s.success()) - .unwrap_or(false); - (ts, success) - }; - - #[cfg(target_os = "macos")] - let (ts, success) = { - // macOS `date` command format is `mmddHHMMccyy.SS` - let ts = dt_local.format("%m%d%H%M%y.%S").to_string(); - let success = Command::new("sudo") - .arg("date") - .arg(&ts) - .status() - .map(|s| s.success()) - .unwrap_or(false); - (ts, success) - }; - - #[cfg(not(any(target_os = "linux", target_os = "macos")))] - let (ts, success) = { - // Unsupported OS, always fail - let ts = dt_local.format("%H:%M:%S.%3f").to_string(); - eprintln!("Unsupported OS for time synchronization"); - (ts, false) - }; - - if success { - Ok(ts) - } else { - Err(()) - } -} - -pub fn nudge_clock(microseconds: i64) -> Result<(), ()> { - #[cfg(target_os = "linux")] - { - let success = Command::new("sudo") - .arg("adjtimex") - .arg("--singleshot") - .arg(microseconds.to_string()) - .status() - .map(|s| s.success()) - .unwrap_or(false); - - if success { - log::info!("Nudged clock by {} us", microseconds); - Ok(()) - } else { - log::error!("Failed to nudge clock with adjtimex"); - Err(()) - } - } - #[cfg(not(target_os = "linux"))] - { - let _ = microseconds; - log::warn!("Clock nudging is only supported on Linux."); - Err(()) - } -} - -pub fn set_date(date: &str) -> Result<(), ()> { - #[cfg(target_os = "linux")] - { - let datetime_str = format!("{} 10:00:00", date); - let success = Command::new("sudo") - .arg("date") - .arg("--set") - .arg(&datetime_str) - .status() - .map(|s| s.success()) - .unwrap_or(false); - - if success { - log::info!("Set system date and time to {}", datetime_str); - Ok(()) - } else { - log::error!("Failed to set system date and time"); - Err(()) - } - } - #[cfg(not(target_os = "linux"))] - { - let _ = date; - log::warn!("Date setting is only supported on Linux."); - Err(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::config::TimeturnerOffset; - use chrono::{Timelike, Utc}; - use num_rational::Ratio; - - // Helper to create a test frame - fn get_test_frame(h: u32, m: u32, s: u32, f: u32) -> LtcFrame { - LtcFrame { - status: "LOCK".to_string(), - hours: h, - minutes: m, - seconds: s, - frames: f, - is_drop_frame: false, - frame_rate: Ratio::new(25, 1), - timestamp: Utc::now(), - } - } - - #[test] - fn test_ntp_service_active_on_non_linux() { - // On non-Linux platforms, this should always be false. - #[cfg(not(target_os = "linux"))] - assert!(!ntp_service_active()); - } - - #[test] - fn test_calculate_target_time_no_offset() { - let frame = get_test_frame(10, 20, 30, 0); - let config = Config::default(); - let target_time = calculate_target_time(&frame, &config); - - assert_eq!(target_time.hour(), 10); - assert_eq!(target_time.minute(), 20); - assert_eq!(target_time.second(), 30); - } - - #[test] - fn test_calculate_target_time_with_positive_offset() { - let frame = get_test_frame(10, 20, 30, 0); - let mut config = Config::default(); - config.timeturner_offset = TimeturnerOffset { - hours: 1, - minutes: 5, - seconds: 10, - frames: 12, // 12 frames at 25fps is 480ms - milliseconds: 20, - }; - - let target_time = calculate_target_time(&frame, &config); - - assert_eq!(target_time.hour(), 11); - assert_eq!(target_time.minute(), 25); - assert_eq!(target_time.second(), 40); - // 480ms + 20ms = 500ms - assert_eq!(target_time.nanosecond(), 500_000_000); - } - - #[test] - fn test_calculate_target_time_with_negative_offset() { - let frame = get_test_frame(10, 20, 30, 12); // 12 frames = 480ms - let mut config = Config::default(); - config.timeturner_offset = TimeturnerOffset { - hours: -1, - minutes: -5, - seconds: -10, - frames: -12, // -480ms - milliseconds: -80, - }; - - let target_time = calculate_target_time(&frame, &config); - - assert_eq!(target_time.hour(), 9); - assert_eq!(target_time.minute(), 15); - assert_eq!(target_time.second(), 19); - assert_eq!(target_time.nanosecond(), 920_000_000); - } - - #[test] - fn test_nudge_clock_on_non_linux() { - #[cfg(not(target_os = "linux"))] - assert!(nudge_clock(1000).is_err()); - } -} diff --git a/src/ui.rs b/src/ui.rs index 5854f4a..a8b0286 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,234 +1,338 @@ -ο»Ώuse std::{ - io::{stdout, Write}, - process::{self}, - sync::{Arc, Mutex}, - thread, - time::{Duration, Instant}, -}; -use std::collections::VecDeque; - -use chrono::{ - DateTime, Local, Timelike, Utc, -}; -use crossterm::{ - cursor::{Hide, MoveTo, Show}, - event::{poll, read, Event, KeyCode}, - execute, queue, - style::{Color, Print, ResetColor, SetForegroundColor}, - terminal::{self, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen}, -}; - -use crate::config::Config; -use crate::sync_logic::{get_jitter_status, get_sync_status, LtcState}; -use crate::system; -use get_if_addrs::get_if_addrs; -use num_rational::Ratio; -use num_traits::ToPrimitive; - - -pub fn start_ui( - state: Arc>, - serial_port: String, - config: Arc>, -) { - let mut stdout = stdout(); - execute!(stdout, EnterAlternateScreen, Hide).unwrap(); - terminal::enable_raw_mode().unwrap(); - - let mut logs: VecDeque = VecDeque::with_capacity(10); - let mut last_delta_update = Instant::now() - Duration::from_secs(1); - let mut cached_delta_ms: i64 = 0; - let mut cached_delta_frames: i64 = 0; - - loop { - // 1️⃣ config - let cfg = config.lock().unwrap().clone(); - let hw_offset_ms = cfg.hardware_offset_ms; - - // 2️⃣ Chrony + interfaces - let ntp_active = system::ntp_service_active(); - let interfaces: Vec = get_if_addrs() - .unwrap_or_default() - .into_iter() - .filter(|ifa| !ifa.is_loopback()) - .map(|ifa| ifa.ip().to_string()) - .collect(); - - // 3️⃣ jitter - { - let mut st = state.lock().unwrap(); - if let Some(frame) = st.latest.clone() { - if frame.status == "LOCK" { - // jitter - let now_utc = Utc::now(); - let raw = (now_utc - frame.timestamp).num_milliseconds(); - let measured = raw - hw_offset_ms; - st.record_offset(measured); - } - } - } - - // 4️⃣ averages & status override - let (avg_jitter_ms, _avg_frames, _, lock_ratio, avg_delta) = { - let st = state.lock().unwrap(); - ( - st.average_jitter(), - st.average_frames(), - st.timecode_match().to_string(), - st.lock_ratio(), - st.get_ewma_clock_delta(), - ) - }; - - // 5️⃣ cache Ξ” once/sec & Ξ” in frames - if last_delta_update.elapsed() >= Duration::from_secs(1) { - cached_delta_ms = avg_delta; - if let Some(frame) = &state.lock().unwrap().latest { - let delta_ms_ratio = Ratio::new(avg_delta, 1); - let frames_ratio = delta_ms_ratio * frame.frame_rate / Ratio::new(1000, 1); - cached_delta_frames = frames_ratio.round().to_integer(); - } else { - cached_delta_frames = 0; - } - last_delta_update = Instant::now(); - } - - // 6️⃣ sync status wording - let sync_status = get_sync_status(cached_delta_ms, &cfg); - - // 7️⃣ header & LTC metrics display - { - let st = state.lock().unwrap(); - let opt = st.latest.as_ref(); - let status_str = opt.map(|f| f.status.as_str()).unwrap_or("(waiting)"); - let tc_str = match opt { - Some(f) => format!("LTC Timecode : {:02}:{:02}:{:02}:{:02}", - f.hours, f.minutes, f.seconds, f.frames), - None => "LTC Timecode : …".to_string(), - }; - let fr_str = match opt { - Some(f) => format!("Frame Rate : {:.2}fps", f.frame_rate.to_f64().unwrap_or(0.0)), - None => "Frame Rate : …".to_string(), - }; - - queue!( - stdout, - MoveTo(0, 0), Clear(ClearType::All), - MoveTo(2, 1), Print("Have Blue - NTP Timeturner"), - MoveTo(2, 2), Print(format!("Serial Port : {}", serial_port)), - MoveTo(2, 3), Print(format!("Chrony Service : {}", - if ntp_active { "RUNNING" } else { "MISSING" })), - MoveTo(2, 4), Print(format!("Interfaces : {}", - interfaces.join(", "))), - MoveTo(2, 6), Print(format!("LTC Status : {}", status_str)), - MoveTo(2, 7), Print(tc_str), - MoveTo(2, 8), Print(fr_str), - ).unwrap(); - } - - // system clock - let now_local: DateTime = DateTime::from(Utc::now()); - let sys_ts = format!( - "{:02}:{:02}:{:02}.{:03}", - now_local.hour(), - now_local.minute(), - now_local.second(), - now_local.timestamp_subsec_millis(), - ); - queue!(stdout, - MoveTo(2, 9), Print(format!( - "System Clock : {}", - sys_ts - ))).unwrap(); - - // Ξ” display - let dcol = if cached_delta_ms.abs() < 20 { - Color::Green - } else if cached_delta_ms.abs() < 100 { - Color::Yellow - } else { - Color::Red - }; - queue!( - stdout, - MoveTo(2, 11), SetForegroundColor(dcol), - Print(format!("Timecode Ξ” : {:+} ms ({:+} frames)", cached_delta_ms, cached_delta_frames)), - ResetColor, - ).unwrap(); - - // sync status - let scol = if sync_status == "IN SYNC" { - Color::Green - } else if sync_status == "TIMETURNING" { - Color::Cyan - } else { - Color::Red - }; - queue!( - stdout, - MoveTo(2, 12), SetForegroundColor(scol), - Print(format!("Sync Status : {}", sync_status)), - ResetColor, - ).unwrap(); - - // jitter & lock ratio - let jstatus = get_jitter_status(avg_jitter_ms); - let jcol = if jstatus == "GOOD" { - Color::Green - } else if jstatus == "AVERAGE" { - Color::Yellow - } else { - Color::Red - }; - queue!( - stdout, - MoveTo(2, 13), SetForegroundColor(jcol), - Print(format!("Sync Jitter : {}", jstatus)), - ResetColor, - ).unwrap(); - queue!( - stdout, - MoveTo(2, 14), Print(format!("Lock Ratio : {:.1}% LOCK", - lock_ratio - )), - ).unwrap(); - - // footer + logs - queue!( - stdout, - MoveTo(2, 16), Print("[S] Sync System Clock to LTC [Q] Quit"), - ).unwrap(); - for (i, msg) in logs.iter().enumerate() { - queue!(stdout, MoveTo(2, 18 + i as u16), Print(msg)).unwrap(); - } - - stdout.flush().unwrap(); - - // manual sync & quit - if poll(Duration::from_millis(50)).unwrap() { - if let Event::Key(evt) = read().unwrap() { - match evt.code { - KeyCode::Char(c) if c.eq_ignore_ascii_case(&'q') => { - execute!(stdout, Show, LeaveAlternateScreen).unwrap(); - terminal::disable_raw_mode().unwrap(); - process::exit(0); - } - KeyCode::Char(c) if c.eq_ignore_ascii_case(&'s') => { - if let Some(frame) = &state.lock().unwrap().latest { - let entry = match system::trigger_sync(frame, &cfg) { - Ok(ts) => format!("βœ” Synced exactly to LTC: {}", ts), - Err(_) => "❌ date cmd failed".into(), - }; - if logs.len() == 10 { logs.pop_front(); } - logs.push_back(entry); - } - } - _ => {} - } - } - } - - thread::sleep(Duration::from_millis(25)); - } -} - +ο»Ώuse std::{ + io::{stdout, Write}, + process::{self, Command}, + sync::{Arc, Mutex}, + thread, + time::{Duration, Instant}, +}; +use std::collections::VecDeque; + +use chrono::{ + DateTime, Local, Timelike, Utc, + NaiveTime, TimeZone, +}; +use crossterm::{ + cursor::{Hide, MoveTo, Show}, + event::{poll, read, Event, KeyCode}, + execute, queue, + style::{Color, Print, ResetColor, SetForegroundColor}, + terminal::{self, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen}, +}; + +use get_if_addrs::get_if_addrs; +use crate::sync_logic::LtcState; + +/// Check if Chrony is active +fn ntp_service_active() -> bool { + if let Ok(output) = Command::new("systemctl").args(&["is-active", "chrony"]).output() { + output.status.success() + && String::from_utf8_lossy(&output.stdout).trim() == "active" + } else { + false + } +} + +/// Toggle Chrony (not used yet) +#[allow(dead_code)] +fn ntp_service_toggle(start: bool) { + let action = if start { "start" } else { "stop" }; + let _ = Command::new("systemctl").args(&[action, "chrony"]).status(); +} + +pub fn start_ui( + state: Arc>, + serial_port: String, + offset: Arc>, +) { + let mut stdout = stdout(); + execute!(stdout, EnterAlternateScreen, Hide).unwrap(); + terminal::enable_raw_mode().unwrap(); + + let mut logs: VecDeque = VecDeque::with_capacity(10); + let mut out_of_sync_since: Option = None; + let mut last_delta_update = Instant::now() - Duration::from_secs(1); + let mut cached_delta_ms: i64 = 0; + let mut cached_delta_frames: i64 = 0; + + loop { + // 1️⃣ hardware offset + let hw_offset_ms = *offset.lock().unwrap(); + + // 2️⃣ Chrony + interfaces + let ntp_active = ntp_service_active(); + let interfaces: Vec = get_if_addrs() + .unwrap_or_default() + .into_iter() + .filter(|ifa| !ifa.is_loopback()) + .map(|ifa| ifa.ip().to_string()) + .collect(); + + // 3️⃣ jitter + Ξ” + { + let mut st = state.lock().unwrap(); + if let Some(frame) = st.latest.clone() { + if frame.status == "LOCK" { + // jitter + let now_utc = Utc::now(); + let raw = (now_utc - frame.timestamp).num_milliseconds(); + let measured = raw - hw_offset_ms; + st.record_offset(measured); + + // Ξ” = system clock - LTC timecode (use LOCAL time) + let today_local = Local::now().date_naive(); + let ms = ((frame.frames as f64 / frame.frame_rate) * 1000.0) + .round() as u32; + let tc_naive = NaiveTime::from_hms_milli_opt( + frame.hours, frame.minutes, frame.seconds, ms, + ).expect("Invalid LTC timecode"); + let naive_dt_local = today_local.and_time(tc_naive); + let dt_local = Local + .from_local_datetime(&naive_dt_local) + .single() + .expect("Invalid local time"); + let delta_ms = (Local::now() - dt_local).num_milliseconds(); + st.record_clock_delta(delta_ms); + } else { + st.clear_offsets(); + st.clear_clock_deltas(); + } + } + } + + // 4️⃣ averages & status override + let (avg_jitter_ms, _avg_frames, _, lock_ratio, avg_delta) = { + let st = state.lock().unwrap(); + ( + st.average_jitter(), + st.average_frames(), + st.timecode_match().to_string(), + st.lock_ratio(), + st.average_clock_delta(), + ) + }; + + // 5️⃣ cache Ξ” once/sec & Ξ” in frames + if last_delta_update.elapsed() >= Duration::from_secs(1) { + cached_delta_ms = avg_delta; + if let Some(frame) = &state.lock().unwrap().latest { + let frame_ms = 1000.0 / frame.frame_rate; + cached_delta_frames = ((avg_delta as f64 / frame_ms).round()) as i64; + } else { + cached_delta_frames = 0; + } + last_delta_update = Instant::now(); + } + + // 6️⃣ sync status wording + let sync_status = if cached_delta_ms.abs() <= 8 { + "IN SYNC" + } else if cached_delta_ms > 10 { + "CLOCK AHEAD" + } else { + "CLOCK BEHIND" + }; + + // 7️⃣ auto‑sync (same as manual but delayed) + if sync_status != "IN SYNC" { + if let Some(start) = out_of_sync_since { + if start.elapsed() >= Duration::from_secs(5) { + if let Some(frame) = &state.lock().unwrap().latest { + let today_local = Local::now().date_naive(); + let ms = ((frame.frames as f64 / frame.frame_rate) * 1000.0) + .round() as u32; + let timecode = NaiveTime::from_hms_milli_opt( + frame.hours, frame.minutes, frame.seconds, ms, + ).expect("Invalid LTC timecode"); + let naive_dt = today_local.and_time(timecode); + let dt_local = Local + .from_local_datetime(&naive_dt) + .single() + .expect("Ambiguous or invalid local time"); + let ts = dt_local.format("%H:%M:%S.%3f").to_string(); + + let success = Command::new("sudo") + .arg("date") + .arg("-s") + .arg(&ts) + .status() + .map(|s| s.success()) + .unwrap_or(false); + + let entry = if success { + format!("πŸ”„ Auto‑synced to LTC: {}", ts) + } else { + "❌ Auto‑sync failed".into() + }; + if logs.len() == 10 { logs.pop_front(); } + logs.push_back(entry); + } + out_of_sync_since = None; + } + } else { + out_of_sync_since = Some(Instant::now()); + } + } else { + out_of_sync_since = None; + } + + // 8️⃣ header & LTC metrics display + { + let st = state.lock().unwrap(); + let opt = st.latest.as_ref(); + let status_str = opt.map(|f| f.status.as_str()).unwrap_or("(waiting)"); + let tc_str = match opt { + Some(f) => format!("LTC Timecode : {:02}:{:02}:{:02}:{:02}", + f.hours, f.minutes, f.seconds, f.frames), + None => "LTC Timecode : …".to_string(), + }; + let fr_str = match opt { + Some(f) => format!("Frame Rate : {:.2}fps", f.frame_rate), + None => "Frame Rate : …".to_string(), + }; + + queue!( + stdout, + MoveTo(0, 0), Clear(ClearType::All), + MoveTo(2, 1), Print("Have Blue - NTP Timeturner"), + MoveTo(2, 2), Print(format!("Serial Port : {}", serial_port)), + MoveTo(2, 3), Print(format!("Chrony Service : {}", + if ntp_active { "RUNNING" } else { "MISSING" })), + MoveTo(2, 4), Print(format!("Interfaces : {}", + interfaces.join(", "))), + MoveTo(2, 6), Print(format!("LTC Status : {}", status_str)), + MoveTo(2, 7), Print(tc_str), + MoveTo(2, 8), Print(fr_str), + ).unwrap(); + } + + // system clock + let now_local: DateTime = DateTime::from(Utc::now()); + let sys_ts = format!( + "{:02}:{:02}:{:02}.{:03}", + now_local.hour(), + now_local.minute(), + now_local.second(), + now_local.timestamp_subsec_millis(), + ); + queue!(stdout, + MoveTo(2, 9), Print(format!( + "System Clock : {}", + sys_ts + ))).unwrap(); + + // Ξ” display + let dcol = if cached_delta_ms.abs() < 20 { + Color::Green + } else if cached_delta_ms.abs() < 100 { + Color::Yellow + } else { + Color::Red + }; + queue!( + stdout, + MoveTo(2, 11), SetForegroundColor(dcol), + Print(format!("Timecode Ξ” : {:+} ms ({:+} frames)", cached_delta_ms, cached_delta_frames)), + ResetColor, + ).unwrap(); + + // sync status + let scol = if sync_status == "IN SYNC" { + Color::Green + } else { + Color::Red + }; + queue!( + stdout, + MoveTo(2, 12), SetForegroundColor(scol), + Print(format!("Sync Status : {}", sync_status)), + ResetColor, + ).unwrap(); + + // jitter & lock ratio + let jstatus = if avg_jitter_ms.abs() < 10 { + "GOOD" + } else if avg_jitter_ms.abs() < 40 { + "AVERAGE" + } else { + "BAD" + }; + let jcol = if jstatus == "GOOD" { + Color::Green + } else if jstatus == "AVERAGE" { + Color::Yellow + } else { + Color::Red + }; + queue!( + stdout, + MoveTo(2, 13), SetForegroundColor(jcol), + Print(format!("Sync Jitter : {}", jstatus)), + ResetColor, + ).unwrap(); + queue!( + stdout, + MoveTo(2, 14), Print(format!("Lock Ratio : {:.1}% LOCK", + lock_ratio + )), + ).unwrap(); + + // footer + logs + queue!( + stdout, + MoveTo(2, 16), Print("[S] Sync System Clock to LTC [Q] Quit"), + ).unwrap(); + for (i, msg) in logs.iter().enumerate() { + queue!(stdout, MoveTo(2, 18 + i as u16), Print(msg)).unwrap(); + } + + stdout.flush().unwrap(); + + // manual sync & quit + if poll(Duration::from_millis(50)).unwrap() { + if let Event::Key(evt) = read().unwrap() { + match evt.code { + KeyCode::Char(c) if c.eq_ignore_ascii_case(&'q') => { + execute!(stdout, Show, LeaveAlternateScreen).unwrap(); + terminal::disable_raw_mode().unwrap(); + process::exit(0); + } + KeyCode::Char(c) if c.eq_ignore_ascii_case(&'s') => { + if let Some(frame) = &state.lock().unwrap().latest { + let today_local = Local::now().date_naive(); + let ms = ((frame.frames as f64 / frame.frame_rate) * 1000.0) + .round() as u32; + let timecode = NaiveTime::from_hms_milli_opt( + frame.hours, frame.minutes, frame.seconds, ms, + ).expect("Invalid LTC timecode"); + let naive_dt = today_local.and_time(timecode); + let dt_local = Local + .from_local_datetime(&naive_dt) + .single() + .expect("Ambiguous or invalid local time"); + let ts = dt_local.format("%H:%M:%S.%3f").to_string(); + + let success = Command::new("sudo") + .arg("date") + .arg("-s") + .arg(&ts) + .status() + .map(|s| s.success()) + .unwrap_or(false); + + let entry = if success { + format!("βœ” Synced exactly to LTC: {}", ts) + } else { + "❌ date cmd failed".into() + }; + if logs.len() == 10 { logs.pop_front(); } + logs.push_back(entry); + } + } + _ => {} + } + } + } + + thread::sleep(Duration::from_millis(25)); + } +} diff --git a/static/assets/FuturaStdHeavy.otf b/static/assets/FuturaStdHeavy.otf deleted file mode 100644 index 7b8c22d..0000000 Binary files a/static/assets/FuturaStdHeavy.otf and /dev/null differ diff --git a/static/assets/HaveBlueTransWh.png b/static/assets/HaveBlueTransWh.png deleted file mode 100644 index d9a123d..0000000 Binary files a/static/assets/HaveBlueTransWh.png and /dev/null differ diff --git a/static/assets/favicon.png b/static/assets/favicon.png deleted file mode 100644 index 3683c35..0000000 Binary files a/static/assets/favicon.png and /dev/null differ diff --git a/static/assets/header.png b/static/assets/header.png deleted file mode 100644 index f1677ed..0000000 Binary files a/static/assets/header.png and /dev/null differ diff --git a/static/assets/quartz-ms-regular.ttf b/static/assets/quartz-ms-regular.ttf deleted file mode 100644 index 15c7ce4..0000000 Binary files a/static/assets/quartz-ms-regular.ttf and /dev/null differ diff --git a/static/assets/timeturner_2398.png b/static/assets/timeturner_2398.png deleted file mode 100644 index 763bcba..0000000 Binary files a/static/assets/timeturner_2398.png and /dev/null differ diff --git a/static/assets/timeturner_24.png b/static/assets/timeturner_24.png deleted file mode 100644 index ffc75d0..0000000 Binary files a/static/assets/timeturner_24.png and /dev/null differ diff --git a/static/assets/timeturner_25.png b/static/assets/timeturner_25.png deleted file mode 100644 index 3b44c93..0000000 Binary files a/static/assets/timeturner_25.png and /dev/null differ diff --git a/static/assets/timeturner_2997.png b/static/assets/timeturner_2997.png deleted file mode 100644 index 0bd27fd..0000000 Binary files a/static/assets/timeturner_2997.png and /dev/null differ diff --git a/static/assets/timeturner_2997DF.png b/static/assets/timeturner_2997DF.png deleted file mode 100644 index bf03215..0000000 Binary files a/static/assets/timeturner_2997DF.png and /dev/null differ diff --git a/static/assets/timeturner_30.png b/static/assets/timeturner_30.png deleted file mode 100644 index 4ce0211..0000000 Binary files a/static/assets/timeturner_30.png and /dev/null differ diff --git a/static/assets/timeturner_controls.png b/static/assets/timeturner_controls.png deleted file mode 100644 index a91f39b..0000000 Binary files a/static/assets/timeturner_controls.png and /dev/null differ diff --git a/static/assets/timeturner_default.png b/static/assets/timeturner_default.png deleted file mode 100644 index 734aa8d..0000000 Binary files a/static/assets/timeturner_default.png and /dev/null differ diff --git a/static/assets/timeturner_delta_green.png b/static/assets/timeturner_delta_green.png deleted file mode 100644 index ddc84b9..0000000 Binary files a/static/assets/timeturner_delta_green.png and /dev/null differ diff --git a/static/assets/timeturner_delta_orange.png b/static/assets/timeturner_delta_orange.png deleted file mode 100644 index 64e9776..0000000 Binary files a/static/assets/timeturner_delta_orange.png and /dev/null differ diff --git a/static/assets/timeturner_delta_red.png b/static/assets/timeturner_delta_red.png deleted file mode 100644 index c7272ac..0000000 Binary files a/static/assets/timeturner_delta_red.png and /dev/null differ diff --git a/static/assets/timeturner_jitter_green.png b/static/assets/timeturner_jitter_green.png deleted file mode 100644 index 8cc64e3..0000000 Binary files a/static/assets/timeturner_jitter_green.png and /dev/null differ diff --git a/static/assets/timeturner_jitter_orange.png b/static/assets/timeturner_jitter_orange.png deleted file mode 100644 index 96c5f84..0000000 Binary files a/static/assets/timeturner_jitter_orange.png and /dev/null differ diff --git a/static/assets/timeturner_jitter_red.png b/static/assets/timeturner_jitter_red.png deleted file mode 100644 index 8813159..0000000 Binary files a/static/assets/timeturner_jitter_red.png and /dev/null differ diff --git a/static/assets/timeturner_lock_green.png b/static/assets/timeturner_lock_green.png deleted file mode 100644 index 0659c60..0000000 Binary files a/static/assets/timeturner_lock_green.png and /dev/null differ diff --git a/static/assets/timeturner_lock_orange.png b/static/assets/timeturner_lock_orange.png deleted file mode 100644 index 836a376..0000000 Binary files a/static/assets/timeturner_lock_orange.png and /dev/null differ diff --git a/static/assets/timeturner_lock_red.png b/static/assets/timeturner_lock_red.png deleted file mode 100644 index aa8740d..0000000 Binary files a/static/assets/timeturner_lock_red.png and /dev/null differ diff --git a/static/assets/timeturner_logs.png b/static/assets/timeturner_logs.png deleted file mode 100644 index 6bdd935..0000000 Binary files a/static/assets/timeturner_logs.png and /dev/null differ diff --git a/static/assets/timeturner_ltc_green.png b/static/assets/timeturner_ltc_green.png deleted file mode 100644 index 4329913..0000000 Binary files a/static/assets/timeturner_ltc_green.png and /dev/null differ diff --git a/static/assets/timeturner_ltc_orange.png b/static/assets/timeturner_ltc_orange.png deleted file mode 100644 index b060ac2..0000000 Binary files a/static/assets/timeturner_ltc_orange.png and /dev/null differ diff --git a/static/assets/timeturner_ltc_red.png b/static/assets/timeturner_ltc_red.png deleted file mode 100644 index a8e7f96..0000000 Binary files a/static/assets/timeturner_ltc_red.png and /dev/null differ diff --git a/static/assets/timeturner_network.png b/static/assets/timeturner_network.png deleted file mode 100644 index 06ec4b9..0000000 Binary files a/static/assets/timeturner_network.png and /dev/null differ diff --git a/static/assets/timeturner_ntp_green.png b/static/assets/timeturner_ntp_green.png deleted file mode 100644 index caf824d..0000000 Binary files a/static/assets/timeturner_ntp_green.png and /dev/null differ diff --git a/static/assets/timeturner_ntp_orange.png b/static/assets/timeturner_ntp_orange.png deleted file mode 100644 index 88319b5..0000000 Binary files a/static/assets/timeturner_ntp_orange.png and /dev/null differ diff --git a/static/assets/timeturner_ntp_red.png b/static/assets/timeturner_ntp_red.png deleted file mode 100644 index 16e66ee..0000000 Binary files a/static/assets/timeturner_ntp_red.png and /dev/null differ diff --git a/static/assets/timeturner_sync_green.png b/static/assets/timeturner_sync_green.png deleted file mode 100644 index 9b4988e..0000000 Binary files a/static/assets/timeturner_sync_green.png and /dev/null differ diff --git a/static/assets/timeturner_sync_orange.png b/static/assets/timeturner_sync_orange.png deleted file mode 100644 index 0b41130..0000000 Binary files a/static/assets/timeturner_sync_orange.png and /dev/null differ diff --git a/static/assets/timeturner_sync_red.png b/static/assets/timeturner_sync_red.png deleted file mode 100644 index 1c4c4c9..0000000 Binary files a/static/assets/timeturner_sync_red.png and /dev/null differ diff --git a/static/assets/timeturner_timeturning.png b/static/assets/timeturner_timeturning.png deleted file mode 100644 index fd3eaeb..0000000 Binary files a/static/assets/timeturner_timeturning.png and /dev/null differ diff --git a/static/favicon.ico b/static/favicon.ico deleted file mode 100644 index 83d6317..0000000 Binary files a/static/favicon.ico and /dev/null differ diff --git a/static/icon-map.js b/static/icon-map.js deleted file mode 100644 index 64336b3..0000000 --- a/static/icon-map.js +++ /dev/null @@ -1,43 +0,0 @@ -// In this file, you can define the paths to your local icon image files. -const iconMap = { - ltcStatus: { - 'LOCK': { src: 'assets/timeturner_ltc_green.png', tooltip: 'LTC signal is locked and stable.' }, - 'FREE': { src: 'assets/timeturner_ltc_orange.png', tooltip: 'LTC signal is in freewheel mode.' }, - 'default': { src: 'assets/timeturner_ltc_red.png', tooltip: 'LTC signal is not detected.' } - }, - ntpActive: { - true: { src: 'assets/timeturner_ntp_green.png', tooltip: 'NTP service is active.' }, - false: { src: 'assets/timeturner_ntp_red.png', tooltip: 'NTP service is inactive.' } - }, - syncStatus: { - 'IN SYNC': { src: 'assets/timeturner_sync_green.png', tooltip: 'System clock is in sync with LTC source.' }, - 'CLOCK AHEAD': { src: 'assets/timeturner_sync_orange.png', tooltip: 'System clock is ahead of the LTC source.' }, - 'CLOCK BEHIND': { src: 'assets/timeturner_sync_orange.png', tooltip: 'System clock is behind the LTC source.' }, - 'TIMETURNING': { src: 'assets/timeturner_timeturning.png', tooltip: 'Timeturner offset is active.' }, - 'default': { src: 'assets/timeturner_sync_red.png', tooltip: 'Sync status is unknown.' } - }, - jitterStatus: { - 'GOOD': { src: 'assets/timeturner_jitter_green.png', tooltip: 'Clock jitter is within acceptable limits.' }, - 'AVERAGE': { src: 'assets/timeturner_jitter_orange.png', tooltip: 'Clock jitter is moderate.' }, - 'BAD': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Clock jitter is high and may affect accuracy.' }, - 'default': { src: 'assets/timeturner_jitter_red.png', tooltip: 'Jitter status is unknown.' } - }, - deltaStatus: { - 'good': { src: 'assets/timeturner_delta_green.png', tooltip: 'Clock delta is 0ms.' }, - 'average': { src: 'assets/timeturner_delta_orange.png', tooltip: 'Clock delta is less than 10ms.' }, - 'bad': { src: 'assets/timeturner_delta_red.png', tooltip: 'Clock delta is 10ms or greater.' } - }, - frameRate: { - '23.98fps': { src: 'assets/timeturner_2398.png', tooltip: '23.98 frames per second' }, - '24.00fps': { src: 'assets/timeturner_24.png', tooltip: '24.00 frames per second' }, - '25.00fps': { src: 'assets/timeturner_25.png', tooltip: '25.00 frames per second' }, - '29.97fps': { src: 'assets/timeturner_2997.png', tooltip: '29.97 frames per second' }, - '30.00fps': { src: 'assets/timeturner_30.png', tooltip: '30.00 frames per second' }, - 'default': { src: 'assets/timeturner_default.png', tooltip: 'Unknown frame rate' } - }, - lockRatio: { - 'good': { src: 'assets/timeturner_lock_green.png', tooltip: 'Lock ratio is 100%.' }, - 'average': { src: 'assets/timeturner_lock_orange.png', tooltip: 'Lock ratio is 90% or higher.' }, - 'bad': { src: 'assets/timeturner_lock_red.png', tooltip: 'Lock ratio is below 90%.' } - } -}; diff --git a/static/index.html b/static/index.html deleted file mode 100644 index 02bb279..0000000 --- a/static/index.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - Fetch | Hachi - - - - -
- - - - - -
- -
-

LTC Input

-

--:--:--:--

-
- - - -
-
- - -
-

NTP Clock

-

--:--:--.---

-

---- -- --

-
- - - - -
-

Ξ” -- ms (-- frames)

-
- - -
-
- Network Icon -

Network

-
-

--

-
- - -
-
- Controls Icon -

Controls

-
-
- - -
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - - -
- -
- - - - -
-
-
- - -
-
- Logs Icon -

Logs

-
-
-

-                        
-
-
- -
- - - - - diff --git a/static/index_dev.html b/static/index_dev.html deleted file mode 100644 index edc555d..0000000 --- a/static/index_dev.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - NTP TimeTurner - - - - -
- - - - - -
- -
-

LTC Input

-

--:--:--:--

-
- - - -
-
- - -
-

NTP Clock

-

--:--:--.---

-

---- -- --

-
- - - - -
-

Ξ” -- ms (-- frames)

-
- - -
-
- Network Icon -

Network

-
-

--

-
- - -
-
- Controls Icon -

Controls

-
-
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-
- - - -
-
- - - - - -
-
- - - - -
-
-
- - -
-
- Logs Icon -

Logs

-
-
-

-                        
-
-
- -
- - - - - diff --git a/static/mock-data.js b/static/mock-data.js deleted file mode 100644 index a953e59..0000000 --- a/static/mock-data.js +++ /dev/null @@ -1,168 +0,0 @@ -// This file contains mock data sets for UI development and testing without a live backend. -const mockApiDataSets = { - allGood: { - status: { - ltc_status: 'LOCK', - ltc_timecode: '10:20:30:00', - frame_rate: '25.00fps', - lock_ratio: 99.5, - system_clock: '10:20:30.500', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'IN SYNC', - timecode_delta_ms: 5, - timecode_delta_frames: 0.125, - jitter_status: 'GOOD', - interfaces: ['192.168.1.100/24 (eth0)', '10.0.0.5/8 (wlan0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: true, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 1, minutes: 2, seconds: 3, frames: 4, milliseconds: 50 }, - }, - logs: [ - '2025-08-07 10:20:30 [INFO] Starting up...', - '2025-08-07 10:20:32 [INFO] LTC LOCK detected. Frame rate: 25.00fps.', - '2025-08-07 10:20:35 [INFO] Initial sync complete. Clock adjusted by -15ms.', - ] - }, - ltcFree: { - status: { - ltc_status: 'FREE', - ltc_timecode: '11:22:33:11', - frame_rate: '25.00fps', - lock_ratio: 40.2, - system_clock: '11:22:33.800', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'IN SYNC', - timecode_delta_ms: 3, - timecode_delta_frames: 0.075, - jitter_status: 'GOOD', - interfaces: ['192.168.1.100/24 (eth0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: true, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 0, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }, - }, - logs: [ '2025-08-07 11:22:30 [WARN] LTC signal lost, entering freewheel.' ] - }, - clockAhead: { - status: { - ltc_status: 'LOCK', - ltc_timecode: '12:00:05:00', - frame_rate: '25.00fps', - lock_ratio: 98.1, - system_clock: '12:00:04.500', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'CLOCK AHEAD', - timecode_delta_ms: -500, - timecode_delta_frames: -12.5, - jitter_status: 'AVERAGE', - interfaces: ['192.168.1.100/24 (eth0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: true, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 0, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }, - }, - logs: [ '2025-08-07 12:00:00 [WARN] System clock is ahead of LTC source by 500ms.' ] - }, - clockBehind: { - status: { - ltc_status: 'LOCK', - ltc_timecode: '13:30:10:00', - frame_rate: '25.00fps', - lock_ratio: 99.9, - system_clock: '13:30:10.800', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'CLOCK BEHIND', - timecode_delta_ms: 800, - timecode_delta_frames: 20, - jitter_status: 'AVERAGE', - interfaces: ['192.168.1.100/24 (eth0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: true, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 0, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }, - }, - logs: [ '2025-08-07 13:30:00 [WARN] System clock is behind LTC source by 800ms.' ] - }, - timeturning: { - status: { - ltc_status: 'LOCK', - ltc_timecode: '14:00:00:00', - frame_rate: '25.00fps', - lock_ratio: 100, - system_clock: '15:02:03.050', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'TIMETURNING', - timecode_delta_ms: 3723050, // a big number - timecode_delta_frames: 93076, - jitter_status: 'GOOD', - interfaces: ['192.168.1.100/24 (eth0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: false, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 1, minutes: 2, seconds: 3, frames: 4, milliseconds: 50 }, - }, - logs: [ '2025-08-07 14:00:00 [INFO] Timeturner offset is active.' ] - }, - badJitter: { - status: { - ltc_status: 'LOCK', - ltc_timecode: '15:15:15:15', - frame_rate: '25.00fps', - lock_ratio: 95.0, - system_clock: '15:15:15.515', - system_date: '2025-08-07', - ntp_active: true, - sync_status: 'IN SYNC', - timecode_delta_ms: 10, - timecode_delta_frames: 0.25, - jitter_status: 'BAD', - interfaces: ['192.168.1.100/24 (eth0)'], - }, - config: { - hardwareOffsetMs: 10, - autoSyncEnabled: true, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 0, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }, - }, - logs: [ '2025-08-07 15:15:00 [ERROR] High jitter detected on LTC source.' ] - }, - ntpInactive: { - status: { - ltc_status: 'UNKNOWN', - ltc_timecode: '--:--:--:--', - frame_rate: '--', - lock_ratio: 0, - system_clock: '16:00:00.000', - system_date: '2025-08-07', - ntp_active: false, - sync_status: 'UNKNOWN', - timecode_delta_ms: 0, - timecode_delta_frames: 0, - jitter_status: 'UNKNOWN', - interfaces: [], - }, - config: { - hardwareOffsetMs: 0, - autoSyncEnabled: false, - defaultNudgeMs: 2, - timeturnerOffset: { hours: 0, minutes: 0, seconds: 0, frames: 0, milliseconds: 0 }, - }, - logs: [ '2025-08-07 16:00:00 [INFO] NTP service is inactive.' ] - } -}; diff --git a/static/script.js b/static/script.js deleted file mode 100644 index 634ed33..0000000 --- a/static/script.js +++ /dev/null @@ -1,443 +0,0 @@ -ο»Ώdocument.addEventListener('DOMContentLoaded', () => { - // --- Mock Data Configuration --- - // Set to true to use mock data, false for live API. - const useMockData = false; - let currentMockSetKey = 'allGood'; // Default mock data set - - let lastApiData = null; - let lastApiFetchTime = null; - - const statusElements = { - ltcStatus: document.getElementById('ltc-status'), - ltcTimecode: document.getElementById('ltc-timecode'), - frameRate: document.getElementById('frame-rate'), - lockRatio: document.getElementById('lock-ratio'), - systemClock: document.getElementById('system-clock'), - systemDate: document.getElementById('system-date'), - ntpActive: document.getElementById('ntp-active'), - syncStatus: document.getElementById('sync-status'), - deltaStatus: document.getElementById('delta-status'), - jitterStatus: document.getElementById('jitter-status'), - deltaText: document.getElementById('delta-text'), - interfaces: document.getElementById('interfaces'), - logs: document.getElementById('logs'), - }; - - const hwOffsetInput = document.getElementById('hw-offset'); - const autoSyncCheckbox = document.getElementById('auto-sync-enabled'); - const offsetInputs = { - h: document.getElementById('offset-h'), - m: document.getElementById('offset-m'), - s: document.getElementById('offset-s'), - f: document.getElementById('offset-f'), - ms: document.getElementById('offset-ms'), - }; - const saveConfigButton = document.getElementById('save-config'); - const manualSyncButton = document.getElementById('manual-sync'); - const syncMessage = document.getElementById('sync-message'); - - const nudgeDownButton = document.getElementById('nudge-down'); - const nudgeUpButton = document.getElementById('nudge-up'); - const nudgeValueInput = document.getElementById('nudge-value'); - const nudgeMessage = document.getElementById('nudge-message'); - - const dateInput = document.getElementById('date-input'); - const setDateButton = document.getElementById('set-date'); - const dateMessage = document.getElementById('date-message'); - - // --- Collapsible Sections --- - const controlsToggle = document.getElementById('controls-toggle'); - const controlsContent = document.getElementById('controls-content'); - const logsToggle = document.getElementById('logs-toggle'); - const logsContent = document.getElementById('logs-content'); - - // --- Mock Controls Setup --- - const mockControls = document.getElementById('mock-controls'); - const mockDataSelector = document.getElementById('mock-data-selector'); - - function setupMockControls() { - if (useMockData) { - mockControls.style.display = 'block'; - - // Populate dropdown - Object.keys(mockApiDataSets).forEach(key => { - const option = document.createElement('option'); - option.value = key; - option.textContent = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); - mockDataSelector.appendChild(option); - }); - - mockDataSelector.value = currentMockSetKey; - - // Handle selection change - mockDataSelector.addEventListener('change', (event) => { - currentMockSetKey = event.target.value; - // Re-fetch all data from the new mock set - fetchStatus(); - fetchConfig(); - fetchLogs(); - }); - } - } - - function updateStatus(data) { - const ltcStatus = data.ltc_status || 'UNKNOWN'; - const ltcIconInfo = iconMap.ltcStatus[ltcStatus] || iconMap.ltcStatus.default; - statusElements.ltcStatus.innerHTML = ``; - statusElements.ltcStatus.className = ltcStatus.toLowerCase(); - statusElements.ltcTimecode.textContent = data.ltc_timecode; - - const frameRate = data.frame_rate || 'unknown'; - const frameRateIconInfo = iconMap.frameRate[frameRate] || iconMap.frameRate.default; - statusElements.frameRate.innerHTML = ``; - - const lockRatio = data.lock_ratio; - let lockRatioCategory; - if (lockRatio === 100) { - lockRatioCategory = 'good'; - } else if (lockRatio >= 90) { - lockRatioCategory = 'average'; - } else { - lockRatioCategory = 'bad'; - } - const lockRatioIconInfo = iconMap.lockRatio[lockRatioCategory]; - statusElements.lockRatio.innerHTML = ``; - statusElements.systemClock.textContent = data.system_clock; - statusElements.systemDate.textContent = data.system_date; - - // Autofill the date input, but don't overwrite user edits. - if (!lastApiData || dateInput.value === lastApiData.system_date) { - dateInput.value = data.system_date; - } - - const ntpIconInfo = iconMap.ntpActive[!!data.ntp_active]; - if (data.ntp_active) { - statusElements.ntpActive.innerHTML = ``; - statusElements.ntpActive.className = 'active'; - } else { - statusElements.ntpActive.innerHTML = ``; - statusElements.ntpActive.className = 'inactive'; - } - - const syncStatus = data.sync_status || 'UNKNOWN'; - const syncIconInfo = iconMap.syncStatus[syncStatus] || iconMap.syncStatus.default; - statusElements.syncStatus.innerHTML = ``; - statusElements.syncStatus.className = syncStatus.replace(/\s+/g, '-').toLowerCase(); - - // Delta Status - const deltaMs = data.timecode_delta_ms; - let deltaCategory; - if (deltaMs === 0) { - deltaCategory = 'good'; - } else if (Math.abs(deltaMs) < 10) { - deltaCategory = 'average'; - } else { - deltaCategory = 'bad'; - } - const deltaIconInfo = iconMap.deltaStatus[deltaCategory]; - statusElements.deltaStatus.innerHTML = ``; - - const deltaTextValue = `${data.timecode_delta_ms} ms (${data.timecode_delta_frames} frames)`; - statusElements.deltaText.textContent = `Ξ” ${deltaTextValue}`; - - const jitterStatus = data.jitter_status || 'UNKNOWN'; - const jitterIconInfo = iconMap.jitterStatus[jitterStatus] || iconMap.jitterStatus.default; - statusElements.jitterStatus.innerHTML = ``; - statusElements.jitterStatus.className = jitterStatus.toLowerCase(); - - if (data.interfaces.length > 0) { - statusElements.interfaces.textContent = data.interfaces.join(' | '); - } else { - statusElements.interfaces.textContent = 'No active interfaces found.'; - } - } - - function animateClocks() { - if (!lastApiData || !lastApiFetchTime) return; - - const elapsedMs = new Date() - lastApiFetchTime; - - // Animate System Clock - if (lastApiData.system_clock && lastApiData.system_clock.includes(':')) { - const parts = lastApiData.system_clock.split(/[:.]/); - if (parts.length === 4) { - const baseDate = new Date(); - baseDate.setHours(parseInt(parts[0], 10), parseInt(parts[1], 10), parseInt(parts[2], 10)); - baseDate.setMilliseconds(parseInt(parts[3], 10)); - - const newDate = new Date(baseDate.getTime() + elapsedMs); - - const h = String(newDate.getHours()).padStart(2, '0'); - const m = String(newDate.getMinutes()).padStart(2, '0'); - const s = String(newDate.getSeconds()).padStart(2, '0'); - const ms = String(newDate.getMilliseconds()).padStart(3, '0'); - statusElements.systemClock.textContent = `${h}:${m}:${s}.${ms}`; - } - } - - // Animate LTC Timecode - only if status is LOCK - if (lastApiData.ltc_status === 'LOCK' && lastApiData.ltc_timecode && lastApiData.ltc_timecode.match(/[:;]/) && lastApiData.frame_rate) { - const separator = lastApiData.ltc_timecode.includes(';') ? ';' : ':'; - const tcParts = lastApiData.ltc_timecode.split(/[:;]/); - const frameRate = parseFloat(lastApiData.frame_rate); - - if (tcParts.length === 4 && !isNaN(frameRate) && frameRate > 0) { - let h = parseInt(tcParts[0], 10); - let m = parseInt(tcParts[1], 10); - let s = parseInt(tcParts[2], 10); - let f = parseInt(tcParts[3], 10); - - const msPerFrame = 1000.0 / frameRate; - const elapsedFrames = Math.floor(elapsedMs / msPerFrame); - - f += elapsedFrames; - - const frameRateInt = Math.round(frameRate); - - s += Math.floor(f / frameRateInt); - f %= frameRateInt; - - m += Math.floor(s / 60); - s %= 60; - - h += Math.floor(m / 60); - m %= 60; - - h %= 24; - - statusElements.ltcTimecode.textContent = - `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}${separator}${String(f).padStart(2, '0')}`; - } - } - } - - async function fetchStatus() { - if (useMockData) { - const data = mockApiDataSets[currentMockSetKey].status; - updateStatus(data); - lastApiData = data; - lastApiFetchTime = new Date(); - return; - } - try { - const response = await fetch('/api/status'); - if (!response.ok) throw new Error('Failed to fetch status'); - const data = await response.json(); - updateStatus(data); - lastApiData = data; - lastApiFetchTime = new Date(); - } catch (error) { - console.error('Error fetching status:', error); - lastApiData = null; - lastApiFetchTime = null; - } - } - - async function fetchConfig() { - if (useMockData) { - const data = mockApiDataSets[currentMockSetKey].config; - hwOffsetInput.value = data.hardwareOffsetMs; - autoSyncCheckbox.checked = data.autoSyncEnabled; - offsetInputs.h.value = data.timeturnerOffset.hours; - offsetInputs.m.value = data.timeturnerOffset.minutes; - offsetInputs.s.value = data.timeturnerOffset.seconds; - offsetInputs.f.value = data.timeturnerOffset.frames; - offsetInputs.ms.value = data.timeturnerOffset.milliseconds || 0; - nudgeValueInput.value = data.defaultNudgeMs; - return; - } - try { - const response = await fetch('/api/config'); - if (!response.ok) throw new Error('Failed to fetch config'); - const data = await response.json(); - hwOffsetInput.value = data.hardwareOffsetMs; - autoSyncCheckbox.checked = data.autoSyncEnabled; - offsetInputs.h.value = data.timeturnerOffset.hours; - offsetInputs.m.value = data.timeturnerOffset.minutes; - offsetInputs.s.value = data.timeturnerOffset.seconds; - offsetInputs.f.value = data.timeturnerOffset.frames; - offsetInputs.ms.value = data.timeturnerOffset.milliseconds || 0; - nudgeValueInput.value = data.defaultNudgeMs; - } catch (error) { - console.error('Error fetching config:', error); - } - } - - async function saveConfig() { - const config = { - hardwareOffsetMs: parseInt(hwOffsetInput.value, 10) || 0, - autoSyncEnabled: autoSyncCheckbox.checked, - defaultNudgeMs: parseInt(nudgeValueInput.value, 10) || 0, - timeturnerOffset: { - hours: parseInt(offsetInputs.h.value, 10) || 0, - minutes: parseInt(offsetInputs.m.value, 10) || 0, - seconds: parseInt(offsetInputs.s.value, 10) || 0, - frames: parseInt(offsetInputs.f.value, 10) || 0, - milliseconds: parseInt(offsetInputs.ms.value, 10) || 0, - } - }; - - if (useMockData) { - console.log('Mock save:', config); - alert('Configuration saved (mock).'); - // We can also update the mock data in memory to see changes reflected - mockApiDataSets[currentMockSetKey].config = config; - return; - } - - try { - const response = await fetch('/api/config', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(config), - }); - if (!response.ok) throw new Error('Failed to save config'); - alert('Configuration saved.'); - } catch (error) { - console.error('Error saving config:', error); - alert('Error saving configuration.'); - } - } - - async function fetchLogs() { - if (useMockData) { - // Use a copy to avoid mutating the original mock data array - const logs = mockApiDataSets[currentMockSetKey].logs.slice(); - // Show latest 20 logs, with the newest at the top. - logs.reverse(); - statusElements.logs.textContent = logs.slice(0, 20).join('\n'); - return; - } - try { - const response = await fetch('/api/logs'); - if (!response.ok) throw new Error('Failed to fetch logs'); - const logs = await response.json(); - // Show latest 20 logs, with the newest at the top. - logs.reverse(); - statusElements.logs.textContent = logs.slice(0, 20).join('\n'); - } catch (error) { - console.error('Error fetching logs:', error); - statusElements.logs.textContent = 'Error fetching logs.'; - } - } - - async function triggerManualSync() { - syncMessage.textContent = 'Issuing sync command...'; - if (useMockData) { - syncMessage.textContent = 'Success: Manual sync triggered (mock).'; - setTimeout(() => { syncMessage.textContent = ''; }, 5000); - return; - } - try { - const response = await fetch('/api/sync', { method: 'POST' }); - const data = await response.json(); - if (response.ok) { - syncMessage.textContent = `Success: ${data.message}`; - } else { - syncMessage.textContent = `Error: ${data.message}`; - } - } catch (error) { - console.error('Error triggering sync:', error); - syncMessage.textContent = 'Failed to send sync command.'; - } - setTimeout(() => { syncMessage.textContent = ''; }, 5000); - } - - async function nudgeClock(ms) { - nudgeMessage.textContent = 'Nudging clock...'; - if (useMockData) { - nudgeMessage.textContent = `Success: Clock nudged by ${ms}ms (mock).`; - setTimeout(() => { nudgeMessage.textContent = ''; }, 3000); - return; - } - try { - const response = await fetch('/api/nudge_clock', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ microseconds: ms * 1000 }), - }); - const data = await response.json(); - if (response.ok) { - nudgeMessage.textContent = `Success: ${data.message}`; - } else { - nudgeMessage.textContent = `Error: ${data.message}`; - } - } catch (error) { - console.error('Error nudging clock:', error); - nudgeMessage.textContent = 'Failed to send nudge command.'; - } - setTimeout(() => { nudgeMessage.textContent = ''; }, 3000); - } - - async function setDate() { - const date = dateInput.value; - if (!date) { - alert('Please select a date.'); - return; - } - - dateMessage.textContent = 'Setting date...'; - if (useMockData) { - mockApiDataSets[currentMockSetKey].status.system_date = date; - dateMessage.textContent = `Success: Date set to ${date} (mock).`; - fetchStatus(); // re-render - setTimeout(() => { dateMessage.textContent = ''; }, 5000); - return; - } - try { - const response = await fetch('/api/set_date', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ date: date }), - }); - const data = await response.json(); - if (response.ok) { - dateMessage.textContent = `Success: ${data.message}`; - // Fetch status again to update the displayed date immediately - fetchStatus(); - } else { - dateMessage.textContent = `Error: ${data.message}`; - } - } catch (error) { - console.error('Error setting date:', error); - dateMessage.textContent = 'Failed to send date command.'; - } - setTimeout(() => { dateMessage.textContent = ''; }, 5000); - } - - saveConfigButton.addEventListener('click', saveConfig); - manualSyncButton.addEventListener('click', triggerManualSync); - nudgeDownButton.addEventListener('click', () => { - const ms = parseInt(nudgeValueInput.value, 10) || 0; - nudgeClock(-ms); - }); - nudgeUpButton.addEventListener('click', () => { - const ms = parseInt(nudgeValueInput.value, 10) || 0; - nudgeClock(ms); - }); - setDateButton.addEventListener('click', setDate); - - // --- Collapsible Section Listeners --- - controlsToggle.addEventListener('click', () => { - const isActive = controlsContent.classList.toggle('active'); - controlsToggle.classList.toggle('active', isActive); - }); - - logsToggle.addEventListener('click', () => { - const isActive = logsContent.classList.toggle('active'); - logsToggle.classList.toggle('active', isActive); - }); - - // Initial data load - setupMockControls(); - fetchStatus(); - fetchConfig(); - fetchLogs(); - - // Refresh data every 2 seconds if not using mock data - if (!useMockData) { - setInterval(fetchStatus, 2000); - setInterval(fetchLogs, 2000); - } - setInterval(animateClocks, 50); // High-frequency clock animation -}); diff --git a/static/style.css b/static/style.css deleted file mode 100644 index bc53cce..0000000 --- a/static/style.css +++ /dev/null @@ -1,273 +0,0 @@ -@font-face { - font-family: 'FuturaStdHeavy'; - src: url('assets/FuturaStdHeavy.otf') format('opentype'); -} - -@font-face { - font-family: 'Quartz'; - src: url('assets/quartz-ms-regular.ttf') format('truetype'); -} - -body { - font-family: 'FuturaStdHeavy', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - background-color: #221f1f; - background-image: url('assets/HaveBlueTransWh.png'); - background-repeat: no-repeat; - background-position: bottom 20px right 20px; - background-attachment: fixed; - background-size: 100px; - color: #333; - margin: 0; - padding: 20px; - display: flex; - justify-content: center; -} - -.container { - width: 100%; - max-width: 960px; -} - -.header-logo { - display: block; - margin: 0 auto 20px auto; - max-width: 60%; -} - -.grid { - display: grid; - grid-template-columns: 1fr; - gap: 20px; -} - -.card { - background: #c5ced6; - border-radius: 8px; - padding: 20px; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); -} - -.card h2 { - margin-top: 0; - color: #1a7db6; -} - -#ltc-timecode, #system-clock { - font-family: 'Quartz', monospace; - font-size: 2em; - text-align: center; - letter-spacing: 2px; -} - -.card p, .card ul { - margin: 10px 0; -} - -.system-date-display { - text-align: center; - font-size: 1.5em; - font-family: 'Quartz', monospace; - letter-spacing: 2px; -} - -#interfaces { - text-align: center; - white-space: nowrap; - overflow-x: auto; - padding-bottom: 5px; /* Add some space for the scrollbar if it appears */ -} - -.full-width { - grid-column: 1 / -1; -} - -.control-group { - margin-bottom: 15px; - display: flex; - align-items: center; - gap: 10px; -} - -input[type="number"], -input[type="text"] { - padding: 8px; - border: 1px solid #9fb3c8; - border-radius: 4px; - background-color: #f0f4f8; - font-family: inherit; - font-size: 14px; - color: #333; - transition: border-color 0.2s, box-shadow 0.2s; -} - -input[type="number"]:focus, -input[type="text"]:focus { - outline: none; - border-color: #1a7db6; - box-shadow: 0 0 0 2px rgba(26, 125, 182, 0.2); -} - -input[type="number"] { - width: 80px; -} - -input[type="text"] { - width: auto; -} - -button { - padding: 8px 15px; - border: none; - border-radius: 4px; - background-color: #1a7db6; - color: white; - cursor: pointer; - font-size: 14px; - font-family: Arial, sans-serif; - font-weight: bold; - transition: background-color 0.2s; -} - -button:hover { - background-color: #166999; -} - -.offset-controls-container { - display: flex; - flex-wrap: wrap; - gap: 1.5rem; - align-items: center; -} - -.offset-control { - display: flex; - align-items: center; - gap: 5px; -} - -.offset-control input[type="number"] { - width: 40px; - text-align: center; -} - -.offset-control label { - font-size: 14px; - color: #333; -} - -#offset-ms { - width: 60px; -} - -#sync-message { - font-style: italic; - color: #555; -} - -.icon-group { - display: flex; - justify-content: center; - align-items: center; - gap: 20px; - margin: 10px 0; -} - -#delta-text { - text-align: center; -} - -#ltc-status, #ntp-active, #sync-status, #jitter-status, #frame-rate, #lock-ratio, #delta-status { - display: flex; - justify-content: center; - align-items: center; -} - -.status-icon { - width: 60px; - height: 60px; -} - -.collapsible-card { - padding: 0; -} - -.collapsible-card .toggle-header { - display: flex; - align-items: center; - gap: 15px; - padding: 20px; - cursor: pointer; - border-radius: 8px; -} - -.collapsible-card .toggle-header.active { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-bottom: 1px solid #eee; -} - -.collapsible-card .toggle-header:hover { - background-color: #e9e9f3; -} - -.toggle-icon { - width: 40px; - height: 40px; -} - -.header-icon { - width: 40px; - height: 40px; -} - -.card-header { - display: flex; - align-items: center; - gap: 15px; -} - -.log-box { - white-space: pre-wrap; - overflow-wrap: break-word; -} - -.collapsible-content { - display: none; - padding: 20px; -} - -.collapsible-content.active { - display: block; -} - -footer { - text-align: center; - margin-top: 40px; - padding-top: 20px; - border-top: 1px solid #444; - color: #c5ced6; -} - -footer p { - margin: 0; -} - -footer a { - color: #1a7db6; - text-decoration: none; -} - -footer a:hover { - text-decoration: underline; -} - -/* Status-specific colors */ -#sync-status.in-sync, #jitter-status.good { font-weight: bold; color: #28a745; } -#sync-status.clock-ahead, #sync-status.clock-behind, #jitter-status.average { font-weight: bold; color: #ffc107; } -#sync-status.timeturning { font-weight: bold; color: #17a2b8; } -#jitter-status.bad { font-weight: bold; color: #dc3545; } -#ntp-active.active { font-weight: bold; color: #28a745; } -#ntp-active.inactive { font-weight: bold; color: #dc3545; } - -#ltc-status.lock { font-weight: bold; color: #28a745; } -#ltc-status.free { font-weight: bold; color: #ffc107; } diff --git a/timeturner.py b/timeturner.py index 49fe40b..92f8cb2 100644 --- a/timeturner.py +++ b/timeturner.py @@ -9,11 +9,10 @@ import threading import queue import json from collections import deque -from fractions import Fraction SERIAL_PORT = None BAUD_RATE = 115200 -FRAME_RATE = Fraction(25, 1) +FRAME_RATE = 25.0 CONFIG_PATH = "config.json" sync_pending = False @@ -31,14 +30,6 @@ sync_enabled = False last_match_check = 0 timecode_match_status = "UNKNOWN" -def framerate_str_to_fraction(s): - if s == "23.98": return Fraction(24000, 1001) - if s == "24.00": return Fraction(24, 1) - if s == "25.00": return Fraction(25, 1) - if s == "29.97": return Fraction(30000, 1001) - if s == "30.00": return Fraction(30, 1) - return None - def load_config(): global hardware_offset_ms try: @@ -59,16 +50,13 @@ def parse_ltc_line(line): if not match: return None status, hh, mm, ss, ff, fps = match.groups() - rate = framerate_str_to_fraction(fps) - if not rate: - return None return { "status": status, "hours": int(hh), "minutes": int(mm), "seconds": int(ss), "frames": int(ff), - "frame_rate": rate + "frame_rate": float(fps) } def serial_thread(port, baud, q): @@ -166,7 +154,7 @@ def run_curses(stdscr): parsed, arrival_time = latest_ltc stdscr.addstr(3, 2, f"LTC Status : {parsed['status']}") stdscr.addstr(4, 2, f"LTC Timecode : {parsed['hours']:02}:{parsed['minutes']:02}:{parsed['seconds']:02}:{parsed['frames']:02}") - stdscr.addstr(5, 2, f"Frame Rate : {float(FRAME_RATE):.2f}fps") + stdscr.addstr(5, 2, f"Frame Rate : {FRAME_RATE:.2f}fps") stdscr.addstr(6, 2, f"System Clock : {format_time(get_system_time())}") if ltc_locked and sync_enabled and offset_history: diff --git a/timeturner.service b/timeturner.service deleted file mode 100644 index f3daec8..0000000 --- a/timeturner.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=NTP TimeTurner Daemon -After=network.target - -[Service] -Type=forking -# The 'timeturner daemon' command starts the background process. -# It requires 'config.yml' and the 'static/' web assets directory -# to be present in the WorkingDirectory. -ExecStart=/opt/timeturner/timeturner daemon -WorkingDirectory=/opt/timeturner -PIDFile=/opt/timeturner/ntp_timeturner.pid -Restart=always -User=root -Group=root - -[Install] -WantedBy=multi-user.target diff --git a/update.sh b/update.sh deleted file mode 100644 index ad9fcb9..0000000 --- a/update.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -set -e - -echo "--- TimeTurner Update Script ---" - -# 1. Fetch the latest changes from the git repository -echo "πŸ”„ Pulling latest changes from GitHub..." -git pull origin main - -# 2. Rebuild the release binary -echo "πŸ“¦ Building release binary with Cargo..." -cargo build --release - -# 3. Stop the currently running service to release the file lock -echo "πŸ›‘ Stopping TimeTurner service..." -sudo systemctl stop timeturner.service || true - -# 4. Copy the new binary to the installation directory -echo "πŸš€ Deploying new binary..." -sudo cp target/release/ntp_timeturner /opt/timeturner/timeturner - -# 5. Restart the service with the new binary -echo "βœ… Restarting TimeTurner service..." -sudo systemctl restart timeturner.service - -echo "" -echo "Update complete. To check the status of the service, run:" -echo " systemctl status timeturner.service" \ No newline at end of file