diff options
Diffstat (limited to 'spaghetti-monster')
191 files changed, 0 insertions, 31917 deletions
diff --git a/spaghetti-monster/COPYING b/spaghetti-monster/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/spaghetti-monster/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - 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. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -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: - - <program> Copyright (C) <year> <name of author> - 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 -<http://www.gnu.org/licenses/>. - - 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 -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/spaghetti-monster/anduril/BRANDS b/spaghetti-monster/anduril/BRANDS deleted file mode 100644 index 059f311..0000000 --- a/spaghetti-monster/anduril/BRANDS +++ /dev/null @@ -1,11 +0,0 @@ -Vendor / Model IDs for version check function - -Undefined 0000 -Emisar 0100 - 0199 -Noctigon 0200 - 0199 -Lumintop 0300 - 0399 -Fireflies 0400 - 0499 -Mateminco 0500 - 0599 -Sofirn 0600 - 0699 -Wurkkos 0700 - 0799 -gChart 1600 - 1699 diff --git a/spaghetti-monster/anduril/ChangeLog.md b/spaghetti-monster/anduril/ChangeLog.md deleted file mode 100644 index 0aaa392..0000000 --- a/spaghetti-monster/anduril/ChangeLog.md +++ /dev/null @@ -1,245 +0,0 @@ -# ChangeLog - -Items should be sorted roughly in order of most to least important, with -model-specific changes at the bottom. Most items should use one of these -formats: - - - Breaking change: - - Added - - Fixed - - Removed - - Changed - - Documented - - @brand-model: Hardware-specific change (NNNN, NNNN, ...) - -# Next - -# 2023-10-31 - -General: - -- Finally finished converting all lights to the multi-channel API. - (but a few are untested due to hardware being unavailable) -- Enabled smooth steps on almost all supported lights, including old ones. - (in some cases, on old t85 lights, some other things may have been removed - to make room) -- Made smooth steps work better, and fixed several bugs. -- Added/fixed RGB aux voltage on dual-fuel AA/li-ion drivers. -- Fixed delay timing on all supported MCUs, so 1 "second" is closer to an - actual second (like in beacon mode or biking mode). - (especially attiny1616, which was 17% too slow) -- Raised default thermal limit to 50C on attiny1616-based lights, since - it doesn't need as big an error margin as older MCUs. -- Fixed missing item in globals menu on some lights. -- Misc internal improvements and per-light tweaks. -- Added a ChangeLog.md, to periodically summarize changes in a format which is - more readable than the raw commit logs. - -New lights: - -- @thefreeman-boost21-6a: Added. (1631) - (very nice HDR boost driver which fits into a FW3A) -- @thefreeman-boost-fwaa: Added. (1632) - (very nice AA/li-ion HDR boost driver which fits into a FWAA) - -Hardware-specific changes: - -- Upgraded several builds to use delta-sigma modulation (DSM), for - lower lows and smoother ramping with less flicker or ripple: - - @blf-lt1 (0621) - - @blf-lt1-t1616 (0622) - - @emisar-d4k-3ch (0151) - (**dramatically** improves resolution and low modes on its 8-bit channel) - - @noctigon-dm11-boost (0273) - - @noctigon-kr4-boost (0216) - - @noctigon-k1-boost (0253) - - @noctigon-m44 (0143) - -- Upgraded some builds to use dynamic PWM, for lower lows and smoother ramping: - - @blf-q8-t1616, @sofirn-sp36-t1616 (0613, 0614) - - @gchart-fet1-t1616 (1618) - - @noctigon-k1-sbt90 (0252) - -- @wurkkos-ts10, @wurkkos-ts10-rgbaux: Fixed too-high default ceiling. (0713, 0714) - -# 2023-10-01 - -General: - -- Updated a bunch of lights to work with the new multi-channel API. -- Added "smooth steps" a.k.a. "soft start", to make on/off and step changes - smooth. (enabled by default, can be turned off in Ramp Extras menu) -- User can save a different channel mode for each strobe-group mode. -- Made strobes/blinkies more responsive in Tactical Mode. -- Fixed bug: Tactical Mode clobbers strobe group memory. -- Fixed some minor post-off voltage display bugs. -- Made RGB button brightness update faster in blinky modes. -- Fixed bug: Wrong channel after colored factory reset. -- @attiny1616, @attiny1634: Partially fixed oscillating aux LED voltage - colors while off. Better than before, but can still happen in some cases. -- @attiny1616: Fixed spurious voltage warnings in sleep mode. (it could - sometimes go from Lockout mode to Off mode by itself) -- Lots of internal refactoring. - -New lights: - -- @emisar-2ch-fet: Added. (0136) -- @emisar-d4k-3ch: Added. (0151) -- @noctigon-m44: Added. (0143) -- @wurkkos-ts10-rgbaux: Added. (0713) - -Hardware-specific changes: - -- @ff-e01, @ff-pl47, @ff-pl47g2: Enabled smooth steps instead of SOS mode. - (0421, 0422, 0423, 0441) -- @emisar-2ch, @noctigon-m44: Added RGB aux channel modes. (0135, 0143) -- @emisar-2ch-fet, @noctigon-k9.3: New ramps with better-calibrated shape. - (0136, 0261) -- @emisar-d4v2-nofet: New ramp table. (0115) -- @emisar-d4sv2-tintramp: Removed / renamed. (0135, 0136) -- @noctigon-k9.3: Fixed years-old mess. Merged builds, converted to - multi-channel, removed old builds, generally got K9.3 working quite a bit - better. (0261, 0262, 0263, 0265, 0266, 0267) -- @noctigon-m44: Lower moon, and greatly reduced flicker. (0143) -- @sofirn-lt1s-pro: Allow configuring the blink channel. (0623) -- @wurkkos: Raised default temperature limit to 50 C. (07xx) -- @wurkkos-ts10: Better / smoother ramp. (0713, 0714) - -# 2023-06-29 - -- Fixed red aux blink on 1st frame of post-off voltage display -- Removed Harry Potter references because its author (J.K. Rowling) spreads - hate -- @noctigon-kr4: Fixed thermal regulation (0211, 0212, 0213, 0214, 0215, 0216) - -# 2023-05-30 - -- Breaking change: Changed version check from YYYYMMDDXXXX to XXXX.YYYY-MM-DD, - where the punctuation makes a "buzz" instead of number blinks. -- Fixed issue where some lights always thought they were overheating (when - cold, or after a factory reset) -- Fixed aux pre-flash -- Fixed a rare corner case where gradual brightness adjustments stopped at 99% - power instead of 100% power while going up from level 149/150 to 150/150 on - some lights -- Changed "0" digit readout to use the same timing as other short blinks, to - help ensure it works on all lights. -- Minor code changes with no runtime impact -- Documented new version check format -- @wurkkos: Added red+blue police strobe (0715, 0716, 0717) -- @noctigon-kr4: Broke thermal regulation (oops) (0211, 0212, 0213, 0214, - 0215, 0216) -- @noctigon-kr4: Use 7 aux channel modes instead of 3 (0211, 0212, 0213, 0214, - 0215, 0216) -- @emisar-d4v2: Changed number blinks from aux to main LEDs by default (0113, - 0114, 0115, 0123) - -# 2023-05-17 - -- @noctigon-dm11-12v: Renamed to noctigon-dm11-boost (0273) -- @noctigon-dm11-boost: Now supported in multi-channel branch (0273) - -# 2023-05-02 - -- Added ability to set channel mode for number readouts (batt check, temp - check, version check). Press 3C in batt check mode to change the blink - channel. -- Changed post-off voltage display: - - Display for 4s by default, not 5s - - Made timing user-configurable in battcheck 7H menu item 2 - (1 click per second the display should last) - - Use low brightness when torch was at moon level before - - Skip the voltage display after UI actions which didn't change the mode - (like "Off -> 7C" to change aux LED settings) -- Changed RGB button behavior: While torch is on, use low mode below a - configured level for real-time voltage color display, instead of always - using high mode -- Fixed bug: Channel change could stick when activating a config menu from - battcheck (the blink function changed the channel, then the config menu - saved it, then the blink function restored it, then the config menu restored - it to the value it saved, which was wrong) -- Documented ramp 6C, ramp 4C, ramp 4H, lockout 3H, battcheck 3C, and post-off - voltage display config -- @emisar-d4v2: Added the rest of the aux RGB colors as channel modes, and set - aux "white" as the mode it uses to blink out numbers (0113, 0114, 0115, - 0123) -- @wurkkos-ts10: Converted to multi-channel, and gave it a new ramp with - better low modes (0714) -- @wurkkos-ts25: Converted to multi-channel, and gave it a smoother ramp - (0715) -- @wurkkos: Added Wurkkos FC13 and TS11 (0716, 0717) - -# 2023-04-29 - -- Changed lockout mode: - - Fixed manual memory timer and tint - - Added 3H for next channel (to change channels without unlocking, was - possible before but needed to be updated for the new channel system) - - Made 3H+ use mem level instead of lowest moon (this is needed for - making the channel discernible, and also helps make aux LED controls - stand out more) -- @emisar, @noctigon: Added Extended Simple UI to Hank's config, so a few more - features are allowed in simple mode -- @emisar-d4v2, @noctigon-kr4: Slightly smaller ROM size -- @emisar-d4sv2: Converted to multi-channel, and updated it to use dynamic PWM - for a smoother ramp with lower lows (0133, 0134) -- @noctigon-kr4: Converted to multi-channel (0211, 0212, 0213, 0214) -- @noctigon-kr4: Don't blink at top of regulated power (0211, 0213, 0214) - -# 2023-04-28 - -- Added voltage display (by color) on RGB aux LEDs after turning the main LEDs - off -- Changed RGB aux: Always preview in high mode while changing color or pattern -- Changed default RGB aux color in lockout mode: Uses blinking voltage, - instead of blinking disco (unless model-specific config defines a different - default) -- Changed tactical mode default config: only use 2-color strobe if it's on - main LEDs, not aux LEDs -- @emisar-d4v2: Smoother ramp (0113, 0114) -- @emisar-d4v2: Added hidden channel modes for RGB aux LEDs (0113, 0114, 0115) - -# 2023-04-27 - -- Changed channel mode menu to preview channels during configuration -- Changed tactical mode default config: use 2-color police strobe if it - exists, instead of single-color strobe -- Fixed unnecessary flickering when changing channel modes from/to the same - value -- Fixed sleep voltage measurement on attiny1616 -- @noctigon-kr4-tintramp: Converted to multi-channel, renamed to - noctigon-kr4-2ch (0215) - -# 2023-04-25 - -- Fixed old old bug(s) with voltage measurement while asleep, while also - adding other improvements: - - Fixed oscillating RGB aux colors while asleep in voltage mode, mostly. - Some much smaller oscillations are still possible, but the primary issue - has been fixed, I think. - - Fixed old old bug which could cause spurious low-voltage warnings while - asleep (previously required a messy code workaround). - - Reduced avg standby power by ~15uA. - - Now measures voltage every 1s instead of 8s while asleep. - - Changed RGB aux behavior: Puts aux LEDs in high mode for 3 seconds after - light goes to sleep (much easier to see the voltage this way) - (this change was obsoleted soon by a better post-off voltage display) - - Broke sleep voltage measurement on attiny1616 (oops) -- Changed internal details for how gradual ramping works -- @emisar-d4sv2-tintramp: Converted to multi-channel, renamed to emisar-2ch. - (0135) -- @sofirn-lt1s-pro: Updated to use today's new code internals (0623) - -# 2023-04-19 - -- Added stepped tint ramping -- Documented new channel modes system -- @sofirn-lt1s-pro: Added white-only auto-tint mode (0623) - -# Older: TODO - -- Need to import old commit logs as changelog items - - -<!-- vim: set textwidth=78 shiftwidth=2 --> - diff --git a/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS deleted file mode 100644 index f4e9fdf..0000000 --- a/spaghetti-monster/anduril/MODELS +++ /dev/null @@ -1,85 +0,0 @@ -Model Name MCU ------ ---- --- -0111 emisar-d4 attiny85 -0112 emisar-d4-219c attiny85 -0113 emisar-d4v2 attiny1634 -0114 emisar-d4v2-219 attiny1634 -0115 emisar-d4v2-nofet attiny1634 -0121 emisar-d1 attiny85 -0122 emisar-d1s attiny85 -0123 emisar-d1v2-7135-fet attiny1634 -0124 emisar-d1v2-linear-fet attiny1634 -0125 emisar-d1v2-nofet attiny1634 -0131 emisar-d4s attiny85 -0132 emisar-d4s-219c attiny85 -0133 emisar-d4sv2 attiny1634 -0134 emisar-d4sv2-219 attiny1634 -0135 emisar-2ch attiny1634 -0135 emisar-d4sv2-tintramp attiny1634 (old) -0136 emisar-2ch-fet attiny1634 -0136 emisar-d4sv2-tintramp-fet attiny1634 (old) -0141 emisar-d18 attiny85 -0142 emisar-d18-219 attiny85 -0143 noctigon-m44 attiny1634 -0151 emisar-d4k-3ch attiny1634 -0211 noctigon-kr4 attiny1634 -0212 noctigon-kr4-nofet attiny1634 -0213 noctigon-kr4-219 attiny1634 -0214 noctigon-kr4-219b attiny1634 -0215 noctigon-kr4-2ch attiny1634 -0215 noctigon-kr4-tintramp attiny1634 (old) -0216 noctigon-kr4-boost attiny1634 -0216 noctigon-kr4-12v attiny1634 (old) -0251 noctigon-k1 attiny1634 -0252 noctigon-k1-sbt90 attiny1634 -0253 noctigon-k1-boost attiny1634 -0253 noctigon-k1-12v attiny1634 (old) -0261 noctigon-k9.3 attiny1634 -0262 noctigon-k9.3-nofet attiny1634 -0263 noctigon-k9.3-219 attiny1634 -0265 noctigon-k9.3-tintramp-nofet attiny1634 (old, use 0262) -0266 noctigon-k9.3-tintramp-fet attiny1634 (old, use 0261) -0267 noctigon-k9.3-tintramp-219 attiny1634 (old, use 0263) -0271 noctigon-dm11 attiny1634 -0272 noctigon-dm11-nofet attiny1634 -0273 noctigon-dm11-boost attiny1634 -0273 noctigon-dm11-12v attiny1634 (old) -0274 noctigon-dm11-sbt90 attiny1634 -0311 fw3a attiny85 -0312 fw3a-219 attiny85 -0313 fw3a-nofet attiny85 -0314 fw3x-lume1 attiny1634 -0321 blf-gt attiny85 -0322 blf-gt-mini attiny85 -0411 ff-rot66 attiny85 -0412 ff-rot66-219 attiny85 -0413 ff-rot66g2 attiny85 -0421 ff-pl47 attiny85 -0422 ff-pl47-219 attiny85 -0423 ff-pl47g2 attiny85 -0441 ff-e01 attiny85 -0511 mateminco-mf01s attiny85 -0521 mateminco-mf01-mini attiny85 -0531 mateminco-mt35-mini attiny85 -0611 blf-q8 attiny85 -0612 sofirn-sp36 attiny85 -0613 blf-q8-t1616 attiny1616 -0614 sofirn-sp36-t1616 attiny1616 -0621 blf-lantern attiny85 -0622 blf-lantern-t1616 attiny1616 -0623 sofirn-lt1s-pro attiny1616 -0631 sofirn-sp10-pro attiny1616 -0632 sofirn-sc21-pro attiny1616 -0713 wurkkos-ts10-rgbaux attiny1616 -0714 wurkkos-ts10 attiny1616 -0715 wurkkos-ts25 attiny1616 -0716 wurkkos-fc13 attiny1616 -0717 wurkkos-ts11 attiny1616 -1618 gchart-fet1-t1616 attiny1616 -1630 thefreeman-lin16dac attiny1616 -1631 thefreeman-boost21-6a attiny1616 -1632 thefreeman-boost-fwaa attiny1616 - -Duplicates: - -Missing: diff --git a/spaghetti-monster/anduril/Makefile b/spaghetti-monster/anduril/Makefile deleted file mode 100644 index 332f0f3..0000000 --- a/spaghetti-monster/anduril/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all: - ./build-all.sh - -clean: - rm -f *.hex *~ *.elf *.o - -todo: - @egrep 'TODO:|FIXME:' *.[ch] - -models: - @./models.py > MODELS - @cat MODELS - -.phony: clean todo diff --git a/spaghetti-monster/anduril/anduril-manual.txt b/spaghetti-monster/anduril/anduril-manual.txt deleted file mode 100644 index 545af0f..0000000 --- a/spaghetti-monster/anduril/anduril-manual.txt +++ /dev/null @@ -1,994 +0,0 @@ -Anduril User Manual -------------------- - -Anduril is an open-source firmware for flashlights, distributed under -the terms of the GPL v3. The sources can be obtained here: - - http://tiny.cc/TKAnduril - https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/files/head:/ToyKeeper/spaghetti-monster/anduril/ - - -Quick Start ------------ - -After putting a battery in the light and tightening the parts together, -the light should quickly blink once to confirm it has power and is now -operational. After that, basic usage is simple: - - - Click to turn the light on or off. - - Hold the button to change brightness. - - Release and hold again to change brightness the other way. - -That is all the user needs to know for basic use, but there are many -more modes and features available for people who want more. - -Before reading the rest of this manual, it is recommended that users -look at the Anduril UI diagram(s), which should be provided along with the -flashlight. - - -Button presses --------------- - -Button presses are abbreviated using a simple notation: - - - 1C: One click. Press and then quickly release the button. - - 1H: Hold. Press the button, but keep holding it. - - 2C: Two clicks. Press and release quickly, twice. - - 2H: Click, hold. Click two times, but hold the second press. - - 3C: Three clicks. Press and release quickly, three times. - - 3H: Click, click, hold. Click three times, but hold the final press. - -The same pattern is used with higher numbers too. For example, 10C -means ten clicks... and 10H means ten clicks but hold the final press. - - -Simple UI ---------- - -By default, the light uses a simple UI. This is useful if you lend the -light to someone else, or if you just don't want to bother with any -crazy disco modes. - -Simple UI has all the basic functions needed to work as a flashlight, -but the minimum and maximum brightness are limited by default to make it -safer, and any complex or advanced functions are blocked. - -Functions available in Simple UI include: - - - 1C: On / off - - 1H: Ramp up (or down, if button was released less than a second ago) - - 2H: If light is on : ramp down - If light is off: momentary high mode - - 2C: Double click to go to / from highest safe level - - 4C: Lockout mode. - -Some other modes and functions are available too. When the light is -off, these are the options: - - - 3C: Battery check mode. (displays voltage once, then turns off) - - 4C: Lockout mode. - - 10H: Switch to Advanced UI. - - 15C or more: Version check. - -In Lockout mode with Simple UI, there are a few functions: - - - 1H: Momentary moon - - 2H: Momentary low - - 3C: Unlock and turn off - - 4C: Unlock and turn on - - 4H: Unlock and turn on at low level - - 5C: Unlock and turn on at high level - -To change between Simple UI and Advanced UI, turn the light off and then -do one of these: - - In Simple UI: - - 10H: Go to Advanced UI. - - In Advanced UI: - - 10C: Go to Simple UI. - - 10H: Configure Simple UI. - -If you get lost, or if you want to auto-calibrate the temperature -sensor, do a factory reset. The process for this is: - - - Loosen tailcap - - Hold button - - Tighten tailcap - - Keep holding button for about 4s - -The light should flicker while getting brighter, then briefly burst to -full power. Hold until it reaches full power to do a reset, or let go -of the button early to abort. - -On some lights, like products where the tailcap method is impossible, -use 13H from Off to do a factory reset. If this is difficult, try -counting it like music to make it easier: - - 1 2 3 4 - 1 2 3 4 - 1 2 3 4 - HOLD - -Simple UI is enabled after each factory reset. - -Simple UI can be configured in several ways, but not while Simple UI is -active. So go to the Advanced UI, configure things, then go back to -Simple UI. - -Configurable options include: - - - floor level - - ceiling level - - number of steps (in stepped ramp) - - turbo style - -Other options are inherited from Advanced UI: - - - ramp style (smooth / stepped) - - smooth ramp speed - - ramp-after-moon style - - memory settings - - auto-lock settings - - aux LED settings - - voltage calibration - - thermal regulation settings - - hardware-specific "misc menu" settings - - -Advanced UI ------------ - -Most of the information below this is for the Advanced UI. Anything not -already noted above is blocked in the Simple UI. - - -Ramping / Stepped Ramping Modes -------------------------------- - -Anduril's ramping mode uses a smooth ramp or a stepped ramp, depending -on which style the user prefers. - -Each ramp has its own settings -- floor (lowest level), ceiling (highest -level), and the stepped ramp can also have a configurable number of -steps. - -Additionally, Simple UI has its own ramp settings for floor, ceiling, -and number of steps. The smooth/stepped style is inherited from the -Advanced UI's ramp. - -There are four ways to access ramping mode when the light is off: - - - 1C: Turn on at the memorized brightness. - (see below for details about what "memorized" means) - - - 1H: Turn on at the floor level. Let go after the light turns on to - stay at the floor level, or keep holding to ramp up. - - - 2C: Turn on at the ceiling level. - - - 2H: Turn on at full power, turn off when released. (momentary turbo) - (in Simple UI, this uses the ceiling level instead of turbo) - -While the light is on, a few actions are available: - - - 1C: Turn off. - - 2C: Go to or from the turbo level. - (or if it has regulated down, "bump" back up to turbo) - (turbo level / behavior is configurable) - - 1H: Change brightness (up). If the button was released less than a - second ago, or if it's already at the ceiling, it goes down instead. - - 2H: Change brightness (down). - - - 3C: Switch to the other ramp style. (smooth / stepped) - (or activate the next channel mode, when more than one is enabled) - (then use 6C instead, for smooth / stepped toggle) - - 6C: Switch to the other ramp style. (when 3C is mapped to next channel) - - - 3H: Momentary turbo (when current channel has no tint to ramp). - - 3H: Tint ramping (only when current channel has adjustable tint). - - 4H: Momentary turbo, when 3H is mapped to tint. - - - 4C: Go to lockout mode. - - - 5C: Go to momentary mode. - - 5H: Start a sunset timer. Details are below in the Sunset Timer section. - - - 7H: Ramp config menu. - - Item 1: Floor level. - - Item 2: Ceiling level. - - Item 3: - Stepped ramp: Number of steps. Can be 1 to 150. - Smooth ramp: Ramp speed. - 1 = Full speed, ~2.5s from end to end. - 2 = Half speed, ~5s from end to end. - 3 = Third speed, ~7.5s. - 4 = Quarter speed, ~10s. - - - 10C: Activate manual memory and save the current brightness. - - 10H: Ramp extras config menu. - - Item 1: Disable manual memory and go back to automatic memory. - (doesn't matter what value the user enters at the prompt) - - Item 2: Configure the manual memory timer. - Sets the timer to N minutes, where N is the number of - clicks. A value of 0 (no clicks) turns the timer off. - - Item 3: Configure whether to ramp up after "Off -> 1H". - 0: Ramp up after moon. - 1: Don't ramp up, just stay at the floor level. - - Item 4: Configure Advanced UI's turbo style: - 0: No turbo, only ceiling. - 1: Anduril 1 style. Ramp -> 2C goes to full power. - 2: Anduril 2 style. Ramp -> 2C goes to ceiling, - or goes to full power if user ramped up to ceiling first. - This value also affects momentary turbo in Ramp and Off modes. - - Item 5: Configure "smooth steps". - 0: Disable smooth steps. - 1: Enable smooth steps. - -Memory determines which brightness level the light goes to with 1 click -from off. There are three types of brightness memory to choose from: - - - Automatic: Always uses the last-ramped brightness. - (does not memorize levels accessed by a shortcut, - like turbo, 2C for ceiling, or 1H-from-off for floor) - - - Manual: Always uses the user's saved brightness. - - - Hybrid: Uses the automatic memory brightness if the light was only - off for a short time, or resets to the manual memory level if it was - off for a longer time. - The timer for this is configurable from 0 to ~140 minutes. - -Another way to think of it is: There are three styles of memory for the -last-ramped brightness level... - - - Always remember (automatic) - - Remember for N minutes (hybrid) - - Never remember (manual) - -To choose a memory style, set the configuration accordingly: - - mem type manual mem manual mem timer - -------- ---------- ---------------- - automatic off any - manual on zero - hybrid on non-zero - -If "smooth steps" is enabled, the stepped ramp uses a smooth animation -between steps, and turning the light on/off has the edges smoothed off -too. With "smooth steps" turned off, these brightness changes are -immediate. - - -Sunset Timer ------------- - -In the ramp mode or candle mode, it's possible to make the light turn -itself off after a while. - -To activate the timer, go to the brightness you want and then use a 5H -action. Keep holding the button, and the light should blink once per -second. Each blink adds 5 minutes to the timer. - -In ramp mode, it slowly dims until it's at the lowest level, then shuts -off. In candle mode, it stays at the same brightness until the final -minute, at which point it dims and dies out. - -The user can change the brightness while the timer is active. If this -happens during the final few minutes, it also "bumps" the timer up to a -minimum of 3 minutes. So if it's getting really dim and you need a -little more time, you could do a 5H to add 5 minutes, or simply ramp up -to the desired brightness. - - -Other Modes ------------ - -Anduril has several other modes too. To access these, press the button -more than 2 times when the light is off: - - - 3C: Blinky / utility modes, starting with battery check. - - 3H: Strobe modes, starting with the most recently used strobe. - - 4C: Lockout mode. - - 5C: Momentary mode. - - 6C: Tactical mode. - - 7C / 7H: Aux LED configuration. - - 9H: Misc Config menu. (only on some lights) - - 10H: Simple UI configuration menu. - - 13H: Factory reset (on some lights). - - 15C or more: Version check. - - -Lockout Mode ------------- - -Click 4 times from Off to enter Lockout mode. Or 4 times from Ramp. -This makes the light safe to carry in a pocket or a bag or anywhere else -the button might be pressed by accident. - -To exit lockout mode, click 4 times. The light should blink briefly and -then turn on at the memorized level. Or hold the final press to turn on -at the floor level instead: - - - 3C: Unlock and go to "Off" mode - - - 4C: Go to ramp mode (memorized level). - (uses manual mem level if there is one) - - - 4H: Go to ramp mode (floor level). - - - 5C: Go to ramp mode (ceiling level). - -Lockout mode also doubles as a momentary moon mode, so the user can do -quick tasks without having to unlock the light. The brightness in -lockout mode has two levels: - - - 1H: Light up at the lowest floor level. - - - 2H: Light up at the highest floor level. - (or the manual mem level, if there is one) - - - 3H: Next channel mode (if more than one is enabled). - -It is also possible to make the light lock itself automatically after -being turned off. To enable this, go to lockout mode and use a 10H -action to activate the auto-lock config menu. Release the button after -the first blink. Then at the prompt, click N times to set the auto-lock -timeout to N minutes. - - - 10H: Auto-lock config menu. Click N times to set timeout to N minutes. - A value of zero disables the auto-lock feature. - So, to turn off auto-lock, don't click at all. - -And on lights which have aux LEDs, there may be additional functions: - - - 7C / 7H: Change Lockout Mode's aux LED pattern. More details on - this below, in a separate section. - - -Blinky / Utility Modes ----------------------- - -Click 3 times from Off to access Anduril's blinky / utility modes. This -always starts at battery check and the user can proceed to other blinky -modes if Advanced UI is enabled. The sequence is: - - - Battery check. - - Temperature check (if light has a temperature sensor). - - Beacon mode. - - SOS mode (if enabled). - -In all of these modes, some basic actions are available: - - - Click: Turn off. - - 2 clicks: Next blinky mode. - -Additionally, in battery check and temperature check modes: - - - 7H: Go to the voltage config menu or thermal config menu. - -In more detail, this is what each blinky / utility mode does: - - Battery check: - - Blinks out the battery voltage per cell. Full is 4.2V, empty is - about 3.0V. The light blinks the whole-number digit first, pauses, - then blinks out the "tenths" digit. Then a longer pause, and it - repeats. - So for 4.2V, it would be "blink-blink-blink-blink .. blink-blink". - - A "zero" digit is represented by a very quick blink. - - On lights with more than one set of LEDs, pressing 3C during batt - check mode can select which set of LEDs (which channel mode) it uses - to blink out numbers. - - The voltage config menu has these settings: - - 1. Voltage correction factor. This adjusts the battery - measurement sensor, allowing the user to add or subtract up to - 0.30V in 0.05V steps. Click N times to enter a value: - - 1C: -0.30V - 2C: -0.25V - 3C: -0.20V - 4C: -0.15V - 5C: -0.10V - 6C: -0.05V - 7C: default, 0V - 8C: +0.05V - 9C: +0.10V - 10C: +0.15V - 11C: +0.20V - 12C: +0.25V - 13C: +0.30V - - 2. Post-off voltage display timeout. (only on lights with RGB aux) - This setting determines how many seconds the RGB aux LEDs - display the voltage color after the torch goes to sleep. Click - once per desired second, or zero times to turn this function - off. - - Temperature check: - - Blinks out the current temperature in degrees C. This number should - be pretty close to what a real thermometer says. If not, it would - be a good idea to enter the thermal config menu and calibrate the - sensor. Or let the light settle to room temperature, then use - factory reset to auto-calibrate the sensor. - - The thermal config menu has two settings: - - - Current temperature. Click once per degree C to calibrate the - sensor. For example, if the ambient temperature is 21 C, then - click 21 times. - - - Temperature limit. This sets the maximum temperature the light - can reach before it will start doing thermal regulation to keep - itself from overheating. Click once per degree C above 30. For - example, to set the limit to 50 C, click 20 times. The default is - 45 C, and the highest value it will allow is 70 C. - - Beacon mode: - - Blinks at a slow speed. The light stays on for 100ms, and then - stays off until the next blink. The brightness and the number of - seconds between pulses are configurable: - - - Brightness is the user's memorized ramp level, so set this in - ramping mode before activating beacon mode. Follows the same - memory rules as ramping -- automatic, manual, or hybrid. - - - Speed is configured by holding the button. The light should - blink once per second while holding the button. Release it - after the desired amount of time has passed, to set a new beacon - speed. - For example, to do a 10-second alpine beacon, hold the button - for 10 seconds. - - SOS mode: - - Blinks out a distress signal. Three short, three long, three short. - Repeats until light is turned off or until battery is low. - - The memorized ramp level determines the brightness of SOS Mode. - - -Strobe / Mood Modes -------------------- - -Anduril includes a few extra modes for a variety of purposes: - - - Candle mode - - Bike flasher - - Party strobe - - Tactical strobe - - Lightning storm mode - -Click 3 times from Off to access these, but hold the third click for a -moment. Click, click, hold. The last-used strobe mode is remembered, -so it will return to whichever one you used last. - -In all of these modes, a few actions are available: - - - 1C: Turn off. - - 2C: Next strobe / mood mode. - - 1H: Increase brightness, or strobe faster. (except lightning) - - 2H: Decrease brightness, or strobe slower. (except lightning) - - 4C: Previous strobe / mood mode. - - 5C: Go to momentary mode, for a momentary strobe. - (this is useful for light painting) - -Additionally, candle mode has one more action: - - - 5H: Activate Sunset Timer, and/or add 5 minutes to the timer. - -In more detail, here is what each mode does: - - - Candle mode - - Brightness changes randomly in a pattern resembling a candle flame. - If a timer is set, it will run until the timer expires, then get - dimmer for one minute, then sputter and turn itself off. Without a - timer, candle mode runs until the user turns it off. Brightness is - configurable. - - - Bike flasher - - Runs at a medium level, but stutters to a brighter level once per - second. Designed to be more visible than a normal ramping mode, but - otherwise works mostly the same. Brightness is configurable. - - - Party strobe - - Motion-freezing strobe light. Can be used to freeze spinning fans - and falling water. Speed is configurable. - - - Tactical strobe - - Disorienting strobe light. Can be used to irritate people. Speed - is configurable, and the duty cycle is always 33%. - - Be careful about heat in this mode, if using it for a long time. - - - Police strobe (on some lights) - - 2-color police style strobe. Only works on lights with 2 or more - colors. - - - Lightning storm mode - - Flashes at random brightness and random speed to simulate lightning - strikes during a busy lightning storm. Do not look directly at the - flashlight when this mode is running, because it may suddenly go to - full power without warning. - - -Momentary Mode --------------- - -Click 5 times from Off to enter Momentary mode. Or 5 times from Ramp, -or 5 times from a strobe mode. - -This locks the flashlight into a single-mode interface where the LEDs -are only on when the button is held down. It is intended for Morse -code, light painting, and other tasks where the light should be on only -for a short time and probably in a pattern. - -Momentary mode does either a steady brightness level or a strobe, -depending on which was active before going to momentary mode. To select -which one, go to the mode you want to use, adjust the brightness and -speed and other settings, then click 5 times to enter momentary mode. - -In steady mode, brightness is the memorized ramp level, so adjust that -in Ramp Mode before entering momentary mode. - -In momentary strobe mode, the settings are copied from the last-used -strobe mode, such as party strobe, tactical strobe, or lightning. - -To exit this mode, physically disconnect power by unscrewing the tailcap -or battery tube. - - -Tactical Mode --------------- - -Click 6 times from Off to enter Tactical Mode, or 6 times in Tactical -Mode to exit and go back to "Off". - -Tactical Mode provides instant momentary access to high, low, and -strobe, but each of these is configurable. The inputs are: - - - 1H: High - - 2H: Low - - 3H: Strobe - -Each of these only lasts as long as you hold the button. - -Other commands in Tactical Mode are: - - - 6C: exit (go back to Off Mode) - - 7H: Tactical Mode config menu - - 1st blink: configure tactical slot 1 - - 2nd blink: configure tactical slot 2 - - 3rd blink: configure tactical slot 3 - -To change what is in a tactical slot, press 7H, then release the button -after the 1st, 2nd, or 3rd blink. Then enter a number. Each click adds -1, and each hold adds 10. The number can be: - - - 1 to 150: set the brightness level - - 0: last-used strobe mode - - 151+: go directly to a specific strobe mode - 151 = party strobe - 152 = tactical strobe - 153+ = other strobes, in the same order they're in in the "Off -> 3H" - strobe group - -This assumes the light has a ramp 150 levels long. Strobe modes start -at the ramp size plus 1, so it may be different if a light has a -different ramp size. - - -Configuration Menus -------------------- - -Every config menu has the same interface. It has one or more options -the user can configure, and it will go through them in order. For each -menu item, the light follows the same pattern: - - - Blink once, then go to a lower brightness. The user can keep - holding the button to skip this menu item, or release the button to - dive in and enter a new value. - - - If the user released the button: - - - Stutter or "buzz" quickly between two brightness levels for a few - seconds. This indicates that the user can click one or more times - to enter a number. It will keep buzzing until the user stops - clicking, so there is no need to hurry. - - The actions here are: - - click: add 1 - - hold: add 10 (only in versions 2021-09 or later) - - wait: exit - -After entering a number, or after skipping every menu item, it waits -until the button is released then exits the menu. It should return to -whatever mode the light was in before entering the config menu. - - -Ramp Config Menu ----------------- - -While the light is on in a ramping mode, click 7 times (but hold the -final click) to access the config menu for the current ramp. - -Or, to access the ramp config for Simple UI, make sure the Simple UI is -not active, then do a 10H action from Off. - -For smooth ramping mode, there are three menu options: - - 1. Floor. (default = 1/150) - 2. Ceiling. (default = 120/150) - 3. Ramp speed. (default = 1, fastest speed) - -For the stepped ramping mode, there are three menu options: - - 1. Floor. (default = 20/150) - 2. Ceiling. (default = 120/150) - 3. Number of steps. (default = 7) - -For the Simple UI mode, there are four menu options. The first three -are the same as stepped ramping mode. - - 1. Floor. (default = 20/150) - 2. Ceiling. (default = 120/150) - 3. Number of steps. (default = 5) - 4. Turbo style. (default = 0, no turbo) - -Default values are different for each model of flashlight. The numbers -above are only examples. - -To configure the floor level, click the button equal to the number of -ramp levels (out of 150) at which the floor should be. To set the -lowest possible level, click once. - -To configure the ceiling level, each click goes one level lower. So 1 -click sets the highest possible level, 2 clicks is the 2nd-highest, 3 -clicks is the 3rd-highest level, etc. To set the default of 120/150, -click 31 times. - -When configuring the number of steps, the value can be anything from 1 -to 150. A value of 1 is a special case. It places the step halfway -between the floor and ceiling levels. - - -Version Check Mode ------------------- - -This allows people to see which version of the firmware is installed on -their light. The format for this is (usually) 12 digits -- a model -number and a date. BBPP.YYYY-MM-DD - - - BB: Brand ID - - PP: Product ID - - YYYY: Year - - MM: Month - - DD: Day - -Versions before 2023-05-30 used YYYYMMDDBBPP format. -Anduril 1 used only YYYYMMDD format, or none at all. - -The date is when the firmware was compiled. If the vendor did not set -this value, it defaults to 1969-07-20, the date of first human contact -with the moon. However, it might not be a date at all; some vendors may -specify a completely different type of value here. - -The brand/product values are also known as the model number. These are -hard-coded in the source code for each light's build target, and can be -looked up in the "MODELS" file or by using the "make models" command. - - -Protection Features -------------------- - -Anduril includes low voltage protection (LVP) and thermal regulation. - -LVP makes the light step down to a lower level when the battery is low, -and if the light is already at the lowest level, it shuts itself off. -This activates at 2.8V. LVP adjustments happen suddenly, in large -steps. - -Thermal regulation attempts to keep the light from overheating, and -otherwise adjusts output to stay as close as possible to the -user-configured temperature limit. Thermal adjustments happen -gradually, in steps so small they are difficult for humans to perceive. - - -Aux LEDs / Button LEDs ----------------------- - -Some lights have aux LEDs or button LEDs. These can be configured to do -different things while the main emitters are off. There is one aux LED -mode for the regular "off" mode, and another aux LED mode for "lockout" -mode. This allows the user to see at a glance whether the light is -locked. - -Aux LED modes typically include: - - - Off - - Low - - High - - Blinking - -To configure the aux LEDs, go to the mode you want to configure and then -click the button 7 times. This should change the aux LEDs to the next -mode supported on this light. - - - 7C: Next aux LED mode. - -If the aux LEDs can change color, there are additional actions to change -the color. It is the same as above, but hold the button on the last -click and then let go when the desired color is reached. - - - 7H: Next aux LED color. - -On most lights, the colors follow this sequence: - - - Red - - Yellow (Red+Green) - - Green - - Cyan (Green+Blue) - - Blue - - Purple (Blue+Red) - - White (Red+Green+Blue) - - Disco (fast random colors) - - Rainbow (cycles through all colors in order) - - Voltage (uses color to display battery charge) - -In voltage mode, the colors follow the same sequence, in the same order -as a rainbow... with red indicating a low battery and purple indicating -a full battery. - -For lights with a button LED, the button LED typically stays on while -the main emitters are on. Its brightness level is set in a way which -mirrors the main LED -- off, low, or high. - -For lights with a RGB button LED, the button LED indicates battery -charge during use in the same manner as the aux LED voltage mode. - -For lights with front-facing aux LEDs, the aux LEDs typically stay off -when the main emitters are on, and when the light is otherwise awake. -The aux LEDs on most lights only turn on when the light is asleep. - -When a light has a single-color aux LED and no RGB, it fast-blinks the -aux LED in "off" modes when voltage is low. - - -Misc Config Menu ----------------- - -Some models may have an extra config menu for settings which don't fit -anywhere else. This menu is located at "Off -> 9H" in the advanced UI. - -These settings are, in order: - - - Tint ramp style: (on some lights) - - 0 : smooth ramp (blend channels in any proportion) - 1 : middle tint only - 2 : extreme tints only (only one channel active at a time) - 3+: stepped ramp with 3+ steps - - - Jump Start level: (on some lights) - - Some lights are prone to starting up slowly at low levels, so they - have an option to "jump start" the engine by pulsing a higher power - level for a few milliseconds when changing from off to a low level. - This setting specifies how bright that pulse should be. - - The value can be from 1 to 150, but is usually between 20 and 50. - -These settings are hardware-specific and may not be present on all -lights. The number of settings in the Misc Config Menu depends on the -hardware model and the firmware version. - - -Channel Modes (a.k.a. Tint Ramping or Multi Channel controls) -------------------------------------------------------------- - -Some lights have more than one set of LEDs which can be adjusted to -change the beam color, shape, or other properties. These lights have -features like tint ramping and channel modes. - -On these models, there are some global button mappings which work at all -times unless they're overridden by the mode the light is in: - - - 3C: Next channel mode - - 3H: Adjust current channel mode (ramp tint, for example) - - 9H: Channel mode config menu - -Details depend on the exact type of light used. For example, if a light -has LEDs in cool white, warm white, and red... that light might have a -few channel modes: - - - White blend (adjustable CCT / tint ramping) - - Red only - - Auto-tint - -On a light like this, the user could press 3C to rotate through these -different channel modes... white, then red, then auto, then back to -white. - -Additionally, in the "white blend" mode, the user could press 3H to -manually adjust the balance between warm white and cool white. - -Finally, if the user decides they don't want all of the modes, they can -turn some off. Press 9H (while on) to start the channel mode config -menu. To disable the auto-tint mode, for example, it is the 3rd mode... -so wait for the 3rd blink, then release the button. Then at the prompt, -enter a value of 0 (wait for the prompt to time out without clicking -anything). Afterward, the auto tint mode should no longer be in the -channel mode rotation. To turn the mode back on later, do the same -thing, but enter a value of 1 (click 1 time at the prompt). - -A light can have many different channel modes, so don't be shy about -turning off any modes you don't use. It makes all the others easier to -reach. - -If you turn off channel modes until only 1 remains, the "Ramp -> 3C" -action reverts to its single-channel behavior -- switching between a -smooth or stepped brightness ramp. Additionally, when a channel mode -has nothing to adjust with 3H, the 3H action also reverts to its -single-channel behavior -- momentary turbo. - -The Misc Config Menu (Off -> 9H) may also have a setting to choose a -tint ramp style. There are a few styles available, by entering -different numbers into that config menu: - - 0: smooth ramp - 1: middle tint only - 2: extreme tints only - 3+: stepped ramp with 3+ steps - -This setting only applies to modes with channel ramping (i.e. tint -ramping), and only when that mode uses the default 3H event handler. -Custom channel modes may work differently. - - - -UI Reference Table ------------------- - -This is a table of all button mappings in Anduril, in one place: - -Mode UI Button Action ----- -- ------ ------ -Off Any 1C On (ramp mode, memorized level) -Off Any 1H On (ramp mode, floor level) -Off Any 2C On (ramp mode, ceiling level) -Off Simple 2H On (momentary ceiling level) -Off Full 2H On (momentary turbo) -Off Any 3C Battcheck mode -Off Full 3H Strobe mode (whichever was used last) -Off Any 4C Lockout mode -Off Full 5C Momentary mode -Off Full 6C Tactical mode -Off Full 7C Aux LEDs: Next pattern -Off Full 7H Aux LEDs: Next color -Off Full 9H Misc Config menu (varies per light): - ?1: tint ramp style - ?2: jump start level -Off Full 10C Enable Simple UI -Off Simple 10H Disable Simple UI -Off Full 10H Simple UI ramp config menu: - 1: floor - 2: ceiling - 3: steps - 4: turbo style -Off Any 13H Factory reset (on some lights) -Off Any 15+C Version check - -Ramp Any 1C Off -Ramp Any 1H Ramp (up, with reversing) -Ramp Any 2H Ramp (down) -Ramp Any 2C Go to/from ceiling or turbo (configurable) -Ramp Full 3C Change ramp style (smooth / stepped) -Ramp Full 6C (same as above, but on multi-channel lights) -Ramp Full 3H Momentary turbo (when no tint ramping) -Ramp Full 4H Momentary turbo (on multi channel lights) -Ramp Any 4C Lockout mode -Ramp Full 5C Momentary mode -Ramp Full 5H Sunset timer on, and add 5 minutes -Ramp Full 7H Ramp config menu: (for current ramp) - 1: floor - 2: ceiling - 3: speed / steps -Ramp Full 10C Turn on manual memory and save current brightness -Ramp Full 10H Ramp Extras config menu: - 1: switch to automatic mem, not manual mem - 2: set manual mem timeout - 3: ramp after moon or not - 4: advanced UI turbo style - 5: smooth steps - -Multi-channel lights only: -Any Any 3C Next channel mode (i.e. next color mode) -Any Any 3H Tint ramp (if this mode can) -Any Full 9H Channel mode enable/disable menu: - N: click (or not) to enable (disable) mode N - -Lockout Any 1C/1H Momentary moon (lowest floor) -Lockout Any 2C/2H Momentary moon (highest floor, or manual mem level) -Lockout Any 3C Unlock (go to "Off" mode) -Lockout Any 3H Next channel mode (if more than one enabled) -Lockout Any 4C On (ramp mode, memorized level) -Lockout Any 4H On (ramp mode, floor level) -Lockout Any 5C On (ramp mode, ceiling level) -Lockout Full 7C Aux LEDs: Next pattern -Lockout Full 7H Aux LEDs: Next color -Lockout Full 10H Auto-lock config menu: - 1: set timeout in minutes (0 = no auto-lock) - -Strobe (any) Full 1C Off -Strobe (any) Full 2C Next strobe mode -Strobe (any) Full 3C Next channel mode (saved per strobe mode) -Strobe (any) Full 4C Prev strobe mode -Strobe (any) Full 5C Momentary mode (using current strobe) - -Party strobe Full 1H/2H Faster / slower -Tactical strobe Full 1H/2H Faster / slower -Police strobe - - None (brightness is Ramp Mode's last-used level) -Lightning Full 1H Interrupt current flash or start new one -Candle Full 1H/2H Brighter / dimmer -Candle Full 5H Sunset timer on, add 5 minutes -Biking Full 1H/2H Brighter / dimmer - -Batt check Any 1C Off -Batt check Full 2C Next blinky mode (Temp check, Beacon, SOS) -Batt check Full 3C Next channel mode (for number blinks only) -Batt check Full 7H Voltage config menu - 1: voltage correction factor - ... - 5: -0.10V - 6: -0.05V - 7: no correction - 8: +0.05V - 9: +0.10V - ... - 2: post-off voltage display seconds - -Temp check Full 1C Off -Temp check Full 2C Next blinky mode (Beacon, SOS, Batt check) -Temp check Full 7H Thermal config menu - 1: set current temperature - 2: set temperature limit - -Beacon Full 1C Off -Beacon Full 1H Configure beacon timing -Beacon Full 2C Next blinky mode (SOS, Batt check, Temp check) - -SOS Full 1C Off -SOS Full 2C Next blinky mode (Batt check, Temp check, Beacon) - -Momentary Full Any On (until button is released) -Momentary Full Disconnect power Exit Momentary mode - -Tactical Full 1H High (tactical slot 1) -Tactical Full 2H Low (tactical slot 2) -Tactical Full 3H Strobe (tactical slot 3) -Tactical Full 6C Exit (go back to Off Mode) -Tactical Full 7H Tactical Mode config menu: - 1: tactical slot 1 - 2: tactical slot 2 - 3: tactical slot 3 - -Config menus Full Hold Skip current item with no changes -Config menus Full Release Configure current item - (goes to Number Entry menu) - -Number entry Full Click Add 1 to value for current item -Number entry Full Hold Add 10 to value for current item - diff --git a/spaghetti-monster/anduril/anduril-ui.png b/spaghetti-monster/anduril/anduril-ui.png Binary files differdeleted file mode 100644 index 8f60cc8..0000000 --- a/spaghetti-monster/anduril/anduril-ui.png +++ /dev/null diff --git a/spaghetti-monster/anduril/anduril.c b/spaghetti-monster/anduril/anduril.c deleted file mode 100644 index e46eeaf..0000000 --- a/spaghetti-monster/anduril/anduril.c +++ /dev/null @@ -1,396 +0,0 @@ -// Anduril: Narsil-inspired UI for SpaghettiMonster. -// (Anduril is Aragorn's sword, the blade Narsil reforged) -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -/* - * Usually a program would be structured like this... - * - Library headers - * - App headers - * - App code - * - * ... in each source file. - * ... and each library and part of the program would be linked together. - * - * But this doesn't follow that pattern, because it's using the - * -fwhole-program - * flag to reduce the compiled size. It lets us fit more features - * in a tiny MCU chip's ROM. - * - * So the structure is like this instead... - * - App-level configuration headers - * - Default config - * - Per build target config - * - Library-level configuration headers - * - Library code (FSM itself) - * - App headers - * - App code (all of it, inline) - * - * Don't do this in regular programs. It's weird and kind of gross. - * But in this case it gives us a bunch of much-needed space, so... woot. - * - * Also, there are a ton of compile-time options because it needs to build - * a bunch of different versions and each one needs to be trimmed as small - * as possible. These are mostly "USE" flags. - */ - -/********* User-configurable options *********/ -#include "config-default.h" - -/********* specific settings for known driver types *********/ -// Anduril config file name (set it here or define it at the gcc command line) -//#define CFG_H cfg-blf-q8.h - -#include "tk.h" -#include incfile(CFG_H) - - -/********* Include headers which need to be before FSM *********/ - -// enable FSM features needed by basic ramping functions -#include "ramp-mode-fsm.h" - -#ifdef USE_FACTORY_RESET -#include "factory-reset-fsm.h" -#endif - -#ifdef USE_BATTCHECK_MODE -#include "battcheck-mode-fsm.h" -#endif - -#ifdef USE_LOCKOUT_MODE -#include "lockout-mode-fsm.h" -#endif - -// enable FSM features needed by strobe modes -#include "strobe-modes-fsm.h" - -// figure out how many bytes of eeprom are needed, -// based on which UI features are enabled -// (include this one last) -#include "load-save-config-fsm.h" - - -/********* bring in FSM / SpaghettiMonster *********/ -#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending - -#include "spaghetti-monster.h" - -/********* does this build target have special code to include? *********/ -#ifdef HWDEF_C_FILE -#include incfile(HWDEF_C_FILE) -#endif -#ifdef CFG_C_FILE -#include incfile(CFG_C_FILE) -#endif - - -/********* Include all the regular app headers *********/ - -#include "off-mode.h" -#include "ramp-mode.h" -#include "config-mode.h" -#include "aux-leds.h" -#include "misc.h" - -#ifdef USE_SUNSET_TIMER -#include "sunset-timer.h" -#endif - -#ifdef USE_VERSION_CHECK -#include "version-check-mode.h" -#endif - -#ifdef USE_BATTCHECK_MODE -#include "battcheck-mode.h" -#endif - -#ifdef USE_BEACON_MODE -#include "beacon-mode.h" -#endif - -#ifdef USE_THERMAL_REGULATION -#include "tempcheck-mode.h" -#endif - -#ifdef USE_LOCKOUT_MODE -#include "lockout-mode.h" -#endif - -#ifdef USE_MOMENTARY_MODE -#include "momentary-mode.h" -#endif - -#ifdef USE_TACTICAL_MODE -#include "tactical-mode.h" -#endif - -// allow the channel mode handler even when only 1 mode -// (so a tint ramp light could still use 3H even if there's no other mode) -#if defined(USE_CHANNEL_MODES) -#include "channel-modes.h" -#endif - -#ifdef USE_FACTORY_RESET -#include "factory-reset.h" -#endif - -// this one detects its own enable/disable settings -#include "strobe-modes.h" - -#ifdef USE_SOS_MODE -#include "sos-mode.h" -#endif - -#ifdef USE_SMOOTH_STEPS -#include "smooth-steps.h" -#endif - -// this should be last, so other headers have a chance to declare values -#include "load-save-config.h" - - -/********* Include all the app logic source files *********/ -// (is a bit weird to do things this way, -// but it saves a lot of space by letting us use the -fwhole-program flag) - -#include "off-mode.c" -#include "ramp-mode.c" -#include "load-save-config.c" -#include "config-mode.c" -#include "aux-leds.c" -#include "misc.c" - -#ifdef USE_SUNSET_TIMER -#include "sunset-timer.c" -#endif - -#ifdef USE_VERSION_CHECK -#include "version-check-mode.c" -#endif - -#ifdef USE_BATTCHECK_MODE -#include "battcheck-mode.c" -#endif - -#ifdef USE_BEACON_MODE -#include "beacon-mode.c" -#endif - -#ifdef USE_THERMAL_REGULATION -#include "tempcheck-mode.c" -#endif - -#ifdef USE_LOCKOUT_MODE -#include "lockout-mode.c" -#endif - -#ifdef USE_MOMENTARY_MODE -#include "momentary-mode.c" -#endif - -#ifdef USE_TACTICAL_MODE -#include "tactical-mode.c" -#endif - -#if defined(USE_CHANNEL_MODES) -#include "channel-modes.c" -#endif - -#ifdef USE_FACTORY_RESET -#include "factory-reset.c" -#endif - -#ifdef USE_STROBE_STATE -#include "strobe-modes.c" -#endif - -#ifdef USE_SOS_MODE -#include "sos-mode.c" -#endif - -#ifdef USE_SMOOTH_STEPS -#include "smooth-steps.c" -#endif - - -// runs one time at boot, when power is connected -void setup() { - - #ifndef START_AT_MEMORIZED_LEVEL - - // regular e-switch light, no hard clicky power button - - // blink at power-on to let user know power is connected - blink_once(); - - #ifdef USE_FACTORY_RESET - if (button_is_pressed()) - factory_reset(); - #endif - - load_config(); - - #if defined(USE_MANUAL_MEMORY) && defined(USE_MANUAL_MEMORY_TIMER) - // without this, initial boot-up brightness is wrong - // when manual mem is enabled with a non-zero timer - if (cfg.manual_memory) manual_memory_restore(); - #endif - - #if defined(USE_CHANNEL_MODES) - // add channel mode functions underneath every other state - push_state(channel_mode_state, 0); - #endif - - push_state(off_state, 1); - - #else // if START_AT_MEMORIZED_LEVEL - - // dual switch: e-switch + power clicky - // power clicky acts as a momentary mode - load_config(); - - #if defined(USE_CHANNEL_MODES) - // add channel mode functions underneath every other state - push_state(channel_mode_state, 0); - #endif - - if (button_is_pressed()) - // hold button to go to moon - push_state(steady_state, 1); - else - // otherwise use memory - push_state(steady_state, memorized_level); - - #endif // ifdef START_AT_MEMORIZED_LEVEL - -} - - -// runs repeatedly whenever light is "on" (not in standby) -void loop() { - - // "current_state" is volatile, so cache it to reduce code size - StatePtr state = current_state; - - #ifdef USE_AUX_RGB_LEDS_WHILE_ON - // display battery charge on RGB button during use - if (state == steady_state) - rgb_led_voltage_readout(actual_level > USE_AUX_RGB_LEDS_WHILE_ON); - #endif - - if (0) {} // placeholder - - #ifdef USE_VERSION_CHECK - else if (state == version_check_state) { - version_check_iter(); - } - #endif - - #ifdef USE_STROBE_STATE - else if ((state == strobe_state) - #ifdef USE_MOMENTARY_MODE - // also handle momentary strobes - || (( - (state == momentary_state) - #ifdef USE_TACTICAL_MODE - || (state == tactical_state) - #endif - ) - && (momentary_mode == 1) && (momentary_active)) - #endif - ) { - strobe_state_iter(); - } - #endif // #ifdef USE_STROBE_STATE - - #ifdef USE_BORING_STROBE_STATE - else if (state == boring_strobe_state) { - boring_strobe_state_iter(); - } - #endif - - #ifdef USE_BATTCHECK - else if (state == battcheck_state) { - battcheck(); - #ifdef USE_SIMPLE_UI - // in simple mode, turn off after one readout - // FIXME: can eat the next button press - // (state changes in loop() act weird) - if (cfg.simple_ui_active) set_state_deferred(off_state, 0); - else nice_delay_ms(1000); - #endif - } - #endif - - #ifdef USE_THERMAL_REGULATION - // TODO: blink out therm_ceil during thermal_config_state? - else if (state == tempcheck_state) { - blink_num(temperature); - nice_delay_ms(1000); - } - #endif - - #ifdef USE_BEACON_MODE - else if (state == beacon_state) { - beacon_mode_iter(); - } - #endif - - #if defined(USE_SOS_MODE) && defined(USE_SOS_MODE_IN_BLINKY_GROUP) - else if (state == sos_state) { - sos_mode_iter(); - } - #endif - - #ifdef USE_SMOOTH_STEPS - else if (cfg.smooth_steps_style && smooth_steps_in_progress) { - smooth_steps_iter(); - } - #endif - - #ifdef USE_IDLE_MODE - else { - // doze until next clock tick - idle_mode(); - } - #endif - -} - - -// instead of handling EV_low_voltage in each mode, -// it's handled globally here to make the code smaller and simpler -void low_voltage() { - - // "current_state" is volatile, so cache it to reduce code size - StatePtr state = current_state; - - // TODO: turn off aux LED(s) when power is really low - - if (0) {} // placeholder - - #ifdef USE_STROBE_STATE - // "step down" from strobe to something low - else if (state == strobe_state) { - set_state(steady_state, RAMP_SIZE/6); - } - #endif - - // in normal mode, step down or turn off - else if (state == steady_state) { - if (actual_level > 1) { - uint8_t lvl = (actual_level >> 1) + (actual_level >> 2); - set_level_and_therm_target(lvl); - } - else { - set_state(off_state, 0); - } - } - // all other modes, just turn off when voltage is low - else { - set_state(off_state, 0); - } - -} - diff --git a/spaghetti-monster/anduril/anduril.svg b/spaghetti-monster/anduril/anduril.svg deleted file mode 100644 index 2ecb530..0000000 --- a/spaghetti-monster/anduril/anduril.svg +++ /dev/null @@ -1,4921 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="18.056446cm" - height="30.084438cm" - id="svg2" - version="1.1" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)" - sodipodi:docname="anduril.svg" - inkscape:export-filename="/tmp/anduril-ui.png" - inkscape:export-xdpi="67.543221" - inkscape:export-ydpi="67.543221"> - <defs - id="defs4"> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0.0" - refX="0.0" - id="marker19840" - style="overflow:visible;" - inkscape:isstock="true"> - <path - id="path18419" - d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " - style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" - transform="scale(0.4) rotate(180) translate(10,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0.0" - refX="0.0" - id="marker18673" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path18416" - d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " - style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1" - transform="scale(0.4) translate(10,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker17250" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path17248" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - id="linearGradient7690"> - <stop - style="stop-color:#010109;stop-opacity:1;" - offset="0" - id="stop7686" /> - <stop - style="stop-color:#010109;stop-opacity:0;" - offset="1" - id="stop7688" /> - </linearGradient> - <linearGradient - inkscape:collect="always" - id="linearGradient7528"> - <stop - style="stop-color:#010109;stop-opacity:1;" - offset="0" - id="stop7524" /> - <stop - style="stop-color:#010109;stop-opacity:0;" - offset="1" - id="stop7526" /> - </linearGradient> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker61712" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path61710" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker50318" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart"> - <path - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path50316" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker49438" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path49436" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#7777ff;fill-opacity:1;fill-rule:evenodd;stroke:#7777ff;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker48588" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart"> - <path - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path48586" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path12697" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker12161" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9801" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(-0.4,0,0,-0.4,-4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Lstart" - orient="auto" - refY="0" - refX="0" - id="Arrow1Lstart" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9792" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.8,0,0,0.8,10,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker11118" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path11116" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker10592" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path10590" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mstart" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9798" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker9610" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9608" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - id="linearGradient7283"> - <stop - style="stop-color:#ff0000;stop-opacity:1;" - offset="0" - id="stop7279" /> - <stop - style="stop-color:#ff0000;stop-opacity:0;" - offset="1" - id="stop7281" /> - </linearGradient> - <pattern - inkscape:stockid="Sand (bitmap)" - id="pattern7084" - height="256" - width="256" - patternUnits="userSpaceOnUse"> - <!-- Seamless texture provided by FreeSeamlessTextures.com --> - <!-- License: creative commons attribution --> - <image - xlink:href="data:image/jpeg;base64,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 /p1//9k= " - y="0" - x="0" - id="image7082" - height="260" - width="260" /> - </pattern> - <linearGradient - id="linearGradient1694" - inkscape:collect="always"> - <stop - id="stop1690" - offset="0" - style="stop-color:#000000;stop-opacity:0.74496644" /> - <stop - id="stop1692" - offset="1" - style="stop-color:#000000;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient5876"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop5878" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop5880" /> - </linearGradient> - <linearGradient - id="linearGradient5850" - osb:paint="solid"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop5852" /> - </linearGradient> - <pattern - inkscape:stockid="Sand (bitmap)" - id="sand_bitmap" - height="256" - width="256" - patternUnits="userSpaceOnUse"> - <!-- Seamless texture provided by FreeSeamlessTextures.com --> - <!-- License: creative commons attribution --> - <image - xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQIAIwAjAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAEEAQQDASIA AhEBAxEB/8QAHQAAAgIDAQEBAAAAAAAAAAAABgcFCAADBAkBAv/EAEIQAAICAAUDBAECBAQFAwEI AwUGBAcBAwgVFgAXJQIRFCYnITUYJDZFEzE3RgkSQVVWKFF1ZTQ4R1dhZmd2hYaV/8QAGQEAAgMB AAAAAAAAAAAAAAAAAgMAAQQF/8QAOxEAAgIBAwMDBAEBBgUDBQEAAQIDERIEEyEAIjEjMkEUQlFh M0MFJFJicYE0U5GhsRVjcnOCwtHh8P/aAAwDAQACEQMRAD8Ar2yC6nrRLre36+zv8FjfJLYn0bZB gQtC2h3u4oHp+yKrW0NbD2BMsbb3w64E0YW+XkMeAhurjgABgAqKg8D+wPiSrpH8dDjAu7T5aNj0 2SsC7aXa4dIVPT9c2MJPRa3wZBEy1IVJQAyq2sEECns9ls+KN9Jdqv2Bgfl9gAfowVFHg6/gWo1U jP03kqf4TW7CYVbOcPmuSxLKK/H62+HW6fLHh1RDH74h2Z3kF+7xvlXI/aIAA58f8+Hwrcp9cviv e5eVVtJu6SSiMCS7I9esn8L6QUKGGD7gnsj5+OD2n9tOLdQE1dXZqzOOwSrjlugD5/nwDz4yRyYT GWZ2dIzIkkfpSNAtbIViXwu3s0w8cfmRLG7wPGmCPNGS2WW45He/gY320LNfnp5J490gZeTm1LDC UPYKGky9N92WQY4HbTQ721qgMOC1zCGnuBCZ8Cj9Q/A+CoaHtn4u4OAPeAAMG/4vi7NM9H5VoJ+o e30rsPlWo2sJAxhIiB2hN55FMEIb5ChrYcc4QVKwIFqJ7N4sZwfm1oo/gPAY8B6WNT2YDr65DJmv baJZzkHq7s+BsIephyh/s3aHdBwcEOGHtRgmHOHwJ3BidNtAwYj9rkkF5/3+/dSNZ0W0XJID1LX1 V0m+SnugYkgAh1OwmHIUXlRf5wzqEtSyEMehqtD3BWjwyLPZtXZhjw7BLR/6H+fnj/UncR4zxzOr yo6ahDD2LAcNwpIztHNXGQfTnHtqsj1IizrLpp4FKRPC8WdHHh8wCoSVMqUkxyJddwahSUjq9fz6 fmD7frGNTK27RrNkaM7lresnxyQ7BfAMMgYmCE9kUB2+VKPfIKejPKur8m4T+/7+A+g4b/2HEdwz bMvJzxuC/kOlgNXJA8lWVftn8NJRhsaKYH2TW91mA8xh/kB6lY0zc1doJowM1VxsHx8Agn+A8B6Y T44ajHyv63zWjPsh8UgLIJTlUbIrKbV1XsLSBQx0NDW4b5Mr9wg8/nnENmRigp5RvzYk7B+Xd/8A Pr/ZUczLV6farQgVLV3zzD/YVHuAH5aeBKCYoFwXjN8J/wAOtyDh7kFKCtoyNyizBm9hQlqVDbqC ffj+D9ifYRKqxsxf1JFTCNMkjv70yYyLIPtaSSWucQOco6wH04Ux2kdmkZspJKwAV8QkQx5oxxJd nLLiuOp7QU3dXsIC2vhK7LGsI3dzxppPWwwh7uKUNbUWYQXLIZHD8f8AB21fbVXjTM0CxiMDdnc0 DAP1B1FwHYH7AqrM5qFTazG2Dm1utmFxxN3dHtS2k/uR257N1KH+GHrdDwQ+SHK07lnLgwWSlNsw xHpMI7bAA5/ivnz6Cgit4PBCwcwzb4HFbs5oW5K9dDsBaFOq3yLXtc02yVet1Wt2oH4+Ham1gAg3 BZrN83TY7RduDoPPsP3/AKgbwHslg2o1WqGuZAW4tqNpap2qZHbA+nOVLVzwevw7IH1IB6THGEdD r89Bhi3loFE2b97w597f54ABkkZpSxZ33akJL5xo7UHijehnhxk2KXa0oHUiXEMmSJg5S0jrOseS MzVX4s0CeeoEdl1PKrMwBynBtGq5KNp7IDcn4nxQPfgWyEE+G+La2tkDBzkEBHrf2ab4Gk0c27c4 2B+QQHn0HrdYGXDq+4JkCxk82H7wVLYKuSiODuYV1evHxoodgZEMPzx9HmAf7HtgxDFszNwnm14f rv8AwFBwAdiu6B3wxUsAo1v82xnxkd2gOnj69Q1eLLPSltgrdP8Ah2oyD2SuQJHvgYWVkXxnfAjt SZz9/wD7BhPtge6FwpdibVWcNVQyS2ryPDcVdshlJbDXJ5bsCtzEwNMD1/g842fbUEwzoyu0LNQH OEuxzgOwAP39gaiuVRvObqlVhqIroX92GX45yI8iupuJK0jOMcc6F3e2I7+B7sgP145vhg0vV9d2 WLtoW0WTGVK5yadbHCt3YwvMmnypbC7Sp6/al2p4dDtSv1uCeYENGuAn7/ZvdISQZ/8Ar4+AAPy/ WlPeE/tWktr5Dwo1Xs5tlh0myLYqdkKUjYe1w18OyPlDhw49bnNqfPgzMVkoLZif9bdogB/wGL97 2ET2tkr6liWUGuAlErSwgktgtSq3BeMNCuvFLkW8A8yGyQ1tPZEcC49udsRilojNjCJO+cBQff36 XinDqsWYcE0XqEbZlXje08hquaSWMNErTgh1fMIQ/eYt/wA4jtrABBzNsw4KT9tkeMGA+A+/e3Sr fZlWR8N2Z2QKM5HjGGLxpa5XZyGQxAXk3wJKrTRrde4k4ovtrN6OF0a7TZDfjqxcN0cBeY4bNVZJ PMmG22VdPyR9hTAKawlbGhjzCG4B/r7JBn19WjUYt+31dX7QdkzZvYN/4DboDgICqINstBI07V7R YauCcO6Upttgw1NTxZr5LQ0jfoZCG+TIemPh8PssngZ3BsWho5zvfCd/2Df9/PoPR5UavX4GPk2X aF5OyHdwdlE1+yDWBecKv5YeoeGwGFswYmMmzg59X74H4wLaBjNvdXeA2AAf8Bh1DvkiWkPhJNgV KbsKkYcnlFe2E4cbq8WWF/DYFtwfFuGtjzEFtsDEGyowx8fBhPukE2NB/fwADwBQiNZsCHldKdlR L2a8TGmOWFmk4ys9w4JGTcC9vYknGfnNODImPGN2vNn/AEPQ2tslfxYeynrU7M1yHpynHiHnV+Jm AXxIcnKq0+h32Yth2S0DDUer/UPVbJ9oVyZM4k1cEOIP0FB6YTQv2AMtQbWmqB2W3y7qZGlmB2hj 9XbKAV2FolIfez5kNwTx4Z4Pd6fhjHmr/wBN8Cef7RH9/AbAAG6PpNDqWHXzGr2Rv2lWpZLZHhu1 gpNb20m0NY1jJ5Awth3DkifDOHSLbO2ysyqv2ztRJSTZzE/v+H0E+AUuWhpaQhmEdoT7kJKSQt6h cENPYJaHYybXt2lDCeYQw9Vw09gW2rtf9wxJvnGWZ4CBDZz8Rffl9+9xZZvQGSN6KRbkMe3/ADVw kubZxjD1YsFzJQZKOiiZMpW2nGb508255+B6aVVcnnK/iuQO/JmXXLBMqWK1O0ym3xtr1f43J+GL tpI37j7JiyGOz5AxOn8ReDAwntiy8nMceD8AP7/+/gPWLUhYF6Wqhn59yEhum+6XwIWRzFhVRU8P a7DpF8qusA9bvkO+GRg3zj7Y1J9G4WgLrMm8GwiSbt0BsHXnvlo4sWLGvltKpJPSGRkYa335IU0/ dKyFvhjjbhM09hzKcHBnmACD3Pa3wmso/m3jf+AoJ/gL8feUxHvTTwLuyVPh/MrkapS7A+GwMK2B 0+yxbQH5gZW5gfvAHrqfZ75R4cmzfrWe9u3B+AgH7+wdNYRNOuWazKiOGKemmdCo3y9S8O44pjxw cuGCN49MxkCHTtMquQ9yK+nrNWjx9GRTKu1Jk9W3b0jUNluNIq8bX2oIlaIEytqVhI9e2pR9mmKv PKcpo4/MMB5kOaQmc834J+vA/BpN2BHgAffQB9+QOp4oUj0YMsg9TZi4zGahu9hMCHnGOz55o2H5 jBMMGXxDmYMiq+bBOT3ni7R+KrR2Q6APoP8ApFsB88F6mL007tFJ2rX1nUBarbZC2kMHCCC8HsZX lyhcNwqtDhvictr6fOQ7QAo75xlpQ6z/AN7Y7/sB/wDz60ttmB3JH1gdy9MbYq3S7JK9H0+NSfw8 XKpGUh2QwTHx8oeq09ghzuH8H/GaHaKMMOOxsJsIDYAFRPp/pChhcLwu2mkqZpz/AHlGMldsZqL2 VbHnIMOFx5Esx3HSVI3VyilPRAxxs1353YIHGNfdn2myX3MsuYBtqwdS1tZKk4VdWUdkGuESq5V8 WEeiGNQOzmEOqzFfrYLVLcAF5sgmTfFcY9PARJpN43+3fP8AAUEAEx3BPA2w4ZtjGKUtUMt+Yzv4 d7N4ueiK8rbw74HreyE/S+HVW2r1Kuds4GLrMmDq7TxSfPwL9h7c+2CHTx5SkZie25q2pMunit5K 6QW3ZgiLcUDwMpW7A4B63T3xDYJqqPcLLo9bWRnKNs3s39+7ur9uH6i6gSC3Nrlwya0qAPvAFlUb CHt5KSkTItjCRcWyOYLbI4Vut2An8Dx5wYRka0GgmMtTtd/UAD8uoIDpjIsb4Rj21hH+bCk936of B8/A6EllfdkXEGtxiadaxxzjo4/IXuN0R5HMjiVoeVUbqrW0cOAldEsji1TE15TY2ipbtsa2rHAO L4iRLg4enU9t9aHTAu3iiH6VgJi7JWL93e386voTBh9rOswi5mKulB8ZCQF3yalsJHJXXcDuhyUM tbabzBbrdbW7HDp5gGpJ9DQbIRlm0Gjc3h25vh+In4AA5AwPx2n12LMolzGD2oNSZM2JFr2oD+l5 fYb4PXGw2PEQ0/jWpun6TxtHlaliQgw1pnFlBeB3wYK3vdCfULYAAA31UTNN9l13Q4YVTJvSvArF JXmhqZLAsyIrnrY1BRa3p8PD+uQ8bI8edBQyaxuhPfDlouxz9UH9T58+vezkQEOoe2jCLubchx3X Pct7tpwcccPLX014dtCytSTHT1A4IvTvnsbsd+FqTDuN5MOCOUpRZ05WlgWQ7VeyaqtOua1Dl+Oy LbgVDi3N4PU5MToQeZauKGPZJ+kxw9sCXeQmj4PBo2EeGAAfww5Bj05cut67FWhkmRbI2u0+4alb JF2Oy/FhvltMJ60Fuv5l8GHCbD+YqvloqTUyDdQotWqAYj2ibCHOAoL9sC/z6oq6uCOU4utlHNqU oeUkxi25GK/ELdjJtgi1eH7vn5UDj1uCeHwDnaB57oDBmLtSYT9/P7Bx8/04Ed0IVBDMLcXFJsIp T5PvQNr3UAWfGgX8qKYT9ntStoagw+/IENV2ys3wqzDHje0r8RYH/wDPfykTBvqIoc3aERuzSxK7 SJjsyu8rx54ZSYoq8ZG2Fi1xFmRFdqTTupWT/lxsfVjq+d7FO+xjt+1i3QfeFgR7Lp92cldJpOsW hVUkghXqewLy3UqGkWNXKHaD7MhuFwPjBvkBvtqufvKvpfZyYPuib7uvz99+Ae2EbHq900tOFb02 m2ENfNZFesvdAC+acGxbu2kXer7Qocjg3iE9bmVhyqfYCmcMExhRDZkY4lG9O5xg8+AxAb+vs5sH j6zMMsqoLCNpGbDGlk+zlWQpvkWXE5QtuCe4Mi2yWoP7cttfvuzsxMWhjN8wxCHACDz5A9z/AEEr dLlKWsTm9VLdAh81bpxIR7OQ1eWYixWza2Rfh42mHZa2HrgJtHwHhkWUYoLRmZ4NpOx8+38+AQd/ 6IPI6RkN2cYs49c5SwRneW+Mdy055AYcXYopGSpZbmW9wg5RtYXHF6GVU2XaKNddjhMT8qQ7QMrO jW07PjJ/D81YUOwuEoW2AXxbr9cMUPD2ZwZAc9QPPBgmMaGju+j/AIu2AB9/P/5klgLY8pHpOxtO VzWRdkUxUrYv8kYK9cO16QU+YRw7Vw0O4GBkBgbgrSBtgzjHnEn/AH8fQfP+fFcyyHQoCW3fNGjY dLB6KU0d2Q4zEtgUNhPckT09kDmGSYQhwUOBdNOrayMF+TBmzfBz78/7AggH7qNtyGKDVgHbRfCZ koxJ2/t68WE4Jp6srGFbfMDLdwODJxvgbA+KvBhlXlHjg/NgiOg/2AAg4dCgYbOYxdclwuwkYMZj S6F491mhd+BXRllZJokjedJMDnGZQ7Sc5usMcseWfbwznDEAGyemdWdgXZfqFZyYLJEgKaZNqa/a j5S9I92k1dqXT6h7Ot6kDD4nv6HO7Pnwd2M3dCh0ZZB2jVxtH2DgP+rwDpbslgQ01Hh90M6SNQw5 uXGJO1f2a4yrG1Hi651UJ9kTLIMUPw+yUdD5aDW1lmKU2zM29hODn18Bbp9+Xz9RdM7vAUsGo74d wN8EtJZQ9TjCwWcyVf5Qo7vlXw19bMUPMT0PkgNDYLaCGOTq6vWfhDfB7dPn9/8APH+g/T22QndH zmPKrHTwNimI13UuTDv68yASl86c7k7X2Qh3wnvhghMgwLAnI4e8llXtAnb7xaPNnjYOP+3uA6WF iYxSO2yiTRh4YJbj08nOSBcVv454LUTXVqrs0q3DJhC/v5L5BP8Ahx/Vw/kn5XbiV5e7HA2201aH KP1B13i9hEVusAPukfIHOXob9LdT8gjm1haevVOyAls+h3tA2Fxz3DOyk9pdTeTLJo+Wsxl5fVEg erLAnOvJ6yb0qfS+2zquZNEesPH0D8mJkhCFK3RJTUctAWI/orkrLjLPrppuhBJcRxR2kL6xIkt8 MRDFQREjJxMQCkqVnTcP7Zv0dUTFfpnb8paYn+T5FH//AHCB/wCntTNpA7MAzPvAZE0S1bTVZ5qz XH46v/IOXJY2n/Jsu7uNzJdkJLvAJB2C2DFS6lsbGPLY8PMD7w4ckrn+QnLZO8vxmM+7O6Mfxt3D wAAAfh08XXenO42pDMp5KHV7GMuORtshTmCxaQrvie4B+YXYHW17lVSEKleHCoFl8VyaMd4T7oP3 5B+/AOgnTm65+pDBlGQaNCF7fagktHSaxq+vocpWuJyil7AMfqtslgf0+pVXxn33NmvBJ2TgNu4v 2GCDwEAzrMX1tjOElJu063Gt5qqbYav1FTLAXocopyiua343DMPt2ByF2I8C0La3gZxfbCXhEmqz 58BbvALdQUEBUcuw2AbJBStJ7dtFI20xtsqt+7JQfxfPTZAsrZOUzPuZzFHlyoFCKFLrm8i1XQqz 0pQ7RmTx5KyzNYxhtq5CS77xnSKnmOUVhq8qhjoaHMhp/MFqch3BWn+r7RyYnwnHEHsAA+wYn/AB NgENVGkGxDFQJrhUqemklKwqvaj2n8sngebq9y4L4e1HAPZEPEPg2/AanzxYt5Wfwm7gwH34B+p7 p2VnD0xuSmSsbW5cBvODV7Vzu0Lcyhy3PHKwjtSp4+kmRDfHzAgycD+f2rWSenOryfBki0cTn0F+ 8+fAdLF4qcO5UuhhothMjVFmG4iQHQ1+pw1IgZaHY1PVfDcDOm8xuC21gSAGx2QZWZRXJ/hM27Az /gMPbDf4TFqJHV88FxbF0ygeQcRuDb6bUbVPa1JgH8rl3LIljQIpT1EQuA9yKjcNHImIwy4IbJrx bjt6cwcWjz8tb0yMeopSZDJIap59zXK47xF0+1kBQ6rX63qtat8xZDBMOcwUoKG8jNrRmZHCbJ5/ H3Pn18/0bKcNkXKztruNnMlDq+TGs14GgKfiBz0V3lFHDmFV0myzK3X/AOQX6WnMhNGFFLfZnh2N 8H8BwE+hYoOKTrdoFmcvSjXJqhwlnZVb3HbKdDqZf+GBlXyLtB8ILb5ySaHXw+/OEA4h8ZuRXZsT nhAQDgGP/tAkCHKGRWq8oSQLgPXBJs1HMKyOXuADKpwor8gmLYeZVfMA9V2XaCiq7YzK4vcznCP7 /wDQfsHUKyoxkUueWLq8eAZxLJE7juf3bSnGuzgW3npjd4RWZGdaBdGytGigkjQrQrb3WUNkc/NL 46MI/r02LhSYGaKxtG7AS0g2EjkgKfDmoloMVilFt/2gPM/o6dArCfgyIwspj9485jv/AB/2PIOw LEfMrhIvtVi6lWWKA0tO0WLX11uOm+Hv8qIB4GPMJzInoUvFjtTGrp8JPw3R8eRrwb3s5z73wfvZ BQGcjnHhjRwLu+DY1zJqGSLcwAsEQOmxZe/B0CWYcDDg4OAb8gHoEMYsq6HUDMbdqudvv4DYAKCf 3+SX8ul4tNnlxDrFkfLWMakIjQYabf8AmW0BU0NDMMENwreYYT+HNW3zwkPbOLvIwG7Wib3/AH8+ AqLYNgZIGyXMYuXRGS7MM4oA5UMtuyapcshytcrWO40IMKotyq1bW5tYErVt/iHcCasGjYpA6dw8 NNtTO08VUk6S7CynYavK4G4Lw2c9pzXmj5hAO4WRMD2RX8ycpOCGD7ZvO1rLz92NgwP7/v8AiA67 I4exCinXwHNrfHOnzLRthH/iQ5EYrm5buuQCyL62HDmJgcehtXD/AJyGsvNXtAsYDCJJsGA38/yD f+iSyEev6rR85jF8bVQIEYWIHocdehNB4SB2cgY5JDZP9hsGMGYsjFcoTJ7IEdgePgNg+g9btRGY lUEYfGiy7ySUnvkbEmM49V7CyPlSlsPh08tuC2hmFtPwR+4Flg2TFmKFGZGBhEk3+rB/QP36CWJg KCNjUsSxLUk20FyVYlLyN7l5RXwsWORZRoVjAt2co6Or7T4Z4UQZYn80bAC2ByTQpnMjwr1e2Zyl cjh2lrSt+3oewnCt9PcOVbS9XMWt+BsheZNh7xBn2gBeIaysvgsmNeDZsI8c+fgHH6i+/Nogl1/l Ph5XSLsJVlWo0aw2hYTJZ9OWm4i9PbRFZON1At2oYhj1tV7wXS7w1nlO2M6OkpJvf+PnvvwDB+Rl 6ahUOeQSQxrJbXxSybRikFXOMKYZ8sa4wJ64CFjrZgxxBP2NuvA9XMxGWVf6Mc4TV3d0AAP7+eAd RxBsR858uCvmi5kCyKMmDYkfOtSp6cMVKeYXIAtuLJ2HhmE/h7U2p7bs/JnxXsz97uyj9/fwHsAw Pvyw8jGKaUppnLrJsyGKWOSMUELbkLZZc0AFx8HPIYtYxI0mJ3Yo8VacDbkSQ3kiG3xAsWec+3ha 5D1Or19ysysoCkhxrzsF2By2B8oHUBYU0XKrIAmrZ8PcFbuDInjw6PuGxoYx55Rxg4bCef8AAAN/ 2DpnVm8r6bl2ohnmq2nZoGxrCHB2m6F6YLFrwGJ/qQth6T+yAwNwfT+M2gU4Nwm0fff8F8ByA/j0 BtCG+Ntf39muSqNrEeq21YY8ZMES1ooeLXKLDj63MGE98W09k/iHT60tSHwZDwGLPNvZ44D/ANNg 6YVTvmYhsA5IV7ISSVl6b1thYK9pNfEoYsp/FA5cfpMOyMoeyKfT1V8r9Sag7NzxXGW/+E9PDxyB Aft/oTrKyTSNMhl3UEixyfUNFBq0khmhkZS0EKRp7QtiIWWuu0Dq4pY0k0yg7GoO40eQyj2zhTvJ xhn8DBvBs8X1Xts4X8gwuHsmyE9ymRZa/wDkCIyxVdhioYf8VOHzC7hDBvn9SkyfFyfOHbzj+AAA AB/FBP4RpgHYgZTD1ouX8bPZR64xP4YD16txT6RaBSGv44uCfDmEFu1FK8PnBxgxDwWd8STZs4AA fofft/xajAnuGUtsosDMk1jmgSVZODhalkO8zGm6nPRQ6+yU/DuDZ8Pg1L5x8J1nTbQU2PZTZx+Q f9v7/wBYvmKvcmDOgT6TNh9hCe1YnzDDMsY8WAlA/A29Dh6kIY+Z8/YYVb/tYyoObf2DYMcP3/oA MInJd3vCszeNEeP9b5/0H46zgBJQYEeTxhmu1uUVuuXqqF+eW6W6uDsjNKJ567r+si1BlnfET3wC rsM1XfBIt8ML8xbmODIYHzIMDfmoPwa5GjnJw2Edjn7Bz4Av9G18DylQZk2udSVSv1Y6h1UJbFoM mTqQdw7ketgC5QuHrnau4FtfMI54gBOe35QRkY47OwR44CfAfQefdJ9beFe6Y/xbBtR2uCLW62JX jK3W9OODRUrYrtDJX+K3T9cMifTzhcVD4tqPhudotCMz72b4OfQWA/4BBP8AVtK/W83WRYiSuWrD k2dzBkr1w7Vp9sPpRoE1fEMsG8LbJaj5YMz8gNqP7LOkt8eiYPezewoPIEF+PgH4/nlbZ1MItI6h T3viIOfApTuZ/rbxKA2xYU+NdzTBkkzmkl7gq5benNf8Qchs7XO3794M9bW3TqRDtHMDK6fxKwhp iVMk0jHMODhWXxXzT0UlmE9kMfRFtgtQ4Ar/AAOLaz/QxM5aJz/rwHfz/RWPsRLgC0OekGFLN+GS Ex0nJX1SZKV+ecksBbMGJnJB8ztKQxnY/wBL4+wRJCc+X9//AH8/i2tRFTzIpRPuQMkyQKbqQQLY tCjT1oO6HKi6j6vVw/MA5hbMJ7AhtSHcE+j5iMM9mZmBm/B7+ggH4Bz7gNS8swwWMyh9hDxmqA4E hK+tskgsYltFTi32HX4cwHcNnX2Q5ZY9S7kYVA0WgMWcPOHAGwcBPgOfH9ajCIXKjIeWdztlMaoV 3ZlrPytUPNmkMuUh7Nu3jTzleZIy8L4rx8/kddhiRlhqPmFA1kBEl3p/VFp7q8PeVgr0O+IqnQ5T cHBDZFvSXNT2TYWAC87YivlojBmx9kzgGogHd1Bfv1uAvj5ikh3NaCuh0mngdaS3E0j39WNr/MlR S13K7gwWRDZNGaeh/MVe0ClBsgmTV0OzMEc3slHnwFu7A/AMMX6tLYplHx0W7MfUNSas6n5Kmrw1 tHpxDq+xnem4u4WQH5gtwqv2OBV4EHgMWSj4zLPNv38/sAA+Aw388rPLmGWDOMgpkkxZeTGsK2AO lZGYWSxtQS9UrkHsBwMJ+oS1Fth7qT3Ch1X/AFkKLX5swdjiCAP0G/Px4+f6zPzgU8QsuEX/ALik GWPP/L2U2POQ7QfLAhXtzzfhiuOOMbUI3Js3uU5K0McCbOVCuk0owafj9M2/VTI2nnEmbiSKOfGC WHqYo27FMYPmU8n2pjX4exq0wUmpbJ4XIrswwHVxvfD4B/fgADYOnmlnA554t88BZKufLLslliL9 kV6Q+YKcpcWVZFH8DMGFtbT2SnSDABeO7+6Pmnonwn7wAPnz6CggPY+kzjYltrINAudejbgxcJLu 8WpW7REcHyLLaKvDsBiYYhsjJiyPF8WBdMFkp/gdoVnZjxvf9ffQaiAcBAM6HHdbW1GUnedyO1kW RKmVukB2TJr9hre0NX1ZSqvQ2APMcLgquYApPYWDfFsmUQnxm/e6ueP07unkAAfwkm4rZsqSIIcc 5FDSbkZBjRmsZbtvRoFMDw+XbI/bgO50mDrGvMksE9XKi/O3tcpfOY7l+W1Dpc4Gp+YBgQ1Jb2F/ YTBh2V+SASks8VDj5jJMp+GHIBziH8DttZizfDQTszCrrROe3u/VEfPgN/WItfMNpXBcigXZ8uQC ciMFbpIfH+IJpLIcXTen3BQ62HT3xfhnJ/LUfc9raLMeXhJ2MHUXd3nx/YAPXyY8UfZZBJFrmmNs yW1krdgre4KH0360bIlXJqEKWMn19D2iZMshPToL5YPzpjMs2gh0b7nAdXeAfj/aLgL91vAMmZPY KrPFOfrcC8m3Z4fH2yHV9jcxfHxxMcwmXCHIIc5CsCBzDbCgu31mq0jfAZ9+Pvz8A2BB6FJu0sXT BnZ2Ltt4WFYgDFsqjWR77eIwtd1ibH7c/wDwjyq+1b7xWUjRxj/5k/bRgcy8HxcsTOzc1PWwMBDr d3jw74H8wfPiWhq04fcNV88fA6+yI8Bwn1y4MyMr/jP6TaP4i9sH73t3o8ISFNSsCt56kyVvZzQe CWFp/WzFoUjcEUp2bctwp/TGYQ5neCHA4f8AAcFmzOL8mR0lJCfr9+v1BQQCCsct0eK+pbBcDXYb p9Iyaud6/cM7hEIoBxixbUwmXByTZx5hqUbgtq1Q9QLLQ+LPOEkI7+fP/QeA9WPR63bavT2WUiZN jy1aGgiKP/4ldZF20QnOdfRIreOT5tViLsfcLTVbKQHxrMWcLVxVZowV22MFgBfqj5+/88wYAItx o9mNpZolCVtCfGKOPeVu65Jtu0grjuXdPBIrLuPp0xmn242jUk54RiVpUUih43WW7NlboeAiLdfM ypMt8aD2SNMTw6TyglW8gTMFuVhHvh4GIeoRkcIdXhwc+j324tr7yK6NZhzmzs8bAeP1G/ddlN5g +wafs5ozXy0SSiB7IsFkIdficClS6cK5aZvzKfDzE9kx4O+N55HhLJPniy8vGyJIPfz/APYAHRVe C/DMvlAy8rOqUO0IY0TR8MPbEu7GhDsIWBZHAPdkOGtsi/DtTS0PgTkOzLfvhD2zZKu4OfAPz8fP /QcVuLS7QVzDsrq+ck5NI2EaLI8wbHs1DKIbFFrkyv8AbdDZEIPYAejzw89Orfa6HF4fSgmLyfwQ d/3/AOglIQVXEZPG6bgaffkiJ9s7yYJlt0cUwXMvea49xRbaSVMHEMiNjmuP1GJW4PJwzyW37wtD ta7E8YyEuvnyvA6Qt6b7PqAbSaQYr0bYBbgYFsKWzg48wmB3Cn0+ZBgD1JHmLIx8F2YzbIE4PsB/ wHQdcOoSr1ep85yMtVtGMnJUl6tyWm9opzdBbZFKsg/Z09kTw6/24ocgpKq2TswW0VmsnEg2E58A Qfvx9+6NylmSOcLZnngQO714S4/TLUvxPigV9XFh0+Y+Qw8wPPMQVJwQzkNG4GLGI2CTaJs6AX35 BP7Bz7qXswWr/SWNcT1KG5Z1S1kj2cq4RKrTalYXKL3QmB/hp/zw4OfR74DT1nDdHkYDwdt8/VCP PwHwAxKzmKOplaSyBDzlJce47DjHLtoc/PP4Sz9uatCESs2mF1kQVxH+xy58gf6G4tCHdVtlVmBs Y/N0y4MjvlZZtngapbR1yoNrC2TLiRBB2PPF6eSUqsyWROJC5B2eegerKKEWkuy4GcjKnR/X6es6 8kJ1rNtuRxjOM08R84lFyCgVlm1HDBq6lPJw2Y/JDZ+QGbnHNn5WGSjzlGAJlwXu2hBRWhLxSBYP qwmZqanZ0mpU7Y9WFRTSrtA4qCtC93mgKv55NeAdZmY8kgk+SYtLyfz/AMN1ZMeLW4FBuE9DcIyS GfLIEtGdpXpewnxypGIBpIxaCe4TLVfA48PqaQ6/rQHZFZExf5MBhHak3hBfkDfwPgEHI9b3QUS2 qK7mLAWyieRR3gbW6fbBjs3ccqUtkA8xktStw9oTAdZuEGCHRkWrydGswP8AfQHnwHAQHRfMy0My vuB6Lk3Yk5W9ltPFnTB8uHFsZIlKz4whw6fcENkcK3VZ4+BBMDGb+HNmZgenjZEffz+PID/sfiO7 FsK6OSeLBmX9qEY+f2F9qTxKEBA6mrGlGOYzKrsiGYT4femv9PEHAnb/ALVn/mk/iI/QaCAQe7vR XE2ZGBeEqZXd8M447vSgYsO2/wCWz5Hp9AQyBTltI3cErL1O3ccmx7+ztrgA8m+km4Q63bY5i2q+ zjdqSiSkJz7ITh7DMFvlZOQF8XzDIIZJgerw6rZa/Pp1xWRhRoJ7FzZ23/YOfH9/AdWVzGB8yWCk zS5Sem8lXzsk2wYo3RzV+zi6vbCib+NodkakJgdewggbAun5gxmQxfJgfhP3/FfP7AA6X2ZT7o5O hK2haeEmUjkkohgC1VvEMFJTDXJ4wQZYeNkQ4ZDZAKepI6eTrPTm+DEZHScUk4AxPvx8/iAx6Go6 XADD69Pcqf63zUKyCo9qzk9TmFLaSGiUn/MMcbQ0PeIPb898ys/obMTB4fR2D/Lz+waGETqVY3dc 3KtDi/4pY7ux7rqjVc2tJHVg2LivhWi5uvO7BL4vigPDXfFFYeGD3BPQ8pqvVJrR2shhDmLDDr0M qB7ccbcIdwuC3qEZGAOqwLQUp3BnkorrOHCfNn9/58/H+rUOgekzLrf0Btu1bs4KyDayX6ruCwVO H8oTLV63+yWQyXWn8wONq/AajCNUCsLWVl41D+cqLz/aIB4CompRsuwyDoehymctgU3TG7fIr3Tq oJAerxbZXMqGPiTHAxMcCE14xX7MVZjNWYsWzb4E5th9+xwx2Drkr9gq8DX9evgsbW9wW0HNtkdJ GOFezGimxMUX3QMMlD3AhsjhVbU+484MVmjd0OcvATGk+AoP9gAAD65A9xymTCZ3RIVxyPEsMjEm x8RqpFeGv7aJQLbyghMI0zZ3kwqqIAXFrysgmxQHg5cHYc4pq/8AguVhIbIHu7OQKyDwya+77DfC 9qClOC+Hp+ZMhmCK21QLQQzhhGJvmLzwZ19rUftgP9osMD7882B0fTzRXuXQUyNpjbUmtxK/QIGj 6yhORR3vipcPhWo+PkNDIfA3CpUdbZqgFq7MtPBu7KuOPwB/YP8Av1J5hxbMx1VSrkC716m2QybO YqtXXocqxncC5B2CyLIhh6rDpyHVdl0fypPrPa6v8G7BEkGe8+fQd/w6sIDqqt74wmVzpVv52Q7Q JRlOOnrlsVOyIQCXUotk5JM1OVvM3DtyhsCjcRgmjK5RZZvxc71XjsAA+/c+6GMCaRjJgIQh3Fke kMC0BCUrv8mnyXEn2NlQFnaM4A+2rP54U+PjxXn56rSPrMxdOZWNLAWrTNVYA+EYXjOv8gkPiaKs JDtpwX3yHDW7gZCHFXxfUp1Vk1lnaLMGA+EhLU4CfAL5/wABgVUeDH1UwZNQVfbS3bcpD08VlbF5 TE+nE+ULXgLTMHsifMxDshEOcPD1L6y8vgtZJ2p4XHE+ggD6CAxXwHG2ENSeWGzldIyX9kVxvcFw Y7rH6hK3fE3lG8WDDDuC2hw19PBttYPm8bZcm2Eke7DfOcfAANgAAMTBQfLRznt1MxdNVA2CBs6P 9qM57uhLDQpysFBfqxPtOyMETARg21fp5eGN5eMVcWsoxx2NY4nzzBgwH8McGTLKquHhfBaydGiO NmxaySRXdEDEnwbri63Mp8QwdzQVfb8i+SW45HNc31G3LTXarR+t5rS1LdnSj2oi4yA3OpdsT2gW WRBhgeY4et1XMYIc6tCNaWqyPPF0NZxqurvypv4Dz5/Hf5GlHiPbWWn1+90yNs7SNRtx05bB5IR6 9MagdT6Rp9TU+wOBob5MD/EeJ+n+lnjDg3vUBLEIDw90G+z4DkDBg/jauyWIpTD1fKSeyWQBMXqp p9S0baDY+K6bqaKNFqL6G4GdPb4hL6ej1oQn3guWYTtB8erMRwnnO0WwYANg2C0WoN4R7Ut2dFqv R2zaWFdcHRA9hBli429yiei2auLjpczC0k+nU3Cepv6krYPK20i0h6OnLsCnkL2xPr3/AC+k9HTP GGY7bruvp2hGzYIn0yTGYFilUXEUiSwyWVlRyqMKSUxK7QNjcKwSivfH5A/y+oI3+f48fnIUosgW rgVO4ANGVvJ0u1ySbVOwDFSp5aZYtXqZ60Jae+LcwOZ28xOodwgVwt/aOTc42R2R8D6CAA8B2BBd kx0sQWDG3dlWok5WoyjRtI1fUunUxDQwNnlhdoMtfp63MW5ignzEd8IWXTrIMZmi+CYyq0kJaPgP P9ot/wCmO2PkB80eDavfKfUqNt52NRLQybUX2xvlK1xi4vsn0ljMMWTaAYHQ9ovbwns4tWpp5x3t J2QCv4nkHH9T8aT0AW5pCiKzjbKSyuCxZdccnpqyKga1xntqI01g9DrtW5jHcM2e4bgfAwJpNlZx rusvNI2ilAscAGKDYHp9R48lY8lWMh49SCJZpHERzK1ubaxzSXHPa4uzLW2QEa2x0K38oZEmSRAj Ksn8U6AAEnA3tZGuBlbe3HlQENTE9crxvq/Nrak4QGY7cvSbCjl4h4ovW1Q4deZGTtY30mvslxcP 1D8b3MoUJjARsJqHtTYPPgOQbDO1ePIE7HSRgejQudPve7FPGztMbRcbihppbfjA+ZwMOYDD4gSt SBCCY+hlMBZw2E4O/AD4ABwHnwBt/wAvPOJ+VqWarspN3DrYmwE+ZU+0Ve5aj6HKPo8xMhwoafzz YSCic5yTV2jjPCTbt4AAfAHz/sAD1s+75zmZcarW1GJZ9NGlPBEMAGCZYzjYbPST4Qw41ZMIzX6e qIdn1qjGGYW03ItDDmFpG0c+/YoJ8+wc+6pNE0cWpbTqg1Ev1Goik1M0siQTvtZSlpXfZgWl9OPC GP7I1yNqXVkarSjVTTbUTxxvtLQOlA7laj9tqAeSQTwK67HCHqEUqTvJ7UodJ1LWjs22FondtOod gQz0S2MBbh3gmWphZMwgHeMWECDh4oz4TrPEGFdjX5eqMAA5BhiAraEufVHTFf2/jU1MqSHF1Aqb agNxIcqRE1yhxhb0St4xMqwPMYFtqguFaNAhn3S0Mec4cJOIOIDDkCAgYn7bOCep2W+GMLLo1SL6 lodo3JIs5bj6cA9S2Mwpr7M7wOC3ZEOZ/qWPgQXwozK/GRlV6h+yZxBfvAn8d/6SdT6sMzKvit0N SQ7ImVfahGJGyarV2FwV7lbAIGGPD2QtsiEtp5jtLaAH/a7RUBPhLsk+A9z/AD4+fxasEj6aWPWF NZLLM8gjSM6fCNscYSwebIrzTkLd8qPmF4vqc9I4iT6ZIFYyfUgyKe+asYsMu2k7uReXXHX1V0nZ dVp9NvmnuSki4d6iXCwtVA9s7xtFTq4tPcHCZvFJp6+YeDw+eccBnKOTb4EpL2P7+fAcB3/okODz IZLW5TvWMka5NSAkV/UrsrsKELq/fkN8IVBdmFkIfH2TlvwGpPWeLPgwZiku3n8f+wYdWEMNF8tG WeumuUMJScCq7jqdomB5FDbWBsLVABML+EQxDT2T+RfHC2gfBhgtXRlne/8AfwAAgr+GB/GqNsPk htOMjRYMw2eu4PJd7YuDOYFMxsJZxV7UITHCZZC24D5jxWlP7GycG7N7mj8IN4/X/wCvz770VNIC UzTT8Nw+EiyNWbyR4mtwBcRkaxayfijIB6mffJiCcfCRRwxxoRZ9uLG75DEV22ZjuAPzQ55SSK9q UPmp5KvSFbrZmWYaHK44oGGQDsj5vCGPT0fVLYCHOmclFtJTY3Z2SQgBBwQd/wDPgONYsBsgWwhn kOwthUgMmpzLtnBmDsjKpx8aMSCfDRLguyZw9WA474yM3eQVwXhKSk2p2i594DYEEwZDhyxl8+7q 4EIhvhhtiWQ4DZDEHigflFGRfT3CZMod8YN8bavgQa3GDOL9zAZtJdjqDgfP7B4DpbuDAr5MwPaE rO7MLjIyO4dPMVfLDvivQ2oupXz5gdb+Fe9oPnuQfDieM/oZGqt2djeL8B/Xn2wPyWCvE0YN5oUQ 1yJ2w2SBf6f5HPF9MUSBkmkgfA6lY3KHOkUUytQXiW1IP24eG6mEchT6SYW6WMqq3nRckbcYeHYS +7p4uVMlcDYIa2GlzGRgZK5Uk9DtTAYMKFKzqAH+LjgDHfvAAF/okruQ+IcxqbaMSSVBZo1tYaXy FuOkJ4torI9XLJ98/h7ZDC+n3EetFDeGSzKzabk4ycq4IEOHwFugcai7Q1F0VZY/UQZxdgO5VKqt Fbu/cGZnr6R8W0WwCLMMC3ZC3ZEO4CEzftH9SzjFmE1fTm8oyObSTfAe7tRffgHPljvi2BVxuVAZ LIsKxqrCL2ke1EOv0lwKFNQm1h2C4NPeoSk64W3BkOHq/padW6z344NZnNjYPz/AUHwHP42ZVkaP ccuyILA5TGzeLechxX7s3wsLHGwl9loj9vEgLqe1JL7K+Tg2XHiuTCpDlXhnACm5tP3ZDulJ5DcA eGwLy2etF3rkWyL8Ot6gpO1E+wYcG27QbVV8ZifPFmoAfNucH8EEBbp+okJC6FbsyuzZCZ/inpIE Dakn5DXTPHlsC+MLQr9r0OGh1u+ByFko8/VhUv1m3xZSs3kGESecW7/v5B2E+n6/sTaqyT5TvuTs BmJBZfqxbkWwyC5S+5Sgw/Cn3x8DGCExVtohQ9jbn71fuaPVwT9/QbdAH/AH56oiiGFHsh6pa3QL aq9VkxHBPDsFm88fIb4UWx8yyIa2yUO4c4AuDbO3N5q/nTz3Rq5IR9gfgHvi/dOj3GKs39RESQjv il2iQoik7fTTNqTE4Z+5suB7EpYyipxjHI2Eie0dy4nzf/Y9dlmNGoAWn21eaRhW4DTSS08WEHdq lsl3ZGgC2K75ajAycDW3x8p+YcfLB+DT6MzcCJkgbsk8HYD9RH/Pv+wGtzrdXn3DOxAy6C1Q6brU JMQ7crAmMjTbSnFPIagYMGbUuFOr8RqZA4KbUYWXpn5ytdr/AGxP8CPYP6Diefp87l1vnXIBW4sO yFWtLCSXfnkwh8NotosBFzF9DZJlJmHBfWwe4AWpk7v1f3fRkc3aKSb+/IPPt/3+tNk6jK7zaTMV y+VXerJqHdm2JIdr+X3fdE1soeUtuFpp4dbxmV+H+eQQ3f6N/oactGrqu7uoIA/sCD58pAjyKCHw T3CNN1JMsKXctMXjo5pi1F1N89RJHUOM0FyYYTNh7MeZYaayc7UZ9pDGzlxZCEntp60aHr4XU1bx J9cSogesaxslhtQmr6g+eYdtkMuxw8GBbBgT55rmDGd8KVCjYpWofFIAvz9i/YAD2B7jmD0dXfGo XPJVKHbUKrpY+sLIjiXBNQ2FX4ewJ5ih4fD/ALz3Q2Nkt8YUK2ZsZs3sbBz4+fP7/wBbbGSG3Toc yhlBtFKak60PVMAfwIxBU7HlJ0y97s0+4yqGvvCrIJL1YT7eh1UtYeumSnuC9VWmfU+nwXp9Hr5B 6cO0rIsjKiW1LoK1Alkab3a9V5gqTOeBVEezDbQuk2CkmSyNmmJ/wIBGAqwnmzMH3FYBhLs4Piff kHf8T78fSS8DYRpJnMiBBJIFgXS6e8GRVQRxSNvHCNI13aNuojA6mCTK5mDnacljLFEkgknxMcbP EibpfaemZRhXC956NsyHMd9N54A2wq3pnUOq2TLXyVkEEeZYxSJKctvDhzBiWY2dHPV/Ze8syzTY v23sIEOcf2E/z5BP9VvsSu5HNFWeGrFkhq54bEvAC7D6cvloTF4DpzmVeYcLhuxPQyAcHuHwZnbN ouTznCauOVEfAL6Dv5/oqSxaW+D3XiWqhtrEoHQLZV6f4+kJ5+0LNin63T4b5SZiqw9gOCruD5Vb ITxF2g8s2yAzewfqA8BsEw2ZlfrlsKtcrg0lWFqw6TLJ9boWndefIrRqEVzyGw4ofeCZajB85D4l amGKzte5g+bG0dB2AAf2BB2AkVoGfCXJFfUuqbm5j624RdLV7wANH2XXNA5G+odpZIkjdtuxH2xn CKKMYpzj/HZ7j7iPiz0pGlQ5cYDB5pVlg1WqzDTQMmVjQ13UwwJ6CWBM5cRkLubn6mZ4m04/oy1u Iuz0r1yZBpaPVJPrdwUiMQAyQl0FnRPn0XTeoLOmn5o7ZziIcbKmYV+1adWbYsZbKIjefiZIBt9T mEmZdeERgaUJyMit1D0QlAQN+AchRfWWZDU6ZnSzqkQlDrtsqcTHshsKxGOW4thaq6Fi+BZoxp4G pm0hZjRY7nk8Wa2zV0TVmrIvmxMWSn2g7uBJDr7UUEs9kAqSQPshJX6yD1zXOsVnqVPIQ9QtwWoy OFgGLGA3A24bYstBSs8dk1e9qwGO/wCJ8AAf+kktrdmNAvOsqoHZbD1fwBhtiYeHXHZCuriRauhk ENkmYsiG4MntqAbaPcOMixaMjd0fvB9BP+3PT/VzZhA5d3YcfXJgktns52rEOxkniwTAtoLRHKGv w6HfFtwqpwQzlSkLawTybzV/JnnhKSbB/X8bdx+g1FSdkrcmBeHYDV5IlkwKfW3dPmaaZC8HtByi NAuY4GNQhit2RkX3wG2j+VJ+57WLKA3bwb8g/qA+/H7j5VlSJFhheJoi43MrsMU9m3ItDGTvqz2n oZEaAsJN4TOjpIcZYPIXE+rGM8eeF8XRI4HT4o6o1M8l17clN2QtrcpVshTq+wjFbid+tCmyltQ6 /MTHvjb4Ph3FgPQ3j3rPa/ypsmJy3eQAOA+3UCt0HZFg1fbWVAhjc5Sm/L1UW1WxBhDq8lerlXcL AW4e8WRuAdHtshS0GY8kxdy7n+oRHAAD4D9/YAClfFup814DudS2RW+oSwc4avMMyk6nsJlFykdD PUN8xPviny7gnofzyCG8YlBloVejPNqfdng/4AAf5912Ols35UFgOGUUyXZq0qnjbZU7VpqyLYfJ UVeV2lkT3AP8xkwq6H8BP74Q+75QoT93Z3q54AVEf2Dnz91ZSfHH09ReqR6kTsjgBPYEyO66fYuU ednlceVs8LMql5Yc4WiDiXKR52ruR8VEe5XctN7R3Guu2r4epSoLEh6jLL43qu08LcZTj2ENsCwl spFthDcqfHuEMxDEbhvkBg+DtjMLaCazikm+DgPPn9/2AAUg0pgXE/OtVMMVck79H7Xnlsewhygt sKWMnjzFqB1vjZAxO4fiq7mTq8oTRjmO9nAFQnwH0H9exPZMtDr8PlyYdbtSbT6kJYJhJfsKt5Vj 05cnJGCHMD2rDW18Pv4A/O4ys2gLRvN1cb98OA+f8/A0mPpOxh/yqvarafJ55Sd3AwnI7Y4VzK4u LtQ+h/khkhp8OC+ETyr72Z+TKg3pJ7qIOwAD58+wYH2FVaOQCPaQPg0atcbYlcSi0NusiSLa7BsV 1cbZOrNI8rp/Gzn+Oypah85UAeRWNc9cZxXTxZStspNmcDfM5Sd18C4fL+LEiAD62wQ7IW4c0xhz mAnocExybtezYnHdJSf6BQX7wADqefEcgLIElyfYKTYVg1XUtex6TOh4j4eV9QiuL5A497E9PZCD hOUrAPPFkEyRQoss1V7IbeAAAAfAAPAHyQOQy7GH16kJodbuCfqQJO7BUpi0Het65lbomshBjW6r MXxMX2RIPD59coawTxaPaq7R72PH7BsB/YOg/MU2QCyWdlKRiStqTUgLyvMJc3T0xyLSgMwetrcO yQ/eBw5a4PiPMWeUC0UpwnwYAAAP7+A6EsZFVEdHcWyB2MecbVi4OLeaNiu2hzz0cYVKxzFPGXwf H1Iwc4z2m8cgQ3HuJx56ZC/gDaOePm8BE8XW9FLt8O28O6GeiyyjmYHwzFkQzEP4c7j9l1yt8Z2v jO9hPPoO/nwD9j0Hg7cKdr69i20NSbCF0yEYh+SHIL1wVy0MIGMHxMVv3U5i4B/xeB5IMZygvjLw bx2NBAef6G7Yr9LgKhJt00sjIyHgKSkK7I1WAJW3w9WRSVZDAHrcOYDvlgWoqnx88GnvItXKDOcb JsZ/2P8An9g6tEQtys7VUyUBoT7srHWlMf5ceHfzBcYe0N2q+UYIJ8NDhvjgPMVy+e6rD2z7NWYJ KSTfPn5Bfv7B1meOI7U0t6nZmjQSQ930t6U6YpIPmNMQ7TWPOOA93Wjc1MMewgjiWf10h1EUS7iP WLLKkaSGgDlutLWS4YgtkjVdHzWOn4aGmgWTVFqDD2jE4rYV4WFiKoiJQ8WYPZJtJmK3fPh0eBHt 1VoaMzFKvZhndEJaOH34+/eAAdQ9ZnF9jeHxotDloF3wrYs4ab7CT14OLx7oK8NfDobhs8zZ58D4 ECH9DF1mzG+1wRH4/wABfT/n+gOv7cvyvnDUVm18qVc+VfZyTET7Oqzt6YaIpauSkxfrfklV/DcG Sd3hrTZxnA0NZJvAQIkPGP1/wCDsEwpMDopZmTLtAkEdq5qtkXh9P3YwNlkK8pIFoa38Oq6fcDEx fmQTy+PVfd5QxfGTpu0TfgPoPWponD6hZVCsXSMSXebmKKWONVoCOMbpVFybCibOVDLv20LYwtso E/ion2mycjXiq5qj1x3BQdm2NX92GagTwjIBG1uJ75WFIE1u0JrZV55Q5JEsiZvC/wBxgNoTzu5L NoXJUCz4QIc37fz/APl0pVPi+VZBJjSEM5DnocYTHSSQ93cHKVWSuUiWAYDrfciyF8ucsun1LZ8R lNFCfBzZtJB7B5/f/AXLqOzB7kvh81jhjUOvs6yBNfn3Ae2d+ANmuUXkDgYmbOyDw7VP+ecD7Zug x57XHHZ4599fPn8OhC9KyfIoOvZ+aHjKtjHiUr/Gdh8MPKKMP08hDZPmGPrcFtHz1VwGborrDMcC JP7Av/2Df7kjZiEbtw8HzlkB8cVWP5PnpQkRVDZXl8Hiqr/W7v8AXQHV7Jbjvkfjl2JZN3aVhtsG KxmWxLhtFtfFTeH9yKTquEYcDOw87gsjM8k6v2w5wlJB4PyDv5/pkMFwWYkA8m0KqcIw1jLoCQPf IcesrIsZX3W2k8gn/DcGOYwTJwFwA2NyYZ9G8J+v7/wI+/cBFQ6mj5S/kwMmseSXdDW3cPn5xCwo blXNgq7SyD4YeyOH7h3U5hsbgT4uLWSeyec/397n9gjay095ltWxnVJKJSVUqhbsHdltXiTFYWW4 uyXByQxhvFgGAbawVKqh9saVdGJ/SQgPfwGG/wD64TBRRd8UHbnV4RihGlWLxtubFjiuOScXkGCS PJRVWS7k43HBy7c+zijWI5+RDjtUCvKzMkXm1Wk5OaYCV7YKq1R5cwCULlHLh4eZzEw4J0P6eBa1 sZuvOeD/AEkHi/fv+wP3Ta1cI98C3CmVdodqupm2q9q4sHfBtHrzIeKJEXkneAO+GIcP4c5SYAIM OMehTQMeXg2b8/4FB2AAA6CDhDMqVPmBU341hRbCIiqHaklHpGGUA2FXMVPcLIZJmD5ZHzYKHX6k cMI6y+U3UAyqwuybBv4A/wDof6nVZSpVSQFGWp1AxLhPPS4dgN1tWe1ONn42DZwsLPMVWx1bjjBi 2KDUVIKHHWc0DSWAB2ws/H0+kB6fev8AFh9a4pFCK7b2zxR05xlfhbxk52qsfa+V/bjyz6fueA+i 5cmQS9uEnaWjUWc8KFt2+4dv5F6v9fKENPMu7tgN22TsAG1B8twfFd3V94X1u4Jhit3DkgKh2CpV VD3N8tBZRng2bCHH4AA2DYACD04Msu4ARd2ccmJMyvhrsp0O7/jIPKixCibDYFsut1u4B+YNR5fb VX7MLtBGGHAnvsB9+9/7BAuDorqVwQ5VfGEqyEgPJ4uhuG09r5USxxdbj+Nvi2YhuEPcP0ZCayUt DHfPu1q/l48fQcd/6O2BHrdXrsOZFvkavb9fFtSthVWzEMO0AV5Nrn6finocxk+Z8+wJ7wuEyZQX cDyjVckhAb8A/oE/gf6ilZIoRHmfqEWSEumGaWtMBkx5/Hxx+R0bLiShaMvFUTKjZ1tgAMTQrOzQ o1R5PSImCx8CHTLHXy0tzJWdGluDINYK9ZHyS2IYFPIIeoSbDm2piyA/0OBybyrtHJvxdwj6Cgnw G/4dOD15YddD3Mhi69qW7JWoRS0tPDJMI3HW8WxomBQwwMkyYthw6+4NUBwbUcOMrNpKMyy8G6u2 NBfrdAPwA+A39G8sKZshqTrHzpNYqRiLLHmLCeFMw0Pi8U4e4mMP5yGQZJwFwPX8HJo3KCbNsmyP ADfz/tv/AB9wPCvszZW9jK7sk/4pJSSLYaphiWyIcUTdzRD/AKbcK3W8XCubMYAOLITrNofGZZOO wTwCCfP7Af38BH9Mr83fcvbItV7H5xv57TdD8dLdY3LSe+8UwAuR86Gyi/O5j3NfZh7WvhVpdbr8 Uw7FKlarRZLBvL8H5o2PYVbtEqwhfJKvvi7EO1A4f3gzyGINwRmfErUCyj7JiDAIPn2DfwB9zWBc BGn6rVYEqwnasUjOCfxAVu+B2ExFTeL3ItkGRP1IGDFb/DtTuA2/DWVndBgw54Q5wHwD8fPoHSBI L74kA/gHlBbMQFuMkbmSV7YhyoglyPWoQXEOHdlkWQnh52mnfpzIT8p5wIESePgN/wDbz/Q2jslF wJFhCzMwIRyoY1eDh2qrizJcoGJFF2RX63ageh+YD2Sq3xfwOMnOWj7NsnCfPnz/ACA+APgCmVnk LqrncreVFyzxIwvlQuNvXBu/iui7QgVnQ7SJHp4nbbG2p9okb0xjxZdksNwDzTmsyYvq4eyLBM1K khwNnJNZEFUDSAiYLqUS+REMiycwDzFtgD2MBo+y4P5fFq5P8o4Wjz7f/wB/4D0ziOY6KVkWdaGV xuYBZPlmA9StFOLavUooXbS38NPQ4dbhmDuMBT3xHQ+M/WWc4ECJINgPnwG/H2BB6p+DuwOeqfEN zxJmOS3V0St8mwiBdbQ1d3li4bgHmMhia+EMIM+ruKraNwMoz7GkhP6AAH0HpkVIj5QYWelJqTUt hVBp2QZfcGx63LOFItAnG2g7jNQ8LH7qDobV2/PPDgso1X7ZsZvhCMAPoOwPx/8AQZEcbcRO642o tQkg3ZHv+No0taAp8hZsFORXUjki5eNnSq+lnDYJFdbm4QG93ZjyKxJ89G1fpbplZS2pJqq7Ox75 NZV+YMSCwdoq+JXNNw+YTYdwTLIITQbangQVqE0ZDQ2ZGBuxvfNgAb+ffwABBZCun6f5+og8BtWp K3mV81MkvsOnp4mGe7e3JaKeQreHW5jgdgTIM/BuNsiy8tHk9lCHDnaLfwACotgP0zT19sY6Dzmg DZq3VeqUPqrXkeznD4jIm207pqunr7hW7ItskNwW/wD0vtkANub4r9sweITUPwF/38AAQfAOaOno W10nOd2qSHbdRRJhIHpiu2VWLaCyaBfCAdbsit5k1wQ2qAQbQbIzDPy//qibB/8Afz+GwTcncyHd 2x6mmEjGWCSXUdgxaKWBajHmORXfMF7VMRkQgUxEtA8tpp5md4fQh0+r2F0rmbM+pNJOUkiwAj21 OchcBUmQsjMpFwmLk8CSW3eEyWFW8P5C8tgSiRaOMNfW5i38yGQhgyDBWnw9sV3x5WXgJVzsc3/H f9/AdO1pZF93F1i7vgEJMP16kxKPzoa+kbpKtiUhmHAwHsd8T9wD1z575aMs+TJ/1t58AAftgAAO hpgmCyj4n/AmIMxda0mXZCqkXQvQ90sIWm8g2e4PmXxvCq2sFtHHBmKe+nomcCG3YHjwH37B9NoO +WpUupwPfpmnwZmuYepB3kOAEe2fF0+rwGuqrX+ecwmcgtRqtpfUgb5WfF1f+tu6NV8/QQHgD6EA jKjKHkV3dUeN2WaWHcjl2wynaZa9gosXrkCubEPHGkcUZSBC6sgcxNUcVFYxuwyXjmbZcD4BU8UN lCD4LtBp7P4O9Mu9e05wca4UvTr5Up53pwotEHxPT7Uh1u4PkECQfAe2W++Xw8//AAADYPoPQHXb RZGqWo0M7Aajbsx5NkLy/D1RMFhMgGxtPYqLM+YGrfvYyV+4Th9fz/mW+zCyqMzI5zvZv/5dP0Hv +wceXXdqWhQ5e6VeG7aV6DHNrDTAC68bCWotENsUooYJ7itskPb5mo1Dr881dy1hoKds/wBkxww3 /wAAfAdMhzrBHC3IyOQugWSvavW42mUPkVLaG8ABVZHsEMcYDzIcyYPm4qTAenOJP8Dk8UerUl2O P2wPx8A/Yvx+KNK3pNKh1JzUS6afcrCbTxz6addt9SuoX6iNpEy1G1QF+pfUb6kCSVVcRLjMA4CG OSXmNkA9N4xi2LxxQ7nNrajqPvkJdM96yINb/wDEKdqyz1VST0uzHCgWj1adReou31MBDC2BqBsd RcbNlS2u3GQpF9CU4WmJzc4FY0evwzFCnm8+RLYC2dXlUNTGmMctg/VbdnxK3ZiANenQItpMVGG2 ByVMF4VBVrNH5LhqCpkitrthB4UdlDqkKC7hQWXNzYwl49UXH0pqbnSPRXhILUUFO4BYFfGP6P8A 1/XTfo9TfeJy33f3bVeeP/a/fj/QfPHlYPR78V0OwpQvKJHs0wElPB6gUd3mAVesilIGCBgPDmGP viOBH1pajh+LiiOM5v8A2AAfAYbA/ALpLavcmbWbgVM1jGG2DSajU7wBsin6ctSVpfU5SH2/mLRi +Fu1POQOW6c+MvNyFVl6/T9/9jwA/v8A0sVsfMsGYhxQ1GoFzGe27DT9YochhcXPhCarsfbdbW4c xDH1Wj2WwKQP/S9DZqzRzZsIct3wB8+/AH5+h6rX6zXLQMMaQ4RqH7MElPlTSHd4fZHa+Sdk3x8s it2Oeh9y05D4eTGdr9sOJPCTnAbdPgACCfP9NlEbpJt4GsF1LLFKkcyNdRTPEk+Eb0bDA5kGiMT0 pJpEkhLSyO7ZYEvCXXERlsI5ZIty+C2LDEhb8i8sfRuCuDVpn2/Kdqv0i2CdsiXZGpuyKfsJP2Fe qa46g7jzNQlbp5kdMggcIBvk4zDHBmxdko3vx88f8CfxPqu1WDVgZQyVabwpHqvmVtTrAn5zBL4a +CbQrlw/1UmOAdf4rPIbGyM2BRXJsyObwSdg58A/YD/ViqD1AQ1JHretK0slbrdy0ureoSQBJI9s LYErfNX3LZCe+Q6rD1uHr8PAbSHwTFmE+LjFnmxv+vkH9D/2B2VcnuCblnQ1jGJOTmUPGr0gYr22 L55kLrJXKN94J/G3BD29bav4gJ9cwyYyryjw890QnOT4DgL8AAIPVaM6uRQmo0yRalHmggjieJtW I9PvkTrg80g+pjjikKSyPs5iPMyxzRrcwh08jSaZpn0+ALTBJWgjk1ccMMke7LHFYgkndclU7uzZ WLIVWORfliQCFeuTaNpPOr62hthGGNPXyyHFKO9oVJDHp63D2ett4Vjw/Txu6MsK4t5WQaS7JNVo O/n9/wCfHz/wYSTtP7+7WBpMtTTOYOutcHwIFbCmF29ilOOci4l0TabfcMRiAF6ebj5+upZMnWLN iUO2f67POAV6wV/1V8CYTuMdmQw9jVfbYsoBG50pwW4i+n5LjEmAcVO5DxhgDmK2+Yt1fNeMWCeD ZGfdBfJkdJSdPDwffvd+P1FwHrcyCqrykejdPHZ/sypKqkw3xqovhPs1btDadhh2hp7odPZK3ZHC GjwGBt40TRrk5xWfm3bCoj5/wHVTORJp9OrOfqv7rqEQRHYjSF5RqHVp45JI1wIYRxPjlbsvaHuM 4wSSGJPSjOphkUY57pGaFe6scFprN2TiOhWyGio59kO1jTxtJw65tSLZtHmXCp15DTUNhA2ghsG8 PlJzGQeYnNvA94JsyG9swzmwM2EAIO/gOP7BhaFToxPtq6GOoV3gNv2hW9xtchbGIBZOQ5d2ptTV WnTMLrqx8W4GIJtrCfiHZsHwXgN2NKu1HqJBwAAP0P4VkFuj4GDh0hShympXMJNOOGoTT28JC2Kq /nh6k2BkT7TD2mh0/DeKlHz7U3N5q/c98q60QhwBz7HtD7H+hsG8A6zr+7GOs6ltGHPshJl9nzyu Jh4lKnFxdwhmJiFZG4LfBLQ4OGWKzV2jjKP+tVW7boBf2B+fkDDQY3ZlcnN22omaqusgGqz+Txfn 556ESoFXcO4jchCMcZFxwcnuvHImq5smx1a50T7NFo9nVCGzpNpriHqZrJorCyGCWnuTkkfLrdfx shPDuAf4bx2PfK5ME8VfEZ5tJSdgAAD6CwIJ8AATK2rmMogqmbuW7aPC842WkNQ0hEMWNu1cyjA9 DDsiHZDIvmPn798PFn54sjN7Bm9/5Af/ALB1DrYuRAV2Q8BatSAem8pSpFpcDw8tDq8Wj2NK/G9q XwnmE8g4I/b/ALjS7yWeTrOxhDeCO/efPoOHv05Q5BYvi1dQemDTlpwtB8a0mpF9P0sMfe0OBqav WACn+myGMRCRJjC+I10U9bLSGW7eGVc8kcUnEKcfcV/1L5/0gT3qXClKkc+buMfURLyzlhj5XIY1 uA+45Uw489LbE5Osm154mkyBxikk7TitfxYtwbzB+KMQpthQCp8c5UNcJR4IJIUmHIJCerlLClAU 4fDmMifagef25bWCA8OCKsi2lm2PYwmwc+/z/UPjXBV4am08NfGTJDzyQ2IPalUwJhpp5tsYC4EI kNb4e4L6eq9r60+YMqDiyM8nLRCez8fQT4A+A98Fut0+8XwDJPgunxsOBZFkL0gPpvT2GY+WhEPN FVL/AMyYhzA4/FqxH8HW3lm2tZ/ZDZzf35+fgCC/Hz9q9OWnm8tTzfW2n4VYszT+MrfJOhQNmHUg JXFOMERFUjza+5mKe5qMloszVc0+m4sX61CaxZqOHx9HoYn43X4PMYPSbBP1YV8WaeTR/TOKng9N EK16Epsk7fG3J92T2grmQCYMF2YJtxI5FMqy8RsTjJHtSx5RyU2LNeWBoAA5CUNksTT6Y7qWWNdy TG1JMTECBcGEOeAu4u0IY6HQ61jMZF/8lVeeVVsYsobQMJ4YBDYRB/7Af6YVscsgCw7bVTKN7Snn aWnkUkhLMIjlTh6VDT4bIt1XT1qOEMGe4G1Vu81A+DOMo4Q2knKiP4c+P9I2ZVbw5J+/AZiBfwut wlTfDySFx4XcVbKbfTFgLdbmOHl6/mVz2vPdnxjyr1ezE0c4k7Gg7Af2DwAAw0/5cOe4bwrraS+W Eef2zh74PrKYLlRLGck8eGMMhjkhAM1PjABasSfFxaMjYu3NufIOGL8AfkE/1HdFK90ImjveiMt7 eWGDK+A7+GwfHtonE5cCyO1yNG7JK7OhddsclMgBbXXbZscE8dKsPzD/ABMmByqTDAnm1sYPhuCQ YaAKnzLj+C38xPZHCZ8Ageaw6ys7WtbGE5v7+Afv0PgE/qkkNkCjg5loZJIE8khVNXr5wV9PaeLr lsaCm30/Mp+bahj4ZwDeHavnFvlGi3vNm+Dn7dqLz/6L9xgBxTnpYHlucpQ7GDu0Roag+0zLurC2 BcqY4J9qGENbh/DsaeQn2Mt/lDc2be6uwOb/ALAA9mDDFSsliNClpjMaZIFepJivhwNTITANgCTF jOTC5RS9fwuBzDExgDtQBffHhjJ/fFlG+km/2AB0rHF12/U2pzE/GNR9haX7rxodnzl7hXJJ/G+4 yRZoSmbVk6FcYxQ+/I93214JNDRlkLIgNDIBgblqDPQ9SDYwXNZ1P/DaIolX+Z2TmMiHDW+B78Pb UeYTGFBYxZBhKu/ER/YAH0E+AmZgN0IMh7NTTqS1WNVaSp2gq92Wx8PAYlXoYZgZLUDshiHYDJie q7FquBm2vxhzzZw+Aw590jaTeF9jsAZX0AwyO1g5xJdjh8B/DxZQsU2dfriW4Q+N/wD4ftyqHWfq 4ys+bbJjsH37z/TyZB180i0HhcU87Pk9DjVlHVT+0w7k4Qe05si/2TMVWtw2Dip7tLBh7ntYwZsj sc/7Bv8AiBAFuq0rKGQTSaYyDTO+M+DYFGCUbyxaxfbQ5N9QBjGsjDFI7WQ3ljJahk+Lxod3zl4F ckg8gr2+PVa5stkjDagPMjvYGdgjqYdocrCPC4Y9bqtwWw7gPZAe3z2pwt8YL4yMBm/yp9+QfP47 BpbGFDiqdYgaHwk52cNrd37qLceW4NAGJdwtQ2e1A62HsneDnD7axmMyyL/Y9kN/5f8AYOmohtBQ yL1ONtlrY2zqqVUnuhfBIg2GEMpYRQpiwvi2YrcOnkIXbRgQzkx5t/gePuEdggM/77A/Hz/SMvvI h0w7zVdicNODU2gVykn/ALeLF2zbiq+18ZLkAWjMxDseLPDHQNvqU8MUenusUXAG6pWHswr5+3q/ YMGCo2JQmQh0GLyBNM7XvSVGZZAlDcsYWtrt/wCJs+2SghY5FGULbfqeK3cvt5sDH8i7+K5+vAdH Y0uGLrrJbVVXr2pUjlTUPLB+LqbRKcCBgwyOEwxwM2Bq7574jI3kxm9nKu/ER/8AYAHswrQmOEDM SWjKTglnZttMjCOfElo/mijDKTWXeLIhoeLjYEyDAq/ir4jIz4rjGY5dgQ2DQT6D9Bw38+h6/bP8 J0AlLGMsjKuJ8ZskAbIHiGQXqCLfEDWBMQ9PbhMT2CHAQ+7U5bWWflDN9JSXZH2B+4Cffn/qYBsE lDJ3M0WDW7a7BXwHbNT51hXQ8VWLAiXIXt8NPfKruCkiEyDdVwKQMO9LPF1l5Oc2CHf7/iAwAH1y QOBnu71O71uynHcCcXHJFR4FFg2VGgvNirxikcvFk6MC6VlgLKEZd8ZzG4tiwBz0S2K2Mkrm0oMS Nh6bauPNGTVYds+U5SxYtbH2OHrdkquYQcad1Sp89HZFkZzy3/OGzgM+g4oPd0Bv58vRyLQUhzba ih1vOdzxJhPsj5U7Yn1fFl1ye5AYuwxfFWLY9bVdPC8h/MrPHngwZ9JCVW/vz8fQX4/v/S3pq6JC 46ZM/FJW7PDOFkfHJcGEwpVXywNczF4OyTA8z+lUOwLa+s7XaBMYj2jV3n/3/C3cepceUIWr3ClJ tGhCTRnG2FPrGvXhTZPr1o3Jdi/dgdDDwqrIh1XUsPgAzHaApzlmRncIkvJ/6CggAB/kCJ58MtKk br2RuZiOx88iBGfuxxOR49w46csGZMryI+JmpUN1tbV2eOGzBArjE+b47ZDRWc9srwNbXG2rKrdt Xw4F2kUNDKdvnLUYtsHzHC1A9Jjw9jXz/Iw1lGKcGWeEm7RePoJ/YEHzwFIVMttsCn7Gyhq2HTZj tL0zpNzNGppPTTok9LQyNqLaH8QP8zCfR6lVcMYsoe2DOEm/Ae+/v2OHTskWRQ+U8qgFsydR9Atq 5UzuYZQ94zIeFSldSot7ATLIpMutVuuzMNPOmBSCTGV4Fk9tRgfCMQIHYfoHH/UCWDSdXxbAZBd0 38pJ9jKtbie5HB15baLar0DpfcB9kMq2+GHBf2NSr+BXIfk1X9oGY4buxJOAEF+3/E+APn7DxlXV BtPgZJVl08xO4MbZXcRxtndMInkwxUMRkpJGJlkErD6oN/FJFqIo8cMVTIRnUkhI5ZkGRTLdYj2F TpmU+l2WYzmjT4+c2tWwm0TX+cyWREmi2helC8SENOfIa2n+DnWhAVWQm8vgsZ4T+gQG/wDnwAA+ NociYhtm12hMk1K23NUpZfQpg/Z5X2i2n20GTExcD5W/D2pSQG1VMcG7yrJN4SdPH7/wDYD/AFdn Uoj6G8ripnT6SoExmkpQkeYT0eWt8DU0NyqtgmB3Bw5IPZJyGQPYQ0bEWieyO7Wj78+Pr4A/7nuk jYleSIGXDaCafY9Vq5inKceKZT7f+Gfu6zU0VXC/WxlvTzLIwGNhXx6rzrDEWzPJz6S8AV8CAQT6 CAP4MaSOSobdNz7nSgKrwMu73c8ihR5vhWLQsWEeeFcSnOwaFqcVw8c+6+3xVmiFqBobk+Ozkev6 SthnxJxDmKruCwthiqZ5DcB4ZDpNPZDFgWo8T0/YwwwnTdoLPBwgTg4AB/v7f+raEK3h0OpodaT1 tuA5qeS4O32RH40Bitkp8hkJhiYYZJhBksYDqQ4P/VCuzI1Vm97qt+4Cf39BQT3U9W6mYsBsJLia Nrc9dLjGl1+hw7AXpkXFePORi4A75Scy1PZkxQyHbkPWe1lCYvmxtJ1GIIDnwDgIBB6ajxvDHcj5 bUDJ2G1TEa2JCTDsBscHNNXotczWAPyWtrgfMU85AXx5wP2z7ydzEcJsiPUXgD6Cfw6YdRlMkAXF IxkzAQrIZCU2nR4oY8Nu3yVlkzyFFKOVGGREaZmDvLMrLAV7HeT+R3GRJ8JQrzfPPSxyylmXJpva dNx4bGzqNVH+YHQ7gTy3ZtNd3xoMWhdlqLfwzNwcHbXDY7IF2YrvhNGBu3uc4ChIIDz+/hLK8V/o oQqgnzs6xzNTZNBXxX+TcxmnQ4qVqaOoaIQW2Wh9SFJy39l2D4FpreKOhXuTeTgQ5iDfj1RMGHAT 7Af05+n+p7HdKxbYlkKRKA4EuUAT1blmSMhpJ5NwcIcOyLI3hPY1UCwAK5W9zvgWs75dgQJsHviA AIOADrsIK6XLIEjMXOCckQ0lsV69+OWh2hTbZ3GcB6HDZKHcE6v6rncPfON+wt8swm8WjsgPtF// AH5IgiIZcNMULiQIunwxkaWCWRidw5Z7KKBQwonnx0Y1U8U8Uunk1IdYzEWfUZ4OIpIZQPSH9Od1 u/uB+Oq5ZOj9/sXI9DAwWeiVxP8ATmzh+ZWvqebuFwq5kxiU3MMo4TJqFyzU7MXV1ikGYID1x8zN z8gV6IsDLz5Q2GOl5+dWS9QQZYQBMIFEjTGeHLSz6a9ThlmqT1dphGRa+OHFJURRDlWKmiAcFwGL FZeaOgz61rs/nyJ04+TCsGByPYbtnR5ae+54Sb5OwBZtbNZn9/J+f31YecgH6mfwD7/9P1+j/wBT 1BWJmA+BzFd8GpOc2krIEkYbIjy3AUmqUWUyd4Lgh1uthl/4L4PA1zNZnkp7jEe7AgRHPgAGKDhf uwoOiz0DLPlC9LB0l+1CJJ8GwEIlqZ9Z4jCbXXRRwXzFKPgYQZHQrigv90I4fH2fcXfDFJq44fxx wPAWDj/TPT8xHzbgJJq5kkk+mxtkO7hwOyF4xV6YJrmxg7DakKq0O1YbBZBz8lnDBPgYtZWTlo7I jgeAgD/7AA419LLtFwEsp8yW3ULYIckp6ZpgGv2xwV4tsJsvh8OyE9PhJ7BT7wh2hPp1OrPT0UKL Kzwm0aTBW6f7RIO/8/fiVlSKVgsJchQ7TH3+axFcVzfJux+OgDNIyxNuND/y0XKvHlsl81xx+a8D rS6Q1splpK472otnly1H+stP/wAOnxKfcloO74+cfhh4adqDcNnR6WuD4C3WYxoF6hRm+YJIN+t2 oj9ur4DYD6rvBH1UUjD4u+JJsDYw2Swjr41FWBE5lFtjV+eT/mLdVzHAOQmVzAntvMCaMTaBlmA3 Z2Cfl3gID8RIKCVOmmCaj0nkqT4hyXykWokvWvQKGQs2GermvbFAmCEyHw8PuC3BfGCpUcz2ztBo ediNhN8AID8f4CAAdWWkEKzzUsDUDRQ+ocDAW71U2BP1IK7D8VydiguH8O7HDUJT8ywJirBvA9QO JNZKfo8b2EOVF+iCA/TpBkMVSsn1KJNtyCBs5IY+A0rpQ5jobyZDbLL3NlwcabtxB00ztCHUyt2S Tir0ufFPyMDidy2OK40a9mB1TtrRamUuc/W20OpU2Yz7UsiJMlPlZXdKZK/T9SEwwtmGFbsa2h4+ d4xXQybN7drgb8fAH/AY7/O2JSdiHrVre5K006sky6Rsa2dOx+jcivTH8PuAtXDr9Ph0OqzGKeyP F0j+D8mRnwpZiyEdgl2doj79/QO/n6+zHyZlWXNrpcre25soCEU2i6yRCIYxaCwr4ZCGhmFvga+4 NQ+v59VmHlmZ0J4ZkcIlGwmOwb97bAfszVDVfVMH6MJoFmXXUNXVugyTSekGcA8spTjBqUEkDZZ+ qpDmp/21Asn1rTx6hPqF75j6Ut3wYF/FAYMD2/mA2nUFS8+PzIYlcix7njhTLweWU18VZtlrJ6RE cbvWAQSnKioa9yaSsRVY15N3xW8hWCnwin3t4I07SdGYNleaL3adX9hBWi2dOMZ9DwG/Fve1sxAh 0ieAVkbLkuetBT0+l1SUlJfee4sIA/6l9eTOotgvDT7qLfK6u5vCFymnV2rHT/WWQkMMsXGEJpWq yCG4WmZh4APUb97LBsncvFoZSnt3SeDyCffsevsgevhkOsZS5yTlBIGw1fqjSbA/HKavOXG+eVuy GIb5YEydZdoWYjrYy38FcYsnMQl2HPAH9+P1FUXUkHU67KZucLstktGt80dJthfTyVsJMyKhpFI1 zSZAxDQ1vjQ8xPQ2DnK2zFOB4rOARJ4OfPv39fb/ANGNyU8+xHZGf/DQjo185WeLFUTZvjOEx9mA /Oce54qqthXg35sn9UW/qstDMinJmU75xtV5Ut1lHT8hPSE/YZabFMOENDmVXDW2Bb+evz/hjCdo adEZZ7XO1o7+AP8AgMfsCCW6LTxbQSn5VhSSWnhkZBMfJtSOWvipWheA20nj5i3DT0Iw4LbUQT58 4Nj4rjJw4ExBfr+IvAYuYXZCmazFXKA1iyab2glJiDzxgPLmPqbXqa5OLhMT+IMjgQhtSGv91Iaz teAwmcCb28AD6DsG/wCwdbUoxMAuBgoUyUmyBdm1KkV/qip9PsJbq9DdyiG4EJhiq2SHMXzHZWwF JqDsyzjijI29G3bz6DsD8/c+6HTyuIZVCPGkcm2qMLd68vCooSIeMXGPHx0UkcUrxK8kbPNt7Yg9 KOPMdyzyDMJIuKdmJok8/ietRDYANHtVvgST/MM6exumVfpO1PiQ9OZWIh10uEJtb3A+B09gD2NW n/pYicZq8nWaz7WgE/r4Afw3/f6OI9BqaRYFWT221DZ/TmebZbfkqtTNi20SndDlIZAOyfMh2QQD 1zA1ATzn9UNCNsbt2uBv2DB2i2DYOnxl3rCV47UGPIdb0yx167Ni/UkMgWW7HFqcopaloWohTDEw yvp9xdjz3w2ZGfFdmJ2pza66rQd/AAKiP7B1PGEyGertPilKrq6yExjCS6nqWYnlpiueuM9KMcws hkDh0/6PAcOVOCystGIxG3v9UHwD9wHA+AkxDKIw7wzPzAzrEtOoU5gSzxZYZiwD8gkjiyQKkhnX CesQ8auTG0bAZpIMTedAqftomjfG4WDR65p9kU0hqU2TKAv7EwUaBIezk0S65V8CKG+B2QzMHhoM 9Pno1PkybQr1msvHsE8/v/AT6+fP7ygd8KJYZtCvhK1FdPf17Gwg5D5hQ8pvltwx7K+WQY+vsldH iB6xoaN7PdZs3CbsN7+/cBAAAB/3FGQhYDRhnMaQeCKmahsksfNfE/uR8VIfP2eFZG8TCD5sI+ej uDyzC1cYTObJseL9+/gAGwMFPKFE2GBXCgdTD1pYTapL8xwX2xbTabd/ih+YUnjMhwyC3VZ4hAtR k3PBoeWY5gk72f8AoJ/f9gACUdGEjm8nRAKqsvJuz4rxQ+eeOg+oR+xGeLLyyP5qqvtH7r/U/nqN mAktIoPvdLuAk7uVYsi8QloavzCU+Vkrq6fxtDxfIfIOKz3CyzhhZGfWVh4OBN8AAO7p8B7HsRZs HlLGy08AemNoEWYNqhBww4kHAnkho42QmOFJ4p62R4qpL57EwTZmgoM3w3+wMCCf38BsHUOUQjHa M8BM16ScJUxSiGPhh5YeLFlnq5XPh2oHZHBwHuFjYsD4dp8YTFtG5o/5RBn0HgPn34AAnleQttEN PFi5jb3VD8eMVu4XRzw9hLjSpg8xitzFtbX+1d8WBPBuHGSm5vKOEN+2P37fz+HTSzRvbO6vG7LP JE1I9Y4FWq3+8UQMb+bAAnuw07IA7IjxozZSDI8iSWhuAUtemlGzXdwBTKyW56/k2rAWxoeVMtGv dO8NqIsLILtBesauU8e4Miehh0MfDg4p7bXLgjk1coM2O0f+qBiv/wBgYRTMquUYyaHsYYt1vdzU NYZBgkn8wQ00Tw1PIMlbmIcLmBhVgWi2g2QYzFBZNG3urrsBnkE+AAfv3Um6ZmYLsB8Q3evUmt3K Z4eYSDr1VuQHfgLIPhhmSn94X8a5nsKGj2QjDGj/AFxd7R9wB9+fkLnwAB05rYr/AGaqrU2Gt1K7 Kf20TQ6rMsiWnoZ4SBlGF9DDmJhiGvmK5odwrQ4HWbxF1cMZgbs7JOwH9/8AP7B0BkzpN3z3K7Ll IJFxwd3JGeFtS0oskX0alYAXC3VWLq+QPNH/AF8eSeqc6qA7hYwxxlD0NlJVe1Rqcjuw2PXrIh4b +BMD0/ups5hPcDmni0PD/aKHKMxwHik/fsd/PYbAfc1Xg49lq9Mrgagaul5STTl3D9NNkaf1Nkcn JstCUXr7gYeyFtkTw9qdj4EGt2YZ+M0Z4NJJt4Ac+4+A5+f6WItXj1yDs6AGZLkGvjIgO8fJDuBb htSu7RXMMeyTFtwW0PjYMDwNqhjHpX5ysvAQ2beMAHgN/wCfY3GtSYYA1XTN+03qWJUnqMcObj3C sq3xQxfExdjLbAhuHG4dkMAcGpMH84zcXxebM+7Xac+g+fxwPgHyahVVVEZSWZJEi1Bekb+PMv2+ njkuIybLJuVK8rGnzP1AkRnR45G0ynKeN0BEbFLF3bgDj5/V1X1GWIyc0zlyfQ9bvb41O3ehwzh1 hXALcrCq9pW6/tRP0xuFV1WQD9tLQ+CYJorOUWd8N4c4AH/bu5gA388rPWJrN1hp9J6cwNeqVP1B UqlfE/Jr0x2fQ+PJtjchW09kW7ItRgmQXxwodH5ysob5wYI7G3bfz78APn/P9KRQXrnDuatqG0rV iSrFn0pP1ULwFjIL34bSGix4bAHmocOt7I+FBxHvjUYGPO6f7J/r4/5/790txEgPGtcRaF51XKTq gZDeMiwtNQZ3fERXtcDFcOebyHhiG9lgHoFl2MHs1ZaODrB3A2lb/iB9/Pn+q2kZgAs5dEjdX/l2 Z2NEUcbMVfkB7HC482jTGQRgRhJXeSymykqNhg0b2+5VNlwoQkcnKhcdxZFe7mSzrVsYlbVzVfcz svV8huGmeWybpYVyVft8wOHmrcNwmvGJADVYcmzK5QYz/wBbA/3/ANz4DquzReGqTJmJK4m2cEaq +mamu+DTs4lPFvlOXIhmF8P8P8kMCfv1wQDk0Y8i8Bgw5shs5+h/+wdMFbXqv3DJsYynuz4uB7+l /wCDDV2GZXNOCdNB6b3UWw9buAfeOWjkNVh1n2v+zb2E9+0X+Z/rjESQaRfDVaukHUhhkz+W3Ivh z1fqaeCsaJXKaHX5i3MuAQHT1o4pL56uXAmMF2hii7I7cH+wAN/Ac+6SI5os/T+o2BHNpoZmx08O xFHGiq1Ns+CzHF87ApcLY3f+JxMYtyFo9RPHJuySSdnqynFLsklU+3u7jfWA1dfFnGrUFfBipba7 Ym7CH2PRuoC7nBD7sJr5ZA58MfMmMpB7gz2ADY1wMzyUKo3B/wAXI58AfQWA/wCfQYGwEPLSNPdP wJdkEg4FkJWE0JLIHX1q5Pviu4EPwmYZDDAYtTs9Wk6Y8o1oWgT9gmKSdQfvx8B0eUXV96Ma3DSa 0oF/ZGNJN07HrHOkWFMVzynv0xxT5geGYY7RDg9uAz3AYzU20cmB727HOA7+APn+QPyfqtDKVVH1 OJrdk21WCQqv8tX1IJ8d3h8NLW0r2QwLYdwe4cxxZLGA1/sZhnZSgtaKHHYJzh/fvP7AAP8ARGF3 ErI9YzTWK87kLRjnIcjcJHBuq4uxQmjVRGylkkhWKOZhFGg2pYZWZzFEuN4KoBz8khhiVL+78Ibv YFkapU3THV1kJE0ZdxBVVpF3TFdXh4HnBgtSt4a2ycfw4k37GhkyaGhsxP8AZDj8/AAHAV8AggBW n7QuS1cxVzbVs5tcANbjXdPqtkYG1bigdhira+4VXMT7UZLBfOedpTm2PLQhjFk46pKScAH/AGAb Afx63Mg9PqCl7OMu9hSaf5UpQ63rE9IXlsWmlvih6fmB4Yean/Dg0s4AQd8DWb+KBmWXkJdiS8b+ vv3/AE62xmySLr8Or3Sn3HW7QAuSsgwG/iC9sKGkcyqtgmQ3CyA+I9beP2MPzkXaH0c27VccPnwA Dfz/AJ+2eLFmUJLg5QhlHFFOQbNZWbFfA5vwMZlVXiCw6YjG5GNSTAkdpahuSA3tpxeTix1JVAKj 6lqQPJEW5tJh6BDf6dpCHWLgkrcrU+7IlyXAPuBkL1xT5iAhKoK8QTxiz4oVoE8AnpdqTA+7AAQM V/A/isswPQdy0nkwEivbIG0/C1aJDxnDR8sOhymx8Q0/h8yG4MnHjJwCwXxXJjgqHpyWdQuyBHaq 34/v4BAPoOwM2TmK+LAH+eh6eLaQ0M5bA+t5lbyrsTbQs09KD2AYp+1FuGH/AJ5t+eCcBiNV9NrL N924OAP7+g/fwHX0xV9brF4AYqRkqUPNJDUiwCUNplmJQFhlC7s5gt8kidn3CnYFwT/mExhRX8Gb 8H9BPnz/ALoOORg8cpZDNDjMJoyoxj5rJUf+r4AY4qEscHLjSJKAOWOUO17Ih4x7riiiur8Nl4sE c2jbchWzPZ7mA1UnoDJpufLaU+B1LaNZMiETLC9PtqfD3gwGDfMOIZDfU8ms3ILGIyOECdq9gfsO fAEHqy0e+flXBYUqwKxGodX2QyS3DJ09o9sGK5F1khy1tgDmKrW3yHV62cfKvPWNW6M8+ywio5vm 3PtgAP5/36ZDZX+ZYy3fGuvKz2RcXA7Ip1/c1/cemRbGrKxmgxyRkuCt63Q2BwOT1/BHuCoBnF3p ZOG/B4P+HPj+/gAClCMiG0WJMgFGp/vJSrF/dyHAzAlDld7qbAoe8YGIcwOPMToC++HGQZ7oe2f1 sE4CffsQD9v/AFdBjKsLbTumASMbTm/mVLaqrt5N23IA6GPdj+nzXcSGaMtNKdyBcv8ADMw3DeJy zaQ2Bjjze5f5JkZBKFOhhSBOOcMTi2FZURZdjV+PKNU3Md5oxSMIxlOyIQiJnM/qw9A1kBDWvOke uQdKBVKObgJKznQIQtGsq7aHtXXrGvWlErF5ZWpDrkFptJN4MCq2LOxsaPkATXpvsTIzFz0k2wpl K+RN9EvPyFnJEYZWfGg+qGJG502lPkWfk8cn8+Ok7jDgcAcAWTQ/1sf+Oq0HHyZfD6ku6GtxaTQ+ 6IlfJXlyFwpGpd0iTCAeq63hh1uwO4wFfpZqcFkYrtAyzDiTzYGg/wBAoOwdW09fdRXMQ2iKY0uP ltaY41ZV+Ntqv2GGmlGFyira+yIa2GDp9gTAfnsK3ZllpfKg/vgI+BfvPgD5/oPh5jhaCGSDNuTU teoY1bE1uhzF+snByq8TEF4kFrAxDD2RvCqeHeYWCau0IyMDCJPOPP7AAAdcZhOeBbQn5rkq1vai 4NUl6n+1afEcEOK7s74t9k3AOHZOPhzk8g+TeM9+FcZsdXOrtv8AwHwHTJysm4ZAkvoy7kB3dx4J MMdvamisylDnkDhgtXkaKKQwXw66hJpJBIg0zQLIBqdNIDpdTpNT/eF7JBqUmjuyrRGlZVvHj5Vg 5i3pplV4/h59zLdsXRW7s72En02UYbulTB9b6kNPYcOGq/2UrAbdnrMYUFsxPwloo+//AOT8f6PJ 9qL+TImNFtDbRZLfyZPyOYPBaYKTUh8AzHBDQ63vgPMxDwVJggI8Pym2Mxw3ibR0HsGAQUEAePn3 xYGZS93Xo60hmuNS1u7zNTNmo9e1vX66HfLa09nq5mJ/JA/w4ZCZ34cLa+YzUarlBhNH+78BPgD5 8+AQQADjkWQ6QKzuAe+VjaNhSiSTYRiZW4/gZQWWfFfh6GyIThjZBAw1VLjWnG9r7NrJN4N1cbCW 6Aw2B+Pn37pYCtGoCPvZqlsuG1nQqrbdR8e9PTsqvd0To2RLOiIyM7RRvNLH2YUY1llbYkGfa65e eVPFG6PWeoC1XhJUharGW+3oN4q+vXxos2Grvks9Kqv5jgyIb5W7B7gbQREen3mzKbq95GVW7BAm /oL9v/sffuqrUWnyEggGXLaW+6laGJLZtwcfLcCl3CU18h1eHMLftDHp87kCHanBkYWUJvPCTbv9 BfgB8/8AriyFOh67Pj2+K0Hqchob4tlmDTq1EKcMHgIlyAhx5iZT8MPMT1uxlKrm2q4ZPug0PPOE mrsAYB+PnwGCDsHUOLZLwQ2TOn6aQ5LJY6rf94h20ru8Kxk1TilJi/MW4eAdbtBbB4r885Mo0W0V fZm+BAex8/AAH7YT4Dq0XPcEOy+4U22haUOcbunklnwFMvgc85eBVPatG2Miwx5KyyNFJEjnDNWW KCDPGhRYi77QCTYrIaAeU0ZMqyw9tWdb+SN28lvDu4yosuLKp8hai2yMjJw+ZB++Kq3cCN2bZiYN 3NpJzHgB/wDEfnzZbH5dfB09klVjGAhskaXDGLCYBLIeQ6yPRQ+8cwhzMGBwgz0/BVmjbMxfBjN5 tJB/19/t8+H6n19fukO7O7Gqya9PEtpcEO5pCOYPW0vOTRDYeSJ8xkQx8wH9tamQmzFENlrMGku1 XcBPgNgPn2DYDVGhWfKcKlPAXx2L2DlG1QAHyZ/AicphjaX09wxrirFu1GRgMfAYIOIcoUrBXt8m DNu2OLBUW/sABgAbAaurQxiCN48ssBKMHhrC805vO7HcKxvm+AK4yM7ncwxrGDdQ5VeD7i+Pnt/H XJaDQUFujhRkqq2S1E2vUCnLYT2qMJW3LUYkbpuD58wwyQ18wjntN56Djtiuh4kzn0nABi/AOfeA QtNd4L6kyVi5W0kySUUxJiVe7Eg9hQ0I9wOLMvD6eyOAev2ScBIYA1sZumFmDAn+lZ/gP7/ieAFT WvtGbDPVUkOrvnDyRJ3/AMaG4WFMfFdIcvhj5iEHT6rMD3AHA4kq2TZnsr+c3ukzmwfv+wYvyrre 1HwADyQwsaEs5ImLcveLUR3dkcorY+NEMfDM3Ah4LbgHOTyAJVMcG4uTJfSfPoOIE+/b+f6kZKhU BxdETdXz4Jaef/75GZylcZ45H3EWVciwV9lv4g64VVZ/LWfaD4oUOb4Ox9bq9q1PVenO6clAGik9 tXmAlbauvb80MKa+Q94rd85gHTpk5TQK0BcZZtrGLIMJaLtv+wHwPuwIKCLTGRPnq56AZJDHbKJK TCr0y1I93GJQASLF2o4GO6lJh+QBwdLOD4D4yTFq254/dge//wBQHz4EBx2g2dguSXTRmrpJya0V Qleq8Ozh6RMGShIFomL5hwZafQ5g/wA8wITvue6C/Y54QHv4ABv4A/07LMh0PXw/4DRqo08TLafU CJaLIByJYdNsZTF2hgQmBw9kbxaENHbWBSgp6wzbosoqO7BcN/7ugOPvwHpK6mNGhR5Uz1r6iXTq 8WRlk3RLPgpdJIY03ogiSR8ckMwLBXfTA7srB0TTJDHKUatqMZbKng5cCQg9vj99D7ws1cV0e1nf 6lkZD5qNX7zkZLjXBl0jK1iRMKoxJt+EJNrqGuhxxH1HtjGrQ0j6R2Pqs40d9GIM96MM02weoXcB gOkYdM2WZcFE8Luxbr1Xpmvaf1CGavilq51BTCDKhzLssgPR5jltwVK1B8EYor/o7hNiAPwA/wDX z+wKfUownbBt4FrfO6hBkw9njofqEY8clAS262KxgUIMyQoiGOtSG9rwL/mR/wDmZiS1h6fUFNr2 KHgwYrx0/hb1w031IuSElNrpqf6rfIY2ZdF/ZOsivYYGpYlntAdfmXu4p7ItjoSrWdoKbutrAzF8 Gc5CGucgAB/E+AQfcAyBZI29SeaZJZp5ADHuSBJJd1InkzXLbMhUNiMrJxXpbtHNJNKUhiWLaikC kh5HjjjiaVErvzEYLLkNu6yfKweq/D7LUyWw2cyNTGq1cvVv8xwr1baIrDY/JPmLe8dkx9qQf4sP 4jHzBZFtDw8nObOzyg8f93722CsZSq74Rw6Gk1zVa2ebc6NL/wAFkR0hD+VEsauQ49PWzDIYDj6r g8gAtTITGNH1lH5sb58AQQD9bvn8Y28Ecdcld17aGaBN1iTW7As2pySfU68IAyq9KFHBfvhPT3Bb mD63BTyB6cybmrtCz5urgmwP2HgH4AAAWKSx+oS8ymdXObnb9FshbLDzyTfCnZEqm14CruDhfDh3 4MOBDlSGQA2pDZvF8mR3Z3Sfv2P7Af6GLEIqK6epkriRtuSKSGV43Ro6a/aCDkPcRXbZkuW9uPFM ryJHJxHUbRuexkjyqO6axbXS/jlVh5At3OJNlqS3xszxJ3IOyTyExKtuXYxT8J1u+Id8TMFuehp6 HeC2ss1X03uf3bz/AP1fvcABrdF2RcEg+Lys42BzbIuOvQ6HcweXDqWuWE8eT2BPMVXZDIYIcV7g cqTyaz2v+j2ib+gv37+A4D01MzTnDXKbY5V0nuK21YRthq+2qNreLMFxSz4rw2CZW9kOEyHYENHP fAhLazjV+2LLwECJLxv/AN+PoOwdJ9taNUDG8WplRc6rSQG1BlOZ+TTKO2YuSbqaF6jFsfpvT2RP D3wPMA60uF8VU/bLkfWZZB3YkhDmwAD6CwHwAA+cSojGPchlmGmZJISYpETZC7rOXljilwDoRtSP 7jlha5grZNDupKqI4jB07dkcbY7aiPHjHFrJbvvwtcyQqrNQFdI4eeFziIdIs0LZsdcvLPiB4qvZ h/FOf1x8DTUOyGFwOfltpxJLT4rec97rqxAYAFugAD9sGMllg1+UUocM72FRVelLItp3rYxbVLu9 byjynbVX8gY8GRkT1vGacn1/ypwJsyx3fRnfD6Og7Af8+gdPfU+O9CtbZcVBrJ3pWNTDGpcr0+LD uGvhE0+AUIOOtQPiiGG8/LVJ+LBYz4z4q9XrCxhhg7pHAMMDy+f4+ATUhTW3G2APtknEmgrCQHdo ZLOYF4OUixHLjfzFsuyGGRfmHFLibVxndBlmE3j/AFUAIP8AQP2BguNp3jcNH9O8qSJHJlu45xvE x22VY3rcDVIjeKGNk9Nk2A6iJ91BjuKVxvGWGVecmr+Jh4PuJ+KIohw7FqV4aoDmeJXNpLh207mK rqu2C3A64tg8BhuDJMT3yGydyIFaEHw4hLL1V6GzbFve9gAADYOfdb7ImHa5zM7NtDO+ZAmcTvgl Z1btkOLtDR8wfD4eY5hxsHB4HOfCbyLtAZ7b2bOn0E/5/HE/0wo7I6Zws9Xxm4H/AOek2ku2A+Dr JiLb4mrzRKTyIdkcIcOYnuE5SuADOh8ZF4o2+cKq79g3/wA/0pZGOUGtyG+McyNui2bU2BbziCR3 GTe428EWRDQ7IDQx/nqPIQec/aFnE4ESLRR6ifgG/wDnwHQkqJZpMacQx54vLtttA1hC8jxQ3uG9 pVyoZ5YriUHqGOIdqPMcR7sN3AH8ZViPxZvx02ocx5Frd2IbbXoQlXyTaKQ8OyePh3BxeJz1DT+B snzJY8wqwGE9BME0ah7k/rbulhsB8Af9uP8AS95BCcjjIpUiBk5OUkuy9V57JqBhLi2hITYvME8w YhOCJw8G2j3ydM/a2Zm+7bJsGKCfPv3gJJHOajG23LJdzNnSZkXV0S3BwD1vdyfYwtsxaLs2dPrd 8hp6fNeKWYENqcNzq9Xedj7pBEc+g7+A4DwLrTMdJrat9qotPNuF3EtSDDX+cSX7YtVNu6skPnlf 4h9MbJSZn4e/YNtqGLMeavfO5jwb7pI5/oUfKJ9xt2Y4mMQTVo5o7xzEeBBqRZY6LEdl33UsZanj bJ4Mr9cx1JDQj7lOfEZupX+3s7WviHaF+2KH1AV6xmRuJ5pDjVPcnaOJfE0BLu5NZF987qWpW918 bsbvBPVQ6MTaFcYLB8JdufW79+2ABj0n4Zy3CjJnGaqMVuYPTJMsPZAFH4eUtphi/D424THCYHHz J1lr6i1B+c90ODPBvhJw+/b/AFFv/IAF6pAezNOdsDLubZi3p7q98ktqO7ZweIttDQvSleq2Bw7V zKrMD/gz9SGANQWUZoaBn+9jiCAfj59+ftg6SbJmUWpL9VocVVjW1qgmXGJsi2s6RcYepa51CaX3 wPaExPhoZd8YA7x3QPYLayMV9zGHNjdkd+AfoAftgt0NJJBMjajTSzTQvgoeGTP1IzjMjDEVtyBo wwJzxLUtY9TUrPG0MMsCZruhg0PrsXl31Y9/ru0cqNI9x1kvab6FbEF0m22pT6lQ9ekhtlnkCspA 2vU+VgUaBJQpVae+sjhSaHD558BAbZ1kExituayc7o1dgf4Cvn/Y/v6rkZcNDQxuU0TH/HKyUBeq ca1EHcO0OSnUvJE9xiUmYmMpCYqga/RPJk6v4MjA7RSTbx/X4Dz9RAHYU2OquzNZprtvzuHdqnsD WAtmEgxXNoUg0HqrHh7Ip4xcHIIdjceAznwmMF1esjDjtzYHi/eAqMBsHUbI+PbS+BpKBMCXAuNS lMtAbDr9HmafZRYXV6e4LbIGmskIgyHANgNoMPWbPclX8mBpNXBPvwAAf58f61bnpwRu288WeEzC pBnt5Z8nP2rj7caPm+EqOdThwHdFMX/M27o52MazPGJ8+b56nhdqPjHUde1KnVXpL066oA5u+bYP Xwr3GnnrGmaQFdkcDDhW7JMhkIeLbqArOd953QYzc2CJNV4n0EBsB8/7KW0LYsS+XAOUzVsbZ2bD W4iuSs7TvU8yLKXkIX/JzGQwn9r6eakMhAOYrNvtDSzI1VpPa44AAH37/wA+cEeu5FLWxZ0WUeJc jyJNe2DeVPtAlku6KplKHtQeydh2QN8AxB2+BB4N+ZOTfdqTOfv/AGiAP+HRHT90U/3s1QwFca/q upskt1lT4ft/YTJKV2zSq0GR0O0w4eG4J63ObV98eDHiyjMipBukwfn363d/AffkSYaYTSNvOgeF I1j/AJFzyLBpebjWhsx4DbJfubLg4y+pIjiiUOEllmcjNBHFGZC0cXbt1gQwzYMGU2MKeC1AVHej Rp7AUvb8Mk4bMNEWBDd6vE4/FYUOrzDiYmUOYDh7AZK5rSwICraizxe0FoY8d7eDoPPrd8Af391w G3U3gdvioH3PWrTKaIwunAvad2WDXy1p8PJKxbS0nsweWXp+aoN/bUht729Vo+PmHdQ3aKQbt7Hg OO/efpRV9D1PY0NkrmKh6kKrq88SSK/3IfYVcRQNm7CtpxiF4dPr9bBcwP2NM/F5Xa3g3/QPn8D5 8A/gLOB6juOBRdcakQucSZfmKdhBhx7uaYpHUZcVNgXBeqyZMMMkxwtRHuhgntJkYMwF2YzAjYW7 MV9/AANgQffpbRKZQpeFJotVJKjSLqpYxHrsFGEk7CJpBFDKkscDvt7iNIwGCto3nkjLR7xSaHTa eZIvpVAfRxLGHP0mMYgSQpqDNtR4QxzNg+B6p8ZaA+oYqRfVX/h/N18BcidNXYbjXxXOqRLDRxkv OkQq7W1A2p3QQyxFcDZ8JOgkfQ+TQ02MJyuLDg6nlAx2RnTcyCeqt3Fg8yuKyqnNTlUPERwcZMVd U3E4MBZxzYkL0rk9ZbQK6WDFIXrjMQ6WEBBRkOKaywcQXCyxGGT6c66BfVMbWLJSbU5AWDjRrE1f HH7P5HXElYLLIsg0m4sjq+WkDNmrYtbb4s3dmhfcaHFbbYZAbkLMWNPQ6lcLGzqBqe+KTAo7u4K8 VsZ4r44WnZBhlcIbhMau6Fl1X9ZwfCbMDSdUTtVeCCeAH7dxQetxCn148HmARdpkqZ1BQ1uwsEms DHvqMPMMpnWx5gwxw3DmGAQ84IhtwWVlWtDAm8BLR/7AfYKiAP3VnFZskSqnMZVfDKuuDudpveCH +CYLOFcuTBSNc3Ynww/JNnq8PBAELaarUWXkoUvIZgb2T78ffgB8/wAgwQ+MyqzzIBV1dDjZLc7P +I9P4OWDlHy2N04fMWw62t7gH+BpvvjEztjQURucc2/QBz7/AHB1h0k27Gjp27XokFonywAIa4pX xu/B8fBbnHsarT7TMFVzDI7PEVMsQF4ZD1YVzq15HjmxyOq92AvuikL0xtoYaEybkqWNfK/atwVu JfENod7GTofezF87qQx5gH3AQ2oPyYoLGE+bf5/XwAA+APnyS3LIZJRAOLfNPZvT2+Xxx60JlkWB LZJSuWptyWyHA7thh09xcO9K/AnWQsMuozuZZtqXZ/Xx8+f8Af6xkMTKqONVagSbIt7CS+OYmJ9h MhR8EOVc4sFbraGYmMjAH+AQgQcO2ZTdCRw3vYM/z4+fAbBsFqF/LqSfD2GVqcJWdFJSWG+CQG8E jADYy85Sg/GzCfMMMhCZ+L8Hhk8oU5Mcq427YgNg38/7bBrYyx6qA9wSOGSAs+7LhH6e2AiQyRkr 32JUN2MMe68ymNIZHjjh733HuLFBI9ZM75HHKhiMT4PSZQnmO0Q69XBdM1KnpoEIJR7IyrYvnmSH LlAZg+Gn2QhvlkMCGcUh6kq3Yzdr7kZlo4E84goJ9+t3YAGwGpQxlu9uPi5PGkk+VMW2wwquxhIf ClSsIs8yMBhDrek2Snx4eah8SR4ZPgb5xk54TfwGwbB5/qT4utHk/JbWMwgWE7n41e1+4WF292vk IFNW2CGY09uH18PBPME8Hhp6ZuBrP73i87+/ff8ApSrcxCXEMwuT9yASoaQJT2Q8HXlw8h90Dz4v zORzIfH4bVAsA8D2xZ/GZOq//IPv3H/P4yyRyMIhgnaBHBEFjQg81GsgjS7HsRMvuugV1rI9BZBk 7I6GVjcj5GM27sDI+NcCSRqJOONtkeIeZYDHW54g+reDVV8xkU6fJXAvy4dIgacPAZifDZLgh1un r4dHx03oc4wsszRaCz5sJ7YbB4B+6kmysng88E/+HhQ9wU5ZzQHbRIdJhtMQwUoewhYDTfYFwTLI MMktgho8Bf007PwZoV/7JaP5dQUHf8eAgAmO0EHJwdnx8fHdVtAkyWEHSXztlz2pVNXihwC3vAdk D/MrkCwNtcrQxZ4GTrMHV3CarAIOPHz4ABsAGHru2Fev7apZDdn9VSLOqWIn0PM1EFltyOr0UWYH 1uHsik2QPaAfgZCfOD9jWi0NsBhMMcNgPgAC/v8Ah1qni2I4XEaZ1G0emdc9uSSgpMtj1IMS80eA xiDyZHbxbNE6s7BjeUIlE3JMn+XD4xv3ZNeVUKrq0QiOYn2QeXNhdjD5pdtGvU48Nj2En21dzxfE pPIbOZZLUhuEyceTz1qJ6yTaKvqDfDYRKOAD5/8AoE/j0mVdsT4zJYRRcyWTCtDwSvXBqhyJcKUL iSmgOoTLIDp5iYvrUH6G8bmMKNFZk98N1d9+P7+A58fAGDBVYPTSl1UuXxMNnmRJf4lXkr+q+wkI CrLzRV63aHeAPW6e+OCccA2h85bZifF3nY+bXZz7YPdC4Cf6kcuyO0tuZItcUHb5WcNbI4cOrsNP uUosmi7gXzBhwW2VDHzFXcHw4n0b4uoGZ582Dx/oH+/qjhY59zyKmFLp2uqvYLmuNn1MeDnmfbjz RbcpHVHy7ULrkdw1ii8ityjZ5rHgE9QWa6A4tZ51IpC2pGLBz4zuHApFgFob4mu55XtRwtSt2Sk3 wxX/AIBgn1zgzLKHqMWRhzzaOggN/Ab/AL/0EpbRSdc0GYsEo+US4ZphblkNOqTaCRZG/CHJDcHG HD+HfAer+K2WwUt8wneZRD8HvZvtHsFu+AP7+1DDALpvMpmLzy2rOsamba7PodV8hT8a5K1zaHcD upDZPx+HsbFOgcb3MWLJ7HshwHyAB/X3gFLHt2v0jT+SqV3Drct8VYzDIs488MIcoBYSj44WA4If 4rZPhvFaWApVWh1msi3zbNkdsMT6Dv5/nwDrRGz2dwuiDUxuXR8aDhqBXHuPbxyOifnEDl9nYiX8 xqVxGX+Tn45LE9oHQHMj6kKqqv5WbDQM8yyah0jvMS8MBqX+HSUnp9PrfdQO4L7IjoZ/uoyE3nnh NmeXbZHjn4BB4Dh1aKY6Mi5NZD3JFJkY3AbYSPqEMNFesgBN+XYwciyIdqVWh7gHnASECDW6M81f cnGQbsb33339BAe5/pevi2wLrhMDMd5qVnC6frcsr5z7Hdy9oCmEDF28wtobInzR4fnlf8VmE8EM XZntaPCfoO/7AhYn+rWkhFEKJNO01T7q04oraYp11f8AJzX6py1yPpVnfRI4NjpZZe1vq9Lxx1eg TVqzqdfGZa31JB+lgwOoDF6gB70455GilaMOyQJKgdhpXpyTVLuV2Y2SDi12eBXLIYnHfCvrI+2Z b5d1i06RqE+NwRufccfHd5688pFbvFgyBsU8NNl7BDkpZBks5XxDlCjDFFzPhp8x8Q5g9ctRSYJ4 OEzfff3v38B+gDYNgfC+jQz1b5zIr5PG1d2CKZA8eX7YZLupGX8WyO2ye4WQYMD5kBScYAP6yUGE yfNgiT5894Dfz/SlHvke1QeUUrmZZBhIW1tIaCRjj33KhnyVMsCHadVmGTh/wXxf/nFhGV0NZJ9r sXc5v/4j2DYEF8V2vzLHS7gbXKZGZA1etteyNXTvS5YOAtBUi20YXzFDviehp4/5z4QfOBsyy0U3 +9728Pz8/AH7wHTZFxs37yPSngt5scWW5d0fxSbb+w3Vdt2M8MzDEqMtzztT1jiQe47Zu748VR8/ A44L48NMAlGiwpDIhpDs2K7tnL/zK5PFgNc8vDzMZi3DX7gB1KOfDnB1lDfKzKcJSQhxB2A/9+fu oxgrewVLMJ1emrYwxk3MNSJFtAVdImi0O40OLuHA3xkcLUX+VcefOYDLM4GMWarSQgSqwDAAQfoI Dpy6pZAtjqutwNczBx7BbpwSPmZ3b1wjHWxDsZw+YyGHu1Ia+YeABCfBZOc1eLZhhxJq7YwGwf8A Woj6m0/5ZieUtq1ClVyVVt06qImQBJGGwMhnogu0A7gHoZw3ityExqPWhdM7k15K+2IxxJNuwM+A AAEFAfvfrPNOzQK4R5sskQIZVwrHZhO3LHeVv3tftNJ8F0KpuMmSR+1WLty8bVmgFfNAk2aIujdd DZys0NNzM5cAocbNngfMW04ODCYu4pMuRDZCG8Pn1vEw1AV8D8zc+UEvN/ePPf5P3IDA4cD4NhKK ZmKL4uDRrCrjUOyCxgWsMKHKDp6HDZKTMQsA4Oy/gKvBhgsoT2Pe6uBnwB/+n37phR49qttD0CGq BkoqHZa3GbNP4GjY4lPaLasIDYwdwmWpyQPyDY7LX/dP5NV74zDEfZN8+g7/AOfwPqQfmpykhy7o WLgHAMqmkikrZzpph2UKlu1de3KGnYVxMqCJ+9tkCBBqwnWYsmNetl9SQcYEHABjvwE/1od42UCQ vUm9EIlfDPExWxcqwGNihifJ56FWOeCsnZsTWkQjuw9KRk1+3hr4/H5f6upyJ9gTNPrHXo2Grvhq vUckYviJMA0kJ4bDI+y3MtNbsBwVYCe2gw7NxdoWazOcJNo4D28A+n9gqvdGZXdyOFtZtaTGShw1 tKUOOTr2v20wLFyyibMH2Qt1u+GJjB8Gy/gNUzkyELZkbuibCG/xF1YoWh6IItRzDzvalf5+rQlf +nyhlAbS8X+IvS/hugZPZO9reySyDh/Et8CDDZWa5GhZZ8OE2hwIAfqIAfwXzx9P2BU8fNyyR5WM 2QSnzKK7gMmS0CQ9XuVZFKlRHAwn91FsOQ4q+VepVXxm3/syy8ah/wDqAPn/AO/1E6Fy0JfHONoW dMMcLDFBk2aPkMJLX2kY/gZI14V1Qvg6NNFJchzCcq2HpgY8juzJ5rEW5g7RbivR9YoZ6wrRzk6p G2IQQxpASn2MerIDF28xDtRbZOPuFqPlfb44M21q7NZlqcJdvcBwHtCA38BV1xT7EMsmSm5tkMjt lDYy9V9b2Q4MNkNDl2vKPnchDmGOeDpmCIvoZwOT/wB873vhzf8AYEEBsC/0wijAUocWZXZ4Bbhr bsEr2v3yt5Esw+AWFo+GwMaHcExkQyCGDfU+fOcCdmIauTGbIbSAaCBfqEwPgOegLFVXYGZQVbh9 UsowSPZo1Ss2v4bsHlh/5vUDbSePmQ+H8bIOAM9XzajiFlZVyjMzeENvHPgHAQCCfw6QZjQMkTd7 okmYx3S3tYcGsO7jm8hRFDp2ywYqs5Wu1mjekSQe8O39OWOxsyU3LSdvHVM3BgshttAw+NEMaeaB ra2ELOVbQlsktNYHJo4+t1u9uEOq9nNqXwDYcYzbWMWQaT+m/n9g/YOo14rpLcjA356rXFbmT0nu xnGCMvnh6zXKKYT/AKeh6kMWCt0aA4Ad4WWZX7mEwZvZAXPvbf373PuDVo6A1KxE8zVWdq9PBrCU kgzpv1OvC8tpp7mSG4p8O1FuYYWyENIn1/PrjBGwQ33H8o+c2B+59gAQX5BWIMgV08OB+UUGjVrh MlhjzKfMNheLVyRaDQt2hDQ3xPW4ZAxzyBUsFw2ztezE9ktFJeOfAMEHwGwakAECJAm3CbISGCXf kkJUTO0MqxZwTRFo1VZDnkzErgA6mSZZi8w3nimEJb2FyaKNXfjjIkcmNm8KyF5B2V3XdN1VYlwX TFfGPJvM83THm1GV4EuF8VKJFoYcfwNkmTDDAYxbcLa3d5GK9yLTMcwSAm/0GfAc+fkJ+6TMyzHz NpdkMgclAre2tOpsTIsIC4JCHUp6wnxomV/MT2TGyJt4Pm/YobXyZFxKVmso4QJV2KDv78APv3Vj wWnDVHRFZ46lq9BKKtVWqZTvlWXM6pqnreubQuKiGlawfWQvaqGXsBw7Z1AeVKsWGgozrLM8HEkF j6f0w5DgAYKvSOcUO4WFX1g8bT1w8/qYC04dkWEhyiktNcjC/wBh+5DHW7BaiO908pI7Kzk7kuRG GA97SQfH78AH/YB0lFDRnHCeGKoGWMxRxnSRcSBUihXbxkLpy0mWIYYWVIsZmKK2cM3NZIOZ3xuh Yvdx5H2FB7r4sUpoepAWDGu75bVXNQtpUrNtAbwdIW2ixpYur8V8P3U2dDr9k98J7wyWbWb4UJkz gTE3/wDuDf8AqSgUeQtq5E+vq5uCyBuaeoqXfBL7DwMA7q7kH5gyJweZMIB1We4wAbJ71erk+DhP 7/bu/gAD8AAQMys4eVbGzQBqAHbYdWqY/THbQaIyK8WwpQsPxsxCreGHsBbB3Sn3wcmdjWi5FlZR wlo7H3dYOAoNunz/AE7GSPXbbYFkHoqStja+cBrvfAYNUCm4FEPTgeFwx8PeJhgOPT657gIljTNz V3zFmRwiSE2A/gAP7Afx6kZaNICVyyUF1ghxjMdpsxhMzht2/dbbmXtTHlrkI7K60hplDHJ2ckbs jvS5Z0lLiMAG5N8VLHp8Iqn1v+Wo1nVpnVc72BW4ej1NbKPkQCBcGBPcJlqckr9bx08b68LbwzFC gx5OJKSkg9/qI/h2iQj/AFuV1Nnq9XJSq+shbW2iYSu6Qq6kK3dzBRWli2gPX8yZ4cwQl+PA6jIa zujQjMxzzaO/H37ABz/7AbR8u2KqkEqbH/Gs4WSNiTGc7OFeuBQ8plDzi4VuY+ZdgdP5V2v2PAZw PcyQNJdwnPj4DD78fQeoGZfK/mnFUWxku2KGhv6lHA1Wjyw74r6ZSiHah9wMMlbvi24OGqitGE81 GBmoUoLWSe972DAIAABbuIDqmkpWbZSS3Mqh+bjcJhga/kkwbFPuxvIV0UUKs6nfmR19jZ3yACOK HiRI5PPOGPF5Cq2rRvtdtaKwcke6aQpYa7UwqPE6Gq6nylJ+l9JuZ1sZ8bCY4R90MTLHc5wwqMWG u3sM2L6nowqSZJCJgahlJMnOvRxZqKrLrREB2O2PUsqBmrs2AmzmVezobSYSMhtZ5QBnZhGFXgDg kw5+mbIcszB0jS3g7FPxG5oKECTFmSPVnXOT+2Y4lWPZvABL+p0ougBdbxq/NWf9fNaJP7MiaR2Q 0rMWUbOqNAkEDnT/AKHSwmKdkafbYMVfSztJrKwQMksQyWSmLuDOQEsmylse4dt2RwW2Bb37CfB/ 2uTGA6T/AM8QCDjsAEB1VEhX4dyU6xss8Nq64M3OpSJaFhViwNgeubQmW0BuCv8AT3yRjwDr0yuY DhAnQlkYrq7MzVX9JOe2/n+mQwHV8OLyQy5T+ngwL06u7YrslhK9hWRcibqEAnmQgXhzQ4f6fBQ6 uAnMWYmr7Z4PELsHPn7fwG/9XY076U3wrp/tW/f4qGTS7eaqgc4tRbsBemJqu2aVSiGPmLbgH9vh 88o88D8Yh7mTOVdV/BwCCfX+fAPAdCWX6YPOghhlaYQbs8W3G8n9MFs2xvu+DX76XGAzIjl5FKI8 Y072Y8j3BzjzeK4njw3Hx1VGsw6e0R2R3qqpdnXIdgcwWzFTsJf6RbVSB+eB3yGt1WQmcTr98g8G eUN8ZlkGkmknwHPuA/r1PJ7A0am18bQ4Gq7IsJoW3+zQ7JqQHu5ix65bIt8GLQuH7gHmbPBgYd1L HGPO10bZm9u30Hf+Qfr0gaXmR5UfOFq4G41t3hya9eGri9ZIcrdmhNXB5i4GXh62wvgOfv1VoZMY hqywM+k7Hv58Bv4DpkSGBgyhcOUm3AyadcrmpYxnWEviQ9cxmxNKTK+Ww7gtw4fw2ptXzzUHGcXV 2ZGObJvu/gT4D+wVqF+pZZL/ALzC6nSqZthGjU8wyy4SdntyGHfx7ceU6eVEKB3cadgd8xxbsgxx CYxZpndtfetfu+rOWRbkjTmpuBnVAHGkor4SlyD1qWRgYqWxqytCN9PDrbJDh8DBHp/B2R5ZlcX2 zOO2yO4A+/AP0AdNQJVC2eH9tAy1RS2esJbs28A56wL5m0Ohy9PoFcX4a2hp8vbpiOBYa0nWojM1 YNKys8JtGrngAwY8BXz7+BAV1aFqyNdaHYSbqWyVtkQ0O7EhouB2MCeGtES0LGrev63Qk7h9br75 Yz4wQAYf9RdQfSMLR3/n3uAAb/0mVPlAvWWt2M7jQlkHhslTp+pSWpBIMVKelpqaHn1Wnp5in63o 8P20+qh/KIfnDex7/wCfPvx8BsBwLGiPJG6CWFMp42jExj8BAIs03s6ezlHgR4fPtfIiExKiSrpJ XCRBjsyN7ci6U+ONjEZEnI8iuSogyZYsOBaEh2CQ8owt1k0DbIHiZYFoU/lMlgBzFJ3yH5h9SHqQ OZyb7MTOWjvfAV9Bfn7wB9+h4ZDMlUPYS2rgX8a5HjfyLIqWjpa2r1evIZSHV8OH8NPuBgmI9t/x DzrIZrg4vUCNvaSbxPgD6CA4D1ZWetPh1Js1oU0Rcr7uER1NT75XZInCJouXygB8IahEMQoWotDp cFSUCFOrbNWhXkpIFdaTaXv7IAAAwIHVRROsJ8pO/wCJqApLSKOzcyRcSSOqsaqt1q2dMoUWnMZG WZT5UV6JemvLYYb4VTBRGw9TIURjgM4j8gQMV9/Xz2PTlPcx2N8rKty4Bs9r/LfZef8Aib8eOuZV MkbuNPSLIYzLjhGSNyQNh6sYpcGxTKzwK5grosRTDUeqoZmsVusTyeMsKtmSHZFmrYu2rYTXJ8r/ AIeGcE9kHh65rS0alRuM8XKPAwH3RCVX+/8A/gNuqTh2JZdh0/m1zLtEC+VWEE0+tmGCWyAVeXw2 FYAdPcHxbtTkiOpV/wAqQyZNXpsaT/0TB26ggD799B2DMrUZqDsVCs7UhqLdlJVA6kG27ldOARiy GUPWaK1BTK/h9hi9bp7hjakDgdcoQxZq8m8k9j/f9/Xz/gD/AFueK7aKgtCGkNnyaxclUlp7qdqf LgYXBypuIeFw2AxDQ7UcOY9nIFPqSq4VBZunNWZlg5aKS7nD4Du6A4+fAP2R23IJIpSjTBDG6I4l haNsfqo5DSb0aBYg60mWQ5WudkIeKVdRGHVFaNopyu28eoW9raNsUkJLU/ONDta+2pZB8eK5vC5k gyNr+yAyTGYV+wjzAJMajIrDKKMhBP1Ifs3zPgEPnB7MRkMo81mDCGzaPv8AwDwHVtLQ5RFy4djV fWMnOtomgCY9PpKe2B5UVhA3Itj7U42YMTB5hV248DmeywLRhmPez9OfAAHAdg68/qIaQ+mB0tRY Tr/rdKn6qGxr0/WpW4CZNFprCTTHtge8LImB4ZAy1AV/DANgiq74MWfuqQ8b97H9/wCrxyNXinSJ hVK2gYkp89kCKa/MiaZ6nMSlep4sWGPhmA+EMwwYNQ/lvw+MVdtn7Ib59+It/wAbdPgDklxMSLnE 8TiRo43xjaM1tMqYnDMh75bwOoJFkjkaRkkRkwjSaPKeIt7t1i4yypcbA9p56XtfsEcMnmADlnDc k9CUmxHfBrxEDnotTnpS3V9V7xaieyD0Nq7XwEbbFmm1dZ4O7JLsbP8Atv8Aigv3RhX9NaiKqvit 3zJhm4bxslOB6ffGheh6gikQWUmMBhbW3x77wQ4J4fANzBnF3z/e3gUE+AAAP38Jh3Q4XLU7JFsa YEG1oB3ZHMDWAsYrlzvnmcxf5hDuB8mD/wAlj0O1FtYwQyiyT3vmxw/v4DAB+/2Vqd0U6vcK3ikM iNSem58G3GvXkq7SHFi2Ha7I/nGQO4frOn1/3HT+Mi/Kd0UkJv8A9+ft/AAABI+GmlKwb6LnPSpu IkYKiQRS2Nxz2kJgmZHla6YY4tTqYiHwrbQOy+pLIhtEeLIbWVtRzk8HjjqOIR7gi1vDd2M8tJ8u zmS419qs6REWnKudUt8DLg/idTk9b03zMVt4beewWQnUDRQ6yjcJ4Thifxt1+AH34+A8/WRg1ANt gEtUAZJSYYGyHZ4ockeT1NPTalr080Q7QMIaGtrcwhxU9YAEFg89m2hmGnTlXG/PgD/7Dv74uBfT +6lqMdBc+uatGQ22R63r13LSz0r5V8TF+ZvC2nvg+YDxYLLnIYza2hZeXi0jiSj8Bt1BwAP2wAI1 4qrVpQUuyaWTXCroYuwo1e2g7ae5DYtNFXrzRYyIPD91IYd8HGFWA4QPh8ZfChNm+7OzxsG/vx/o 5FjbuNzvK7ySBu2R4wUyaSTuLbNjEYC9w8jnrFJuKpSJnKRQiEKzZVmF9QmhhGoXvajj2+erLL9b x23TvUrm+GDZ61bCJyzA2t63iMkpXXgMqHiyGLIZIbh8yCh/P3gnyho2z3NhDfPj/wC/n0EBpVg8 yjbwaVcW7INeJuMlTTx2rOmIqE0RcFcCnsER8b1BkDDzN4T1+2vh1mzbXhjjSVXO3PvA/wBAvwFJ 1nZHZHTJZ1JC0MmNihjVe2BzYepzVdyLRav9rgQ6HmWRMX4cCARno8xlJIe6DPd2N++G/n/fgPWn UoUB188OxkWnqVSriq2pC+H0Zh7jtSnLkXgLlDIMjJ3UmJ7B87h7a8GCZMpyZmR/NvADgG/7B59O oVxGyxSCR82UZLhH2YAl5LbDLLgYm6Jv46eFV1jKx+tgheXLhklC5R448XiO7I+Ca6h09806JBRb aJ7I7HosN2EuDUYDiZiHY6RUsWav1uHMVuYhsCG1T7AwVVsXxcXznZOE+A2B+4CeAHljqIIJ/wAy vbQTa3CLdVDW1tshPzpGzyrlE02U1CMG8cw3ggtvDbaClyQX+L6gGbIk1dx/YN/38+fAMhDq+wJe W7afAwfnYZDZIg/JrfhEzdJaurshGHDrf7J9HQ08FyR5Zyj4828j90at38Bv+B8+AAIJspx9Ocvv wxkFWyDDkeoqIj0/VZh3mNCJXr5Yy2P+G4h5gdg7qgV/e/Jq/OcLUSUmrcD/AL/l38QnyZywRpg6 udiExom4EykjjyLZJ53cguP2EXzYEwsygKyYI7agO5xzx27QCmrxy1mr9t8dVK/xNMGkHVnnY6ag ITVPWDs2sLghgXgt/MtgyKhj5iGH1H0m+V+nQoDAeuJbZxgvHawWOP8A7AMf0P3YslgtStJGo+Ba tY1dYWUtY04vmHut2FOi6fdKNSlIQAvDQqHMOKdNR21PwhMiNp7uTHAo8HPd3ffcAwYe+DAlCOnN bgZRK1cpVQE5zPYCWAl78kaAJaV+PxEzZ1vH5ljcfgPGFmM/jCYI394AHz4DfwCD7GxiRHDVPVd3 HraW0Or+0uNXhzAZ3cOBy/iOFgTFsxdifW69DgqQ9DnJ7NWaurE/uxtJwAbB5/fz/VmRXkjKn2ZB 2FpIshChkQgCOPGwSY4lzsZDtFaIEWOBhbl496J4pDFLGTJGYlZlkiawMyQoK3iVJN2GccmZh4xi h5ucSJNFhpLZZENDaIhi0LaltKuH+HDhzN4YJjU+Ve20DDGM4t8szYwlXhDn/wBAAbBW+HXcwNWa TYwEx8POmSVMwBmWgJQ4ibukVk+IH90+Gvw1VtXyE7k1ZiyhRZ837cBfj/uA4Af7AZRbAq6oZDHj ZIySrdTMd2jHD0P5YE8t2AYslPT3BPATPweeamRnZsRZNm82EeAADYN/wP7Bi37NFZ38Ust2N5wY kNXlfIzkeWyPkoS+NEMgY+GyGJjgtg8PgVzCJ2+hq/nUnwe/oID3AefODcFen/Jytt/T+xzx99nj 4x8m+s7csxzy7GesarHAV5PnP/bEijd9WWqBMtjUznrdfWY9hc4o1VNqZRs2pdQ7AoLCdp7xmTcG 5ktSq8FlOEY1Lb4EHT4t5xxxrO1MDKRyD1erFA9L7ifwq4RYbst2y6V09aYL4tPKktz9FtmpVXPK RK8WVPV6dTq/cTJcL6WJexsgGgqVprWFmISreArH1YhQZ63F9fxQvbB+K0uv6fFUf/iwLIZLOtAP GUzFhNThXtkOUpdjSpjBVdkMhiYtuCFy0h9P5MUV1lmBmwuni1D+GwW6f8+AT9iIce36Xs98tC2l sMGT7sqdfGoa9K5ldzY0IZjtu+WRD4ds5w8QqXmH7UMGebOf/wCvv3V1pi4Cqn0z8aWORLeNzVq4 sY7vHNn2HgjjqsWCKWYFo3WWSSCW0kjQUzBse7CxQoe6uOlLR9gSHdwGxNaWq7bc6pRt8yM5bHqc yxjxZovmyWCHcFbzKHcLAWwf5peA4wYU7Po+yGwhwB4Dr0aW3nm48OxoRjhOox8uwSQSdPbwwvnd BerlEZF9wDmA92LZGY8QGBtasBmnq0KvqAni7cJtXz+wYVF79VFS0ewKQzKx1c95glhWCHsiIPSX ZfYVuxpQmVFMEIi3yNbmEHEJt8A4h9zN0GLLwE+8b+A3/p8C7Qy2Mm4H01VUpgbuREvDJajEuZKs aXY13OA8OyJ8y1GQgY+v84cdsfODPPhDaP8AYD4BgAc+wRIYpJGeJ0WFqThs41AreheShhdx4vib pu0Y8tjWVUIdXz2ZWxfdj9NjHtuDHKmWdNww7aAB7yetGYvg81DW021VZtA5uTX7COLpJgt4FTKN D5s6fDp9bTyH8hV88HuYwXydZBm/9v4IH7/1yC7oMUijtXIw8k8pHq3qd4DrTRE/F9xpkWyGAzDW 7IW9wDnLMT+KmOcCygxZ4Sb/AH/wGH0EAziFbyIC+HM2XDG6b0jhJatzDteGHA+JlNnIrdbvktDm r8y1B6+eag4zte0DEZ4CGzbx5+3T/UPTen9bcnjOgRXBJtS7mtksIhbVY1/L5QerICr4j63DsiGh spBwsZttCBYxjuYLQ/6J2T3f/Pr+wAAC9tAmcxwviMVeTmiEPIrL888fBvoRuKzFVSZFQiUyJjJB G2FyNHbV7eFy76JyWuilTOaZ2i6CVyO+S/1WLh1LLHZLUHLB9QUVeA1LMAc8mMjhCTqrajyeB+YU GcX8Gk+DPYn18/sCD0oFcfDMlA6a52RKZKlzrId8XyG4WFDrloloaYY7qXBW4dk1IfDBtuPbkxyZ oVxgzhOybAfAef8AP9DY9LcM5wam1SG2RXr5nMlx1Otnl9dTygsSBKGPh/DDzFCr085/INRkYzFE MmzHEkIbOH9gPgD/AIDBV1uYOWM4TAzvnabxoGvVt3kNWlfURvD5SKQ0NCdaKGHDB1uY4Q/nr/Bw /fJYuRGZnjzZwCA8Af3/AGByRNDul5M0SFI8qx25PslrI3Vt22PPuHnqAxkRssXYzq6tmLbbxsUF Fe8G7PPNfHVjHBOTaCcmqrj6UlMcgCWy5MKQnXBSdiCYAk2KGmhon1tTYQHYzZsOPPw9WfHWAa0k j/RnZUFTWwgmPkwcrOudauWh67iEqyZNEumm/Myt2ZsVBlwAtY94iFd8H+hlKGs44mDAOSrhR6Rn GTJfLToUGKTzYa3lDYxhhOMGUWn5udA8gDsG0+RDkFvp6sgqLrcNXfiz/wCb1JEzKrCaFQQCBmTQ OPF8XWX4Hjqsd6tEMpQ8OexgbRAwLHSVMhajtV+o+HGPO75K2+yA+LJVb5/PT7AAnE9GeSgv+yef fkAAAAHwD91ajUbYF6ZofuXEakm4IGm/Srp7p+q08xETwB7CMUW7RT4bIHshbIOEI8P5VMWSfFxm xu92cHQf0+g7/jDvD5DpDT/fy5fCS7NWoyvhtOGKZPB1OHFTZabzAgnmIdkGGTzlaEFKueCvIt8Z lhH/ABcD4CA59USC/H35/aiKPbF2xE9civlJnoGdTgkOk50B37tVzYSa0cfmIafVZdlH4Tj1gPuJ hZRlfEmT9kkIDPsADHtFsABBBm0m7BAWQTTI8iRTxRJI8cUukjmmhEQj3IIxqEZ5SfJQKosnpCCV opZTIyVgHVGoo7WYkuu4SU4BoY4+Gy4SaAQF6ka7sI8nQwlPzxtXFu3unsOJcLuFy8ANw4W+nrfz DBBb36v54P6zzwmT/wA7UAAO0WwAPPw7jDj5rrMfLGQ4yfSMwbxdDo1XrLi5SspUoOP+h1u+ByKG jgV/4LgzYoavzlG3s3gf5Af/AGDYYdLX63SJAFDd3aNSeV2cteOBu0O73YBKMNoPj5X7IHhw+yfJ AdLEIFV85RmgqzLJyrgjs8Yb+BP7/wBaVs5aF0w85cyhpJqypqBZtwDciQ2GCiGw1zGW6v5LwOGn /VT1f1o8TGblFoE9jNhPP7AAqL/f2qJolWZQ+qk23QK0jmN5IxHDHHIWpss9pmxr0zYye76JllaO As6DLOliOUa0Y/alLgTfPJyFDiupjT2vslckQ+r7TdcFSPlv1j3CreZW5hTZHvVBXtDgHzZ4bI+L cwhZBxSYG2uYfGforzvaRVzw/cBP/Xz/ALL1gfLQMsCe+NDI/gbauB2s1fPEseYW0LUzz4yj3Cq2 Sq3C1HAw1dn56otjCfPHkZveyPGwf2DkHWRGtk0e2olaoK0xC5LbWNkafHc7pvsCwbTTpTY+NGm9 wDWQ+ImIge+NTYPsq0zD08vgwYSx4TV5vj79hx9+xxwmFMwbvOOHsFnT6uyTFhSbYMWr+TTD5V7Y 5NDJYD38x8p/j9qNWnjT/P54MGIauM8J4M+/L5/3590Ikkj1UqvppBDhDWsVs86zuJ4sRUkFjKbc 9fcvbi2+9DRoUK7yLMjsFjft3I+0JIGs1lRtcTXHcb6ku75Dj55XlGLRtqh69ZGuyK9ifW5SJX1o HlseI7qKBhP2d4AMCHBXBvA2fawdXBMcX7gL8AP47+f4hYbVfUCo30SBobBwrW6yNO6hw9KNMOE0 Poi4yyhP4hZC0yJ58PY/z8WtZZSZVCGf6X4m8PfABjhgwH2rW+le7DIDOlUEeJB60p+46nqd2s6v 5aeeKLyG5Mg9DQ7UqtwcCEMHPX60tRPJrLQLWSYPY0kHv78g7+fP4ACQ5alb3c6Pmwsjtf8AqCyX awk92PXAvGFh8UqlqWGwMi3ZCeyJ5CaqtvLYK33fV1cZj/Yz/wD/ABC/ADk242aSG1hkdmEg59c4 fTivyPU5vnjjqsXkgGcrnBEjKg1HIh/kWROcsu0qchhTcNl21XW46Wh1HcCQ5ZJtw1Ap8ZTz6rto gwvljPi9V9cuJCyLIrdPQsXCZBgONtU7MZuUboT+7VcD/YNg8/1aiv8Ag55cVUNXA36qlHZtYY9V qtsV6XchcuUeDsDg4p/zXDAOq7eeNmGYmhq9Z7GbSf09t/4C/n+lupkCAG3EkXKVAu/NS2po/bGv 5bIUV149Lhr4eq1uEYZN4araX3xHZBgxDVhjN/Wxzf8Aj/6fqeClvLXA4eqnJklWEBVf5gPTJhhM K4uW5VzZJBD2d8cFtgT2qAQUnhkZmZDaFl5d7RpN2N/v+ADABvwszyqzYP2O0qh1xwkfApgbPpxU cI/gsTlz02Mq0cYSNC4RQV04ztI/fI57ccclxWjlbdwrlJnKnQ7uU09jPKo4PlLZuzanau5DYhi3 NhlVLMIODIyIcN8sCHvzg3I/OSiuMJ+ESHZHQUHf+0WwbA5suv5DHV9naXz1bxpiGn3ZYV8w7Uj1 lDcj1T10erb8DrTIt8gQ7GBJ5A5W/JihRZ3zzZz9P2A+fwroYB02rkXw8GAu7tlATlOO8O5kdTDJ kqXXKvDX5lwcDQ/raqeYEPkm2PnBmbZAnsAAAAH7A/H5m1LIYNPrYk2/VWSNDu9erez5OcjqbHFi 3erxXzeDCHM+GP4O+L4E3MJ7piSJg3YJV3/f/wBgASR5JGjd5HZIrkhZGwuNCiGJgQ39KSRA98bl leCpGOPY3Iydt/UglFZZI2IYXYrLj4NAfPTC8IeKsgGdZBsa26iiUzEOSMy5kXTnEe3KEQ+Xs62y J63xJfrQHgTrPHtAzI5ve+0R9BAH/wBgQfkOxMwM6ATMqzuExQ7JEkHg9flrUfE3ECe7Pp8N8+Gh r8ydWmCkqzMHko+I3B/N0ef8A+vx/orX09nih+G1+NdryINT/MDIaSY5GLV16xlcPaExOW4b57rd 4AbBng1v6Gh2+MBmzaSjn/P/ALB1JWQ4U3FqdbPZTsMPXSYtGIQPUavr0xNQ69q9Dh/MMGIZiGnz XilnA81J/GeULLMc2NJOH0G3QH35gw6WZdzULK8jSwy3CFSO73MbZjnxjXaK7rPIrlgCBHjRMcc7 dTlHIYzF7GpbvPu47ePOXCraajTLpR74TMrOdu/GTaPskviQpsidUrFV4tkTtn1UTEMwnw508eB2 dGGInGUbuiDN7/v5/j+O/vxhMDNFaB2rSXcjhJqUoksjCYubOIqbIUtGXbQun0/gYcO+GGDtzPq9 8VbJeWZYV/YHj/597AH5B6JLIR7AApieZnh71D/W2xgcA7BLhnoqm0K/84YWw6fD8HP4HYzIzYoe LMTeDQT/ANj6+wb/ANOwpRZ+eQtrvdMN1Kep9AXtUC2HIXG4M8VsTQMMfDcA9VmWRwwaoFwdxoZR ZtCryazsmHgAC/8A9g6vdQSRtOiSYzGeOV1y+nktQAi8emOMEsY0eTfF7DCtrBOxI5MYwBIgPdn3 cu92z/5bo115+lLQMYLb2eKbat2OyIAn5mdX9ZGLQq8tY3dReDp4eFMmJ7IC08Ve2zphMYrlP3zE J9C/YNgP9ejTQh1EFsCmQzHcBLVRV42rrN5INsisodjWgvHnK4B7In1VDcFtvZAQFggTnD+l7MJg 6u2Sq/YAA56fP9IxkL3FlaNb+SkizEgPp/LscWx7BspXrHCr2m17tTw9POMRiwxfGAO1KU+pp+FF 8pKIwwHhj/y4Y1Fv/PcMcK+B09X4uSyjwGNDijYym4QwwdehtEVesaXSaeYWjBeHuDJOPp55qW7M eezdZkwfmweFugNgQf2AZWabblEm3g8qRSgeoa2sikilZIvtyCOMvknFaAJUlIv8iI5N+Luh45r4 6PMcuqxcgblXdDG2QmrZuwl8O7D7CMFALvSJRPIfNmBmSyF8O1PlXvmH+jhQn9JN7Hv/AO/8B6fB i3Fs8h17K/02yiTIw2BcGopgiQz132ahtE1fcNPdVskxDsD23Gy+NozNzwmT96udkf6/4A+/AACl xB6b7VV3Z3V2pA0u2pCJcgmV7X6o+RWhetD4fw6rT6rT/shwEQbbG3Puh9mOJITnAD7Bv/7BAp+j cwGIWEkZph2p+y63CNjwHQ2hT3RDs2UrB18xMQ3wwnuDJvzgpUdyZ5aOMs3m9jfkH2Qdg2AALDcn 3TKioayEhweL21ac+7n7hWJPTHWRIyQaR0jaF+e/TniMVYrHu5s3fAFWQO4LIsxuMNWa052m9k1D u1tRA7VcxBeuBElKb5p9DMKfcHJOH+CqW0G0GYRmZ7q/9fyiD7u+f3/6DI1/pDbKRF8SUnapbatV wZLNDw0NPEoZQoWAi6fI8k+yTN5VJ5A9jM+h8ZZvuxs5/T4B+AAD/UdM1EOCRYEyvmjJN3+G+SkV vZ8xfYUNDiu6vXKGPDrkOYn/AAHA4esEC1TNzVyjNvnv/wCfH8D/AE7BdoIBRHSa5KLdXAdS1Pkp bANcTAkxXP8AEzTdoMjAyWRW5gRyDYwOoD4OBSzFfUY84HAiSk+2/wD7/wCfBJ2jMSrA8MT7VyM8 SwJndetK8W5WJulFDyBY6jRxysZhMjojsiiS4n7cbyS5MfIoWfHnpb1Bp0sQU4XxmlAJsaxmKmLW uNmF0dkpuuWGualUOeQ3BkQjA9bnqR88jiBgzEqMGWpaHNQew4sHtgwMHTCHsAfKX3DgVGslVcPb anuBbuaOJfFfRG2RZVPp9VmIlqKD4oTDlL3hZcH3rMo+cGOBEk2DQPfnwA8/vz8q0dodE2QePaab ashPvh2bRJjJuaOvPdXoctEaE9guBw0xQ0N8IMliwP4eGpb2xCaOTWpjdqSD+ggD/Uk6Za3YIfTr UC4k204ZpJsiB3DlAkOm1ykIdymKvmLd2UnT8zupsI+2qBMdsxdNjKgtThPB/wBgP/sD8+WOV9Sw ek00rmVZdLJNFIXMMEUv1Bl08e/HJtRsEXHHuBbkEhE6QwSCEoJo4UhZp33I13tUQJNO+KXIu+SW rtxA53Ow1Q09Mnhx2bpzhLdhZRery1oPmTW/8QbO0UOLPoY+q5mjRjmBkCyOyzeQB4jFhoV7gZUa r9lwYN/P+wDDEBWSszKW225nC2imWTOtsPgWaKfPV/LW2ixnZ8KQyAcOnmA5i0JiqBIHuSDFl8fO MnElJ2PYD3/0C7FfvEOtCAEXpuznZbTYaS7tFqab3iI4dpROqBDDj0OyFtDhvloVXXL5sP0Zl05+ MOcJNgz+Hn9g+g05qevo/YsPm9saBDz0lb5RMcHCzQ8tXbJR6YQfDFwIVkTN4OdwLL2cmjC1dmJ+ EdvoJ/DHtF5+QyK67is6h67pI8HeiPdHk2FXx3NYJ9tV1UxVTSLSRViAckbPD2yUMsaAPbxx1uMI 8fKSzBTNvhJrcCBjahEcO1GJb5+Qruput1+YHrd8hmeH/AsA8qsnY1oF2YMB4mzZwAA9+fH9/Pm2 ZW6Hdy+TcsU+nMmzA63xe7O8HewXY1TuQsOwTKfodbcIa/alc6h8LpBp7yzofJhiO7G/dfAYvyC/ AN/PuYHwPKj21ArllSU/DVFW6mjWp8enIct8U3KuTCfcFVPgeq2QgGeDxD50MnyhoeUYHSYT6CAP 26/eAP8AUC2VPJbVutx7QBsipXLjZa6FUP8AL2Jod6lF2QQhob4Y/MD5OstPQ525vPKGW3+E9rt/ 7RAF8+/bAfMzJlG0ARHjdSrhfUeQ1hHIwbuz7grUMCCMWyNQKyq0Mwt0rj/CSL80bv8A28fNjpPr avHlL6qkZU1kT7LMKS8r2EBthTcL5KCbHlLfJEPTGnzOXw7G4+2qpis2amr4wswGE9njYAH7AA3+ 4Ec5p6PL5JXn17bSq7uDbLYJjU0JFqIbRplQyj4wVW4ODJvA9PeMbQqaxuM2Y+FGZm83vmwb+A/r 7qosN8dHdTJWDdOEa1EOzWSsmiyCW71XFPXIUPTE8O+Pkx8XHC4EgDgeBp5P2KDBiOECWjaiCA2A A/AAHVhMu2FOximdZdQTW1PDblZt8B2S2GH+JaLYRSxnz+G9wDzE+1CH5aYJ+mTtAsvmDy8nOE3Z pzfgB8AAPnwD8fUsdujBqSK8ImSJ42yxvcR0MZrAY7UcPk5Z9uNRsPVs4bmCll4kEYsOiP8Abnal jR9o4NdB5BfmpDAebT2c7OE6q9pRhrtIE4PkUSri4bgHfDFwUnM+HXJ+e+I8zckPjOGOyBEfE+g8 +fgAB+63GDAuvo8Olii3GajND1u7yGrOYNmlHhN8C8LP42+WS4Ibg+HLLX54N8GcDtEYznAng+An 19B4C/P3SHTyEh3uBP0t9zlJksxwC8HPGKvbO6IF3GAKfIdyDFDXxDIVvQJ4eBVRH5QV7MeKr7XO 2we3P+fW70/q7uxL4vn6frBD38ePB63XlepbOtjeJUXTg+HsbQZNQlbskyk7gwOHk++ONrNZq9yP LzvYQIcwfrd2AAg+fcsjR8CV8zWcakRyR1WO4tP7ucefIY/6UImDFCyMiuyJNG2ccmOAJU0vixY5 q/PSyHMhYquJzBB01EbSOtCeusz24D7yzMmaQdDg/LnzsxnBM6S4GlhulC80OSYhObnBBcwhPzGV XB+lTPgzBjOotvs+0KKIxa9s6qXGx2oYLh4YMCtY9aU/6stcjY5olLHHgdotS05lykZPFg80YXnK a7AGp0lVSQPpZwSgOfG3OlhYKHo61vHMeg0rofZyj4rkpoU1CwbroNyY8mlJokcmjwauhdfBr4HR 6YBlW0oBlMYFJrdos5t0yo8yyOEOB5904YtHvMWzFkB74ILdjPlP0PYzIsrKu0dzHirggRHPvwA/ sCCg0H1vR6rqNSHveVatwVdMV3Y3Ere1LCaEi1K5tpIcnNwYDFVzKfqtDq+ZBunznJ7fpto09LII IESQZ9Bfj4DgNRey2F35mZTANFuWm9StQDXsdTrfOQ7QbLgrA9sKaHcIdkWQ+Pkxwh78wAWowjM1 oFGbfDdXJKOAqLYUFCAHwHXYLzL8nwzCvPzgg1DmBGG6BrUwNhi0LkSBYqanp/G63tQwn8qbV9ta WQWs3JpzRibwb5sj93foPPj+J+kkmVAkUU2n7I5YhLHhHDIe1NhCT2RRqkeGQ9obLuoPkljdizum oLuzyBHrzjiDwaqmAPzya452zyAuLhkLjIdHPdOEiJaSt2aIU2/Cm5UpNmfDfLrpSY3p+OB6r0NV TyZN9KM2Ly6pLsDP+yEA/r7qfvBbuQ9YifKaKNCUDm5ykp1u1EiERaAtCQLtqk1+H23cA6Gvb4pO E9HXGZ5aKvFrJ027UmcPnz4ABv4EAATNyxNQFStkJcdz2quZaA2Spo/Gw6PMAxZYFymEGUwt8PD7 y8KQ8CDhlGZDKcZ//wAB9+8+bWpXavFs25rQAnpNbmUka75GdRo/TgtxSgipdnYHAx4eGnreDa3g Tjh2zV2gZb5zhITYH23ePoPgOjvUTx4zQpGskItV5vcx8hgY2wCg98beSRjzkCYqC8Tv2YiSOQ26 ycBkZa7MaFGznfhce7sh2BI1N3oM053TkoFelA6kptE0CnxIasUsKLV8weyQ3AOtmPmVyh2BPVoY zlDRyZIdtkBn/wD4A+YL7IptFfgZ5SwlIQ0OFosMdDvggW2toKplXrfAplPvtJhyHwQDgesbc+Lt CM8nDfa7gR8/UWwH9g6cFiU+yvkd81aRe5DhqMsitlMhnOGg+Y+OVcpCHaEMetw0/UJcIdgMI6Gn gKrhcZF05UCMctGrkl4AH8H4+AP7/gh6novTflaT2Se5NVXJJ6G23HU8MP2ncXKVbGwra+4GDNVW pMHQu0vaRHD8ZaBZMnanuExxAP2we4AB0lHiiSMaOZItO7rDGrQ7tTngxgmSPxxbeDY7RRtrxTtL K2ph3pnQ6xhuzRbenbGstp1uQURJGbw4piGJ6hhY9byrYhxQ2cpahIAd/wDDoVgO74MisKvUrgPh w1uyFtPcIYP9Jy3tnF7MRnjujSe//QefbCfARDpJfFzVIeXNRle+ZZLQs5wJDa3LYyk2vAMWGwTD PauH5lq7fIfwyYwosecN8JOf5IOwdNSZX+n9SILeVZa42zDIFS+QSs6PbBg8L1CYJsNhfE98MfMs CWqoaeenB0YYU3MY8JITDf8AYP8AMB1XsfVdPrF8ccsvJN2QhzLsiSVuwh8tkVnKXXL5NX5jgyVs t3ZV62jgXCBB3NGKDGZGB75sfgNg38B7MESlp2EnvhZygjmKQ7ePrIkSS+zPlWKZk8MMT0u2dII0 XshmjxG5EKyIv+R47vAe2+fNWLYQNgq+1a/au1TUcG18ytrDH065y+p2RujvxdkT4eCeh2qHXw6r hYFDgzFZMzRzjZNk4Rz4AfAbBiB6shV5yOkPr5WmUeSRtwXxqHofUhSV5L5aq1faTwsO4BzEzjd2 OBid9tVcFni4uzNjxN8439+9n7FB7vCqO2LF8Wxp1Tav0x1LyRPk2xU5IkwNlb/F1jOWD4QmVvDM Bw5APXClcCGD5MslLQRmbmu9nT4BBfgCDsB/pP61FO1FdofM0zxLOF1ibKsBin46QnlE1Tq+KZcN 4T/5wgY/n4FjTBn1fk3hAhx+AHz4DYPP5dQkWsnh0L6fcTT7OsemGmkE6SxS6aDa+piE4l2po9Um Z24nMD4TSSRw6tM30kE2ojmhDy5aRoSYmLwNW9Mrywy+mtJgQi7hZrK4jqyENPvC6SoIWBzn9VV7 sd2xwQ1sh2HTa5sJ8KLdX2o9h4a24L6f/wCn89OT2YYUQxayDCYm/v3t59+x6qKv1fYm1jcoXXvJ dI2cEU3C2obxEsgW5RBZ58HzA5hbMGGB82Gr21H+zbojM2+e7wfAc/8A2DqBru/Zb4YPHotwLdkS qxCL1H5x54SFuxnLs123YXBbW63mbgt7CvgXhkJjBfuT83+wfv2/89JLA1UA5MyHVVeobs4WUqku 4CeBaPYXV9hAShget42Rw9DH1u8YEG2DubMri7MrL6TsX9gQfAdOibuc1jeKqSdU8aot4CV/7zUn JykxTdoUnZ0kmEKot9lLZlbbeRZHxLmGOKGC42xAEZY7VEBmzNZvimGZENj+ZqimGRsnThZGcXeC xjS+Vu6kSgcenshik3zcFu1fAtQcmsi7PWBfZOk6uB7/AL9ifft/6shV8gxYJWyAzG4LeckAkB3e A95D5dbuXHj2zr/A6ffLIT2DfOYNuzvLPyhZ2PujqHR37tFsG/sHIN0fPOHnRPpu37+JIcWyQjAw JK2Qicoxqh8saZXxeHT8Rwl18HrmtdJ9tNT3gzNAtaJnOEhEb6CAAHz6/wBBMNkpd3sQwLSK3reZ ap9kiNFhTK/l88pGsgKuhp7IGfA74HT4dqQK/bZwazGZ8V3nfAlXJRz8RAT4AAg9RttWDBo1ljjR Jt2GIVR7DLtLHs33YhhNmQR24nIUVqLCFNl5IGgCUh3BEkojN3ee8AG4xKZUc6WBOOjwpI57FccL jmWWeSeL2on2QW3WK7i7kZB8Nx4fM2/CCBHviOtrBPi6yM5s7Ygz4Du6f38+AwmJi2KbdhFpFkak JjGtkiw9PT1dImVfdzvaB763g4MnJCHzm0e2g2TDaxazZmxmzbwA3/z6D59y2pDW4EdEsUoYqXTe hut1u9XpKq03xjYz3Q2AKaRWpiffFcOJD4CnWEBqrdnWVi42YmcC4b4AQWAAgAGBAfkKoAexCB5T D/4QdbxUs5bUyEyt9qZGgXU55XTyHzLU09/cOVNpCpYK2Mt/a9zB747c+QkE/sDAfQcdcTGJJTEd OXMz7uqkcYRgY4q617JLbJL7yo7lx6U+bOGljd0H086bXfIYzMkUpEdi9rdRicuSQOPPTszK7uy7 myk3KBcy3xKgUktIsk8Y2cDY1hSmh9H1uhuBhwhWDMVZ+oCe8snBkO0CexpKTaIPYH4+AAbByDJg +s4D5aiuBQ3ZVtBDN1OQh0/Itik/5s6LDV/DcHCZMcLA5xyACDtTc6a4MinDbsE59/1AH+pi0HCG UvQPYKunXZc1VU/GiMAEO8NlVtFcFqvF2QQT3DGx3CZy+4qHq+6UdPZv9TMUc39459wH32DpA5ty La5qYybQVxo3O4RJd2BVA0/Z0w8eXot3WQwJ8yq2SyIhGZakBPgTmTk3eUZ3Uq60auOcBP7Bz7f+ lqqxKgREwRA6iNbd9+WSUhZLG/t2FJwjxsGjnS07bhNjvkrJ/N4kVxx+T89RsdbS7fmQ3yvafsiY eAyWwwyMkiwltNAlYqu+EIb5gHhzE+H7788THlmFq7Nsft/sEAAP/QerErUz8brlI5tBILIYcVJT R6xv6v8AUJgmnlIohmG+4BDIxrbe/wCEEDZ9tKq1ijlEPH3SQgVIYEHkD8e56gL6UeOYJFf0yuAX e/QFX21aImwJuSPE8yQ3dDV1sfMT4a2tvhAPcUCv59jPiyM5RubxVxurXhB++nz9RP3R4UrN0tUg eisecyae7GshSbF8kSML0yuQIjUZFtQe+Mgfklbr7I1ASAHAOMZygtGWd7SXbDf37DAB+wgjqFIS J0TNirtLnv8AC27rtrt58b2mt/EfqnrQdwV3IPtbCPHGRayA7j3x2NuT7cj2m+jYWLvTNzEO2srJ fxpQOgSueTB6QnlFdTfMBBCYnmA7iHIB657f1NYzhwZ8V3kZ+pvYKif/AKDsHXG0FKTd9hFlLDsi ma0renLCshkPNDvCtraTzQY7qIbhpLZdJY/+wzpjMyq9X2+zAwZs2Dx7uoPgD+/pkwQa60MaaYGt yn38xS2TJs1gJODRZtwWN8TdHwen91E/jbBW/LWHnAdZWUPDjGGyd8Me/m/8+AcBYVZpfo+ZMsGg oeoen65zrsxkLaq8Kb5KaF485QyHw637qIdXmKdAsH8mjXk+C3nY3Y2k2oeAH+fHwGwHyZ5O8kY5 Y+jjE+5Vf1HhliGPxtM95d9UtrRY7J87Ts+7/wAvZx4x+d3PzkMAl92XbgOHqkumt7+1Sbwk2Qk1 iSrIheT4X+HXKtZr24sp8xiyOCehkZk7cALxtZN8aOTI4RJ8A/IP4iP4sHS3h2QHMr8NIF7I7baE rKQYJELNRAMVIodyQ/hzLUMahGRg4rAHgbGDjEYor3lWWybI8bA/H8H7YD5/qs24bO0roKlC0xen UMCF6jJdULWrZKuGu04tTrRZKcwubyyPywYxT9jHerED663ILA30jMPU7Ivr9fpPH8a/QgOGLWIJ epD+A8kLTVR2Q/8Ah9kiVsR6ZcFfh74+VlFfLIX4epDeEOt2Fwarpo+BeEPkwsXtmHCQm/279+wX 0BB6izTCWUNAgRpk2GR5RlBJe2XWV5rkUKcnUruWAQMR0mRIyyJE2TxbTTLVd6n33ZrdN8c4BPLX w5stLKWWtjW1jT9/zWRtYR5Kwo8RDcqvlq6uhr9bh9SCGZQ+H9y098v7c2Z8rCoEbAHsmwIP9AgP Y/S0PIFrZhqbVewm2nzwG2ncen8fEmBfHnI8+jzC2YmTEO8GSDPHnjhgmzFBbMsg7RwCHP7+A+/A G0vmXiuVMDaGnNw7nWWNN0j/AIKSPiCEMovFHyn+NzDAdxrdxDNTbeE+4kNGJ4q7MT/KJv8AEWwb 9z5Bfd3eSo7GqcOLumsfmOWSNXt45QWfGhDXnwWh8DmcwmB1/GxgLee1FuHd9oV+c8JdjSOfoM+f 2DYD4BaMQsgYu6F9uJ0js4REUrLlwRnxzzdfHTpRHJLEVk2nVAjptRUKqiTEkN3be4NVcEWbCWjL RzyvT9rV8ypIJchklOt4ZhPXpjk5LzkLfONuEzUIhw9n4kv1pOMM/PLkZll43vYvaoth2BBPn2oc uBgTe7VSgaZSXaKk0mw/4yTYDCYFyohSkWRg0xzHFD1CJ+KeqtqgB2fEXtbyMB0mb7VgAGID8uoJ /qHBp7YGmVLbVXodSw1y8iTvHsijNN7C+xRdZWhV80hW4cwYmLdf2ojga/Q4IfcxdDjGc4b3zgP/ AMAfVUS3KAR5aUm2UnKLtYWckREewQFb4mJL3pQsfmC/VZd8riuJY6JXNlJ9l1YhjGVX06WWynaT SHbYAFuYAQB8/UQAo4qMYkdJKtUwkie3bEqjCOR6yINE1WJoNzVzSRtaOBBlMCTUstxvRkeo4m/i KrQJGe5wRibBFcxmHks9PXKTjJ5RV5DX6TnODDMfGhhKxUMgGfIYhbML4dVbWCeDmcZK7ngDq7e0 fgIA+/HwHT4HMGnu0GhDqWBcxujRcO7OP1vYNsFk98TaR0llFsgt8kh2pC3ifUt4AdW/cx5Q9s2O rkk2c4C/W7sDAA2B/WoyQzNXzL4KIdFanLBuaNMvhVtOj2EP8XSIU4HwNDp98pOG4GK5rOwJ9jYD Hko0C7MOA+6OL9ihe/gN/rHdAtgV2yqyaGHW0mwbgNqafRuS3ryeUtB3cj34rcOSMi2wLaq21/dL UyorOL+jBAgRJBgH6ouAvwDwClmimktDqC8e7Mszx715GMlN3JNwdo5xXGxwb4ZhLplWU7MkI2YZ UbukHBCs4/pX3UO7OiARXdPEZlIWW+Hmh8mYUDd1MqTYQA6rq/tjtyetdNV4ZBbDsjgnrZDnH8UF tHJvY1Dq9ZGf6WvB8Agr4AAA3/o8bDFmV6PrGxophAcHxP0uqZjJDh8VtoTZZ+unBg09h6rvitw9 gVs1AbgA1zZHu0PjMzHO6JvYAAAB5/gOCqtRXsRyZGqwWOq4qRlBwhaNnHzFm97pSmLrl87PzA7I HfLgW7Usuv221JmLML2wmc+7vHIOQYoL8f6CnWRMUo4evmima37qw+Q2AHPV+WfMTzCruRiv9N+N bw63ML9cUD/9vDs5P6yyvGLsceEFBAffvAdGY2EkY1KpqEjhOnqVMJH07Y3G00DQyuaUczNNjdxi PJ81bzLkYht5PHJiD2LJFlgyJQxrNrFm+ORXMvZdW5NqHhzW/ouh2EwyFFOwzhGpsVYkCxljKmrY 45iiw513LZR5ZUyuZRiVXqqyeh1f1IhBV/VlIh8KnRQtfJOdKd/tS9mEmKDJeQ+IQit10VWWfAHp FsE2UwXVMM7LLsFlMcgO3Fj9gzJ0vOiFMo4UikUgQPBVblgFkYhDl8bnVxpqCiFB/aMKFVwhigKx xLSYxouZpEFKOfH+/VvJuOznXQAuxY83ySCfDD9/H5/PVjdPuq+0NOtlqt5Lk1Bs1omDdR0dqrh3 bbIOjIauKiYGWTG4IkKn/wCfHahwjIy2ZWHpRxmPpxwB4+kFhjhyBft6fBvGkys1hKrm39KUc+rN Zq+LHTnRYsKVQ9siD2AfHglWF1suQDeqy0CmDkSy8MaaWvU8Ou9emoQC9UB3H/mAsMRpvmZc9x00 rmpbcj1SgYxav2UPivQ65fKnirH54rdwQw5jjZv+F+tN4GDOUEyYP8Jo79/QNB1F4DjouRZFyj9Q Z6et23ajR3ILY21MIr3KJW6afVu0HCyLItR8/JFc1on74yM1Z/iAnzY2knF8+AAc/P8ATWMUchjE sweN9KzgLtXu7uJbufckOJzk7cu3tHQAMyQlsBn9RWD51sbAN9q1luAj8V83wVR8w4h0fpLY4qfW 54zYXxB6TeVX3ytPljFmgCydyN4ZEIx9qA3hS2IcnWb4UebMBhOEvHaI+fYH5+6D7oIODHHW7G1f DSQ233y2ki0Id8D69lngNZC3xwX1tlfHBPZHCZah6n3yj/8AS8XUAwHaIM3VYBCf8D4DHz+jTYJs udZhLO0y6cFFZzSSDYDOnUEkMSEKsb+HVgRH+qbep74d27x3MI1PDu0XZeFxvO+e+IRfr9AX39Cx PbC28vLpd3Q1Vinkq3agOTV1saX69VZFT9ka6bE0AtuEyt3wOn4L6G1IdoUs8TBlmPloec3t24Dy DsGf2DYACyRNEs7OHCGNYgsVxokssqxxadJ54nkTexmWUHCoypObAM24pEmKB3QTHGVlzjeooIz9 U2QutoGPjjJx9tnSYR7crShw+n2oHWTeWgBwf4hEC4VupzKb+WLivhBwshwTzCeQW8KlvD/cyv3y Znje0gGg8BQUHpD6fwZjuYyLlDgbae2ivQgm6Ji5Gr3hsoTEPMZCyO6kNk7gGMW0eP5ITwfLQWeD hLsSdgAAP7Bv6wV7YOaeKnsmpZWTW946eDo0S8WEH/KgG2hJSuUPgdbh7s+ZszUBcFJq2x54vWe+ BN7BgAB+3dg3/n1hbUfNUGaDGvnNquWzOHyx7tZAewg6bXImkdnHw3DSuHMU+wefHnoMMYTFq5N5 Bdr3Y4/bB+r91NN9TImqL6WNNMrvlMh9Cfbx9V5cfSkezlDjJtED1JM+0JhEuy6zXMmAdcP4ZJfc l5d+OA57S1+B8rG+Qa3b8dPnodPqWktDJVIp2QefGAs4NEVslFKrYLIquyA7KnkMLUgOF8TmQXwN WZ/728f/AJun37YHB3PcL4X8nNsat0ADPMSYgdJhh2wxEfBMp8W6/cOHww4ccyTj+m+eqp40ZV6u TJvHCeD+ffgHgOkbX9sW4LpujaM0+1WbT0fUU2u5DWMNqcsntFc7WBp/tuHY6TZC7B3UUkD+HJ83 O5Pcn4QJv78g8f2A/wBM3NIw1xPIwAN/aXc8DXFb0lPyNwlCMT1e78yMH0KrOR4RLFtkdPsax2dm s9YxKYGjaUDQH19PgMcV/DoIGdYoY4E1MSR7kMM0s0ru+zM0TSSPO0skjvgrMzS8WBX3G5QrySSh oS7JE77AxTuyAASzhVHmzl+BXQI+HNP9qkaS7QUO7MgbJCae3i7MmQkQwJ5sKAZhDkkMO+PjAt7C wgf6ZVxiyT2T22CokA+g8B6vI0K6/msB6/Qsz+F4Dnch23J1IdqinIWhomV+hmQ9bre/uE4Cnnnh k3N8KLOPCQhz8vHj7BsD8gdUVV2VfsKZDXD0NAzrBG3ZLtBqquRzw9yFXizG9P43DmQ+N8D4Gjwx gxXFszMDCG/9/L59+935+7B7YYzXBVdzK3Gds2GtxFcatsFsGKlOibGisjAYmQw9kTN4gnvo8xm4 HV7MT4Ukm/38AfP+AwLTQyymHPUOUjhbKT+0huR3HjRkOSZZ35NY4nzlwyaaNmlIgSN9RuYx6U/T xjIrZqpOV4rxZJ8dTDxQ9UV8vra5S6TetkXmAq2zVfVQNr8StgZSRcguHX5in4aHMhp5g421+eeH 0YTfFcY8nObJPaI/sB9+4Ev9PLU5MqvvQ1LoG5kFkVzAy7le+NSFPrxcDKKyykwe4rfeB8TyDI8W X9qp4YMFq6ws+aq7fz59+AH37pDrFLg8b7VWipRq3X1qVW2qZ/AxkNjIB1QFjr5yCIuPnJJm8I/b 6AEEMyyVaBgz6Sk7AAxQT+IDgPR7X9R1/p9rOwjVfOA18sF27xvGfXuoGJakr4loWNMIJ5in6r2e r0P84T50KsydoC/a1AjtjwE+gfiJ+fj4AjNu6qSRZkZFQ5Nec6zz00kE/jmGNdPKkn9TfcYJtXIs t/do4nV1zcSNGFx07IhARoDZ8yGeNxXaYkbnLFeKGwSIBiZAUqxQGp3yYsOtzGdg2Q7QTK9qXUZV a/DpNDDsrIwODW28DajBNGQ2gYT3vHYuA7/j/kANcu2LYsZgZMMqoKBr1ysJkl1+yTa/rIwLlWbY 0Wk19bcNN624Pi/sYFPnqqGs2YLKDBm91cbeAB9BAHz/AIBgEDBSPPQq9umparrcuB5t2PzhrAvX Yhn+/AGa4Q7IMOBh8YJljbe2o8xZvJoq+s3nhCSb+gn/AGPoL8f63WBIcGO2GrN1DmIySxmFsTgq hw9Th4tYWFKsaYwB1vuQyp7g4YkCFlhA6yTV7QswZ3R2Tf8A79wFBAP3S3CLgkmZ30V4ESWUbv8A zC+mgdJZo4skDSKH2sxajcFihoNi9OsyxSJXts2rXfN0eKHzzz1pQyCW0VncFXi9K9OHq5MWjp7M 3CejsRhpu5eTZTgnskyZT7JcFf1ZXJC0DyqhE1lXKPLzsnucAAPv2G/7/MXJyzTclZ0BtqsbYQuE Ns2p6Oh2eWuCkbaU/i2Qnvi3cHAw4+t3h8Xz1O3AsrO1s2x7HaX6oPn/AN/W2+WQBB8RnuFxpKRW 40QvmD5D5hQ8JAxWRwhVWYhQzHJHiewAZ3J0bi/gzeO+ef8AAb+f6MTC2ya3LQMVJKDv92X7c3cK 0bCsIeWW00ow7CtfMQ3BwcK3YJlOnh9LeM7X8GZtl4ThwHf0E+fPgOjcvuBHV44V8F5d3DLGyBgg 54vkWQP2egZrWR43y1LY1kLjf85pYyIul7h5I589LyoNbeqdJrC5NHFI0mOo0PcmNJV+0uxiLiTw s1oB7hMfbIm2Pdbitza2Halq4h4DCaEU5zVwMLz1gqI8AxP4YnrpumWy2C0GEiwWSSen6UUm+dQF /LdPu61FKab020C5AxagdPfU9g7Vnk+AEMDCauhrKzvZtJ39B/r4/v8A1Uu/JGoy1CCrZb4GGgWi vglTx87UUj/MQxdhAk5b+JW6G+TENxW1WB8Cq+dcnF4DN7B7Hv8AsAD260z5FF5XD56kkuteq/bZ IV1UDW7Y4npS9qMQ2T5kzUhdlwfzhzAhZZwxWZNo4yjfdkjYAADfv38+tFSNY5EO3uWzs/dnJ2Fn mm4q8hguBqmNnpsTb7OsvKLMsG2aSQIDcQdQO3bkVHFk5hSvbWXTgqO2I9crcOKBJKKeUrxSpyON rGyYjhzKvbalLezzE/TfMtRhcHgDo/8AndzSZPc3nsl/X3gEHwCD1MWQHjlBeSru7Ut39AfBruYr 12Hy+eWgjgVdkX1vjafMMkMLGn7DOcSfi3lmR7Rxw2DtEAt1BAeASV0WBDnqYeuU2nv8FoW34sQh 2cYSEM8Ud7Gpt94fDmae7Th8ENwKPnzpbNyfF5ZfuwRHAb+AX+QY7+bx9Tbo5L7gkBqx035wan9S FmyFugUehluWUiWM0J7hDcFuHT8OwHyuXzTfscPxbQU90qrrseEE/j/sEAg1htyISuac5NeISitc c5ZWfkVj83xHcSqVd8aKkmixEe3DLI9CrwzUVYyJuxdAkp+HdjGj2EBv3UIyf4QGSWq5UJK5ZPuT siLuSk2C+PD0nty3ObR/mCbM+Ifg9kN9ovsADgIDYEPRbRcjvV9faZFfVc2p1QJMZscAL5HXq3uS pWwXY4dgW4bhqcezC+YgqXEoKe87XzkmDCVcko+wAD4DwD90apcywLAX7ajZVD6kANyaewlDODg4 L93UOrgUjRvXKfX5hkxZA7gQXP8A1Iad5sxZZu6CysHLRN/7+P8A9/YGTVbAPYzmrTsjqudqlqpV 1IKbAnmKXtiYmyl3mVb2i+MlqU/T4fjYOyq/n0etvKy+f3s3+/gD/gMcerf6eW1aCH+76mHVaeFV qOLViVIuwWa2N0M3ncsDsqyxFeNFp5ZN2IxTMZO/UQHHFncqfdbEDE4i+WB6pmDv1HDD9RWaZtR2 fEevKuYXi2mpXXlur3J3i2M+L+nsx2rD7etwXxPbZzgzPPF0ZZB/i7z79bvPkEB1blBda5DItKPG RLtmRRVMMamj29qPgzXz0uEV+coTjDe73xUYT8/K1z4QQkysrMvn1C/SFOAzSRsOB3HFBAL59NAj AOBUYetGOpZNnSs6UWT3b5DDiBTdQgH4jAZW5i2thx61O5ghbwsrPa953yrnZJBgLdQT/Pum+jLF qBhdBFNQRKPVaadQUifXt5GRDi0HnfT6Bb8FDTe4S6Uqwc4YUvPUq4iMxNDWMFlIBmziPivv/H8X 0DhgeoVsXMauezUMZtuJtssIQDp4nSaWeQYm5IlTZsZhtxcV6ftcPmUptGlkyRp6Mok9SVZYoljf CmjlYBvKt2MDXy6L8zJ4fU7KgEiVkHnZkYa/tSvbAUzEuU7ngN8MGEPWAhocNgp85AcIHG+DK6uT Wt7SaueP+/n35gPz1BrUNjhp+odNSacJIYhkr1H1FJ7O2OAF8LRQNbjrUZGRkrdkr6Y1VLV98bOU JvlXVozHPNnPoPgN/Pn38jvlN2MLPoZS4Dbtq0D3JLDuGTcEszKV9Qp5otS8LIT5gfeF9wnf+oek JizwOrxnauru6JzYF9B8+/dAbQrw1LUoYTW1PJAZUNtrKv1Ua0S63PSpco9WxCJNhuEPj63ghuEB VmDCgsWs2YD8ID8//kAfsIrKrTTOe85zMf8AFRXt/VWebPnxx1A7SOqEIUOzBErpntRrlQBtcvPP C/H46FSFqXZPrPOSM0CbfK1DkogdJSa/pyZV4HT3KsaYAtSyO1a24D0NVPD3w4+cZpxXJ2Zzbwf/ AIFsHU8t5bRAYIZ60ANpTFymUm+a3mpNPqYfvcvSrkrcehh0NkuCyCHautKPPHHDjNNlPvDsD4Py ABUSD3dP+/ZltlPqRzHUZXw2T/ObsrmFrURWW11M7q6uZIIdkB4YeYwbG22BsdVrNmbWTKA3bzmH n9gxx2DsdZCnfCG+Cs0C7Eh42LUxh2VR8uWeTSwAXahAw+J7jDDuC3BgL8DGYs9m1fjJw3gbB/fj 6Dz4B0KhQyMomil+dQDt6hvaQzSd2cnJDviMuO0dX7M2llSRxjlG5E2BuxTWlZ1yaN0PFc/B63aF jKdemZ6ToVqWpVrATpHqUPV4kP8AKti0K52+yO9lkVsnuEz4GwfMrS8mnc2bZAmxgEH/ACYN/wAY 4eHrNXMae6Cv0abGpr4/qdoMd5WwpvmIynAPMOSQw6GH29kd5458p1PJoxQWLJo/CTd4VCfAfQQH UbDbcVwYBzVJDSd0AxpZA8YcC1kSuWafTxhPLh1uGHhp/FYCeB+Y87WLJk/u2+IOwf38/wBNqzFN 4codez812JWcxu0aXX8OZIlh022q9q9DW098quGYmVuvmGo8ngWrc3lXKcZ5sbCbA/8Ad33QX8Af jNPDJErFF0yRSMZS9auJ4ojFEVOJ+ojb6hjNHcX8aAscrUwsc2YvbmXBWY+yeNwM0d+NmsRRxlys 8DHnfX0O2L3um5zzHMUrmioYRheNQlnK8QxUrQ702muHbcPqoMUOnkEOxu+F007xmzHwWsPIT/Sv wADA/sHQQHzKzssXcEqtMk2BrRwJWEHzrODqbIrlPlVKyr+8UPdkx8T5jVUie2waG/iFKNBNZOJJ u7LU7RH7dPn6D3/oPqej3yLbB5Sl5xK2jyS23GQZHyt15k55XospDH7P/Jw2CGc89AWxjNugsYcC b0DP7BhsD959kD4bbXMyY5VVeVtJ+aepxhMWFk2RDDuYCZcj5ZA++Phsi2yODG8W2n3T2TWcbQ1G I3Bzf+4H5f8A8qi6jlo1jZncZIEAds/4yOfC1efI54+ehja8/TztDG3djhISua+DeHHPF3fFUQSt VbJtcBOanPWfp5pg56mhri56XbT85Z7tn4Zh6cV9bpNzpmmpkgZo+xpJSQ+hPWuZgtf2dihYQxub JwmGS+daazTbTsGukoecueqK/l1sCykOKuXox59Bz4AbOly38CNrJXzlrONHqUWwr3BT60aD3phZ mzLnrVlkOBQFZPBjs63jSxULKE0LMn9n7khPHvf6pc25FtiLPNDrH9RIOMIeOP8AiQPFDxtfv/x+ 6I2Sm4cCm7UuSjPjdqnDVpZqPW4FgYZloVLETVdPIOFbsjJcENwfAZ7iU4M8rHjFnm/+/j4DYD/d 3rjp/Vo8AV9wlVU4Eraba9Umyt3B8V1NPFLH8FtoB6f4HMW2RPq/GcBsACbWidZq5RmGPGyGznPj +wAN/QT/AGIalV8VstRSqDONhyiSDLMFeslkL0yr3yWrtHb/AJ4YfDCevmFVS4HVaezDBTQsozwE dTaOAqK3V/B+fgFRL+5LYENXywwuzKrSaBK3NW8tHyjzR3IKNEs9p9fE+q3wwhrX2Q4B1IQGpkwe Xyhyay8UmEq33+/fiLrnavSx6vRrFKJp0imik1Kx8R6qNbKwzpz2bgSZe41PDG9HCjrj1DxSvJF6 c0kMkKTDmSDcwBkiNCpBiCrfH/fpe2BbDQ+NCG+T6lGpOVTLb2nmEqnicDV2FNlbeYcK31CODHcE OdbVP21iyf8AqgFE2b7sbwYPAIPsffj+6vLEIXcLtmAxu2/Hsl/LVwkw6PiGMe7D4Mhp8xbqvZ/D zkPgcEwsrCG0LJMGk/RwADn2B/z/AE4KrF3gkVZDM3mYCZ1BanDZa6EMxV8uHUoGzSjQ4D4eMznk z+eUuBwLUt9GKK/sjhNk8A/IL8g/YOoxgIA1ePXtjIeyE3ya7cwJTE9SDgUOwhb4n4MjJM44HImA ajb4FqMExe1k1kHV+yAwB/EB/kf6ILcSiMI+oEJqSJ845NkjtjOK5O2fYlc0eeOaAxdpZw7abeXe BTCQb3KbaZNuVttn3JVr+evtqaalNIaIcBCPNtzZoH4mn8a7SKnZEMXbB4WtsBgxVbIybhNVR9wA XmYzLL4rk98djYRH3/YD4Df+qu5jIhJsOZPihySTF+NEMc2HpCHFfIjQAmEFuZ3UqvcODn6/5wh8 F5QzLIMI7pO//wBA8B8+aq9gOtoVfcAe+Hx/hoTtZHKNNMyRd3yqHiXI5PieYQ7UfGQPADgwDhPa v6oKExm9pBvf/wBgwP8An+2RWYeuVuHlWqyEq97YqV3MAExjEfH0XfO1mGBbZE+HD7fwzk4eeVbI ZifPCbNj+Lu7r8g4gPc/sDjKMVSUp2WyQZ5YxviFaePEfyY9gy4CPyb6DaVHkMIdEO3TOlf3iKWO ZaFnLbiEZPIv6j4w72FYlqNFS2DLSCj5UqGezlIvH1OAVezZkWxhPcaYnslqVXMQzA+1AYFwqU5L /F/aBnRwgTg78AQvoJ8+AxD7ouSGuauObhrmZD6QyG7CMMjVYHPKbq++dPoyG3p7IyOFVrjAtnG3 geExmGXIr1mT72uwR4PH+An/AD4AAW1dqy0mVPVVs1nYCNK1MXmGoxqEaaq4zYTEm1NSVnknM9Of QlVw5502PPejMHwkiyGu0Kz9Jz1hDCTiBNA1vMw9Prw/bpW9PuSvXrHETyUMC+Wgw4mGrUBZtj2g m2FSItlT0/eL4DzHANOgOCGdrd5t9pfFms/ChNg8+wbB4BUTLJbRxumX08McxX02ouGaPxuVYLCx Vryb4OVXWwWSZCd10RqB3KpSaNY4Gmo3fhas7tP7ACpum3yAUA04NM6hHZeR0kw0YbXbS+m3cYYD Fq2Rw9kYDFcz2CAqp4wX9GZtkSbRxAeA8+Aw6jbYOAxd2NVS03nXY+MbU/wx43JkVkYqUDqEpGxq 3YIbgnvidC42DqVw7jF2ZZ9u2e+f38AeX/PgEGST0+OZ0Z1jXwZDf3yUkjojwezg6nW9XxV6U0OM 9PMQ7shrbA+79aGHD+xqG+cmSDYRJqtBfj6CAPgEI+fakxbvy31OyHK0Jlfu1g0bSdI3RDarAiB6 QlacE2pTBC1JgeGHT1/g8BfunuqTWWhX5MDtIJjwHHYH7YD+wFGZI43lkffdppLDLjG1FAMwp3DV 8bcsfzllxiuTCUwIIn9IqGKDcA0kZ70YdtVkKPN3445rGjsAtNzM6BaBgI1JsONLq8PnXR8Mmr0i ecjFXw7gmMiIHX7JvB8wbQcPbEMWs2Yj2iku4M+AP+ft3YOrKg9OesDTzXkOr2KlDVZKWsZbrIxM T6mU+UWNYUWuLIHmE9kmslkWAZn0PYAA7cAzbBbyTBmzfsAQT5+ouP7AfqwRM6w3Z8zq60y2SNtR j0r05a7hScwzp8p+LyKnJfP4Le93At2qnsmD5AIU84vKxhg8Yg3bELx/2Xz9vHwHRJRdqQ21X706 vtVG8ZtY05Q1Xja3jsL5ckq7leuWQddtVoa38O0A7UBsCA1GMHkV3M5yECOwP9PAAMEHojLP2vgj bTqVWstQI15SOA8Y42c2o2ce0Y8gqwqmAd1yoFlEXfHwsqHcilr1AyAqRQjLEHIKgrWYtgwmLdI2 qk1+Gn2RaRZHJzHDgdXypepZXhuEwwnmO5K8tnKH4HBT1lmVqbWWZ4q43qHOb/UR/E+wcB6fGW0X BKB39WlaAVIPlHn9eYAK2nxLJKC7uA/MT0+q6fh1XqE3iEBT4Hwydv1fh94/F2CCA2AAAQPbqSjk FcoprZmLnVtZNg2dHs0xalYmWyt4tiiQJRbcK3WtPdwPkwc+Az3dqd+X1cWjIxzzdVvwD6Dv4B+Q ZhTeNQBm2KxKaeD2pBw1Sra2JRwOdHU5kpolOVc/cHxDcA9qfMBcfrT6ys8XebM9jaT58B4A+g8+ BoxqjmpR0DxSbaajEJIkscryO20bSTbVWfEbNWRJlSvaQxqVdkRo6yVI8R3VV9x/H/c/nqNkMFfp FR0/XL5W9tJNtVLhcVPtUJX+Y5Hl60HxPX+BmFuY4D+8SH/IzBgxoFvOx737/QUHYPPgIDNOalIF qZ2bTb3aIeAyLctfdrIR4kOpQMRNPQyDgtrnGw7At/AXp86GzbW0LKMctE3sewex8/sGIBz23adm PYvkVlWpZD3rCzvitNhuAYTWwquWFOrrFwEwxCeyUkn4bDQBDFlG1o02j+uynMcd/fgOIDFgALdT oNksFlyQM+YEodtyQdhR69PPBYxzJhPSjA9kW4eGzMGxnl9tBmRiML3NmeMTbs8b/wCAP+f6kOl0 2mjG7NqZNx5XDa+YNIMpmlKI+IuOLdEca0NuFIUtiufV6k6mWbKKKCDFIlZIY9uPmOKQEJkcaMmN WbAu+aCrh41euD5mzZw0wLT6uEp621B7YWxYuIhK7IwclcGRDDj/AJ2JA9BsgmT5Rtm9pJt4/Lr8 Aw58f6ZCVWbxUFiJ7G5IalnVLkm7YITbmsCG+AamLCzwdgT94re7FseHrmtB6F72YMV2gYM5s7Gz iCAXwDBv4BfPxrYPMAUcbFrRDW9PZlktGWGPTKvE0/jci9ckVPcEJwMcwZGAP89fnqsMn+G+S8J5 s8HwCCffsAGPUk2MludklV8fCUkxVSrJpwOqjSC9zKKJVuSMAdkZafmrY8wqgeeA3Dk74rrOxpJu k/7B+ngG66DFJYUkvPGEsk0um1C7nhoVifvojuVm/wANEWelaTUM8gkMMcTxxu6E/wAHATITihY4 GJ+O8Ub6XqO6A4CnkxWNPG3YZSTfKK3ANCnfB4DE5Q+DzD5ZFbmE8eng9PCf7Mm5tFXPKycSbs3x BxAb/sADoqKVPX5Q5DXANnJN/I7UD7b/AOCn0jVYt8LCyuoVfmzDFkQ3DGn4KkwPlHrZN5oe+Fl5 Bm9kObA++A+/dJ+s4an8cDm02kuwfVdMsiVHDZVgU6HPUO8FUMw4vmJin3DugYwn4Hq4DrBOz0Nm R8UnHtXivoJ5f2D9eqw9QWXrRXdLWnBI0j5AmtdJGHptiwl+AxJ4sTqCVYbev4XZY9jWnb5+FghL 8EJDaFrEbcH/ADJfqOHfZgYsV70+heXhaTGQFBWNZbUOGnW8QMu9tokjj35UfGPLGBNCVqruyK5S GMBdx3YVlha0KHLHnqUtCt0eVU9VvkCYyXBppSYtIh7mDq6RMq89LQ2hwX7UvihltPsget4vg/g9 V2+TV3xZsw53SN8+3/H9EHn0kwC6Pv23MkXRlhEq9rTmyn2xW5CQtprRw2+Idf1UYcKTT7U7qdlV 8DaiGjI2NyE7yRwgT6CfP93QD90X6jyi+GqLUhEi6e6L01JOq5bhvAdWklpli2Ok1yrsY9Ph6fET /lnrVcUPiicQeRiuh0+LNmbsSnjHgC+/AcAADr7mXYPlWZMsvWRk2RYbvDdq9V7O00vFYp6a+ahA ItbcGSGGuAOHT1tVUgAKdDqD8Dk98Nmwm/gAAAAg7A/HwaSXseOXU2UWPk72n1Mg4jWfT9ni3KHd OIL8G6EfaEjrggTMkAy7ckTsVEkccmL3XZk2IvgYiup3LsjLaIc2pc2yLjT5+kUbcaBT9hPDFSfD RIGmr4cGOq4bJZFV8wgtq+h1y+cZfcBay7hAnugsCDUXAdgfuq1ArUOWWj0+LPIY24MpDbacq/Uj Z1sQ8D2n2Imxe+C3VWL4Y5BMtRDsGf8AM3N80l6eifCau7Vc+Qd/t0/9BY7Tq0F0PWGbQdcVwbrG qhl11Rq3JWbW9T9+GikbuTrIXnGHRCe+uB9bVnysB7UGxeUL2GnMO12OKCwYY4797RzA8IbbZle6 QaHhqLJeenvsM4WRedLO8toVtR7lvDhD5ghoe4J6OBX/AMqLK0UaGYYc/h4ScD6EAAcBPn9/gCRS osmncTFJJImPsMcW2J2ievUCh4y3C0WU83wSF3iMoe4g8ccilauSW9pSb4ywfmvPxzRfFyJafbVP rdfSq+Nh4gck7h1RwaBMwWr0irnnAeYQzFD3YyJ63O4fq0BvhOzBbReSyD2Q3hsC/wABqLf+qozK 0shIh2Qxttem7CbVRbbHBqA1vLQwLkvVyL+n491E8OPZK5Ar4HBkeSf0b8omwhwAf/sG/gLdZliF MpXMymMDaNJ5RhTsJes6Xx7uhFUwCbdjhfFD0+nzHwf86BR4GcyIvPP97Vd5/wAABAHwHSZQ7caI FgMoaxryCVvFhg6ycALiPw7clNR9tFHxwZE+YyWQHT5kGevodjSyfF+TcHSQiTgAqIAAXwHgMZAN RLIsQR5EbLPKX1EyleULC+B2owJSuGLcqTlyAFTyQRZyDMumKxgJuRiMeI3jzXLDnFshdnjjpzGD FqUjHAhmNPoElK1LaeJdkVuStBsDFLGLJpRwp+rN4TzAcfMOAdQDaccEbi6usjP6JRsX3YMH5A4C fRoNPvjT7aGSr5R5kVbaahkSyLgznCnA4EpXp6pbUsEOtuFV7R8JqukhS1cGHlmaNzZuE73v4B+5 8/IL9sCZQx9oJF5w90h1LcyvMJMNgHkntk4Vyh1keKGB/beHW+pBcX3BqQ0+lniGMsxXKLDzgbw8 /j+vn/d5VGl3RFpewrk16krj73NaTYcgPYVbCTDm5O8Vyb+SLa24Pu3hzlLL7bj3fGC6u/ZHb/V7 wCD59ghj25NaqRxhJPp55b1JeOZ5IhGQpaaeVJEEAaVHiircjoyUSrjlLDpy8tudwCJl9SCMGPbR yrPG15NRSRvacgvFm3cQOkb8ZlViEdstqrewg6qYr8SHApq9Ywvh6fDfNnZCH8gvvkEwzE1coMFg zf8AYAC/v/791x7Qy5Riwt5Gksmr+ANivkw2iwoZQ8v7otj3BwT7Uh1tX62jto+Achs5MXthPHwg Q+g8Bxw3/oE1ENrAh2YBlNFhMtkZRhkXrILzGihn1Xi2xbRVPsCZvFVob4voljNvwHiGzDCnjNk7 o1Xif/ER8ABP9BJCyGhNrf5WzySSvabs12QeT2gTDFi/uQchDrdwZFtb842kN95MTKFCbz5tJ3/2 PgD+wdCI2Rknd5i8qK7ESUD+B7ft55+b6tmbZMZCAR1ShKkGRW9yS/UvHt7Ux7vOV9RqvZj5Xzwk T6HanYPAT4zFW9qLaew4y3Li9jJ9fzE9Dp+H/qNZaeeBoS0M3Tc9kSXYGggEI+AqPwB+YYJgOvtW lzXJPquMh5ucNlr7JM8xFPMMTyHMKgMIi2v4HEO0Lagw1mzUNXWVkHVwQ2cPgH8+AAe5/q3V4ab0 djZHZH5st2plU+EXh6HZ2l9smRSjZKPVXX7JwNwp+tx8wH3APckGe3+WJv8A8+Pvz9wDpV1Wh1/q CsgCZi1vGrdIG1uvcw1USCxhXcq9uSuUOwJhgxvENwQ9hp98eFsXRr5ue+BKSOPHaI/wF+8/0wvA 2cwkQ7+O86RYYYEYWM2yvJq5XGvm+FqrR+kRSJWA/AIAPwPwOrKaV9AtJ6iRV12Kul3FfrXM1E2a Fp6IoK9uamQ/qrIZ6QWIP0+m0apsQ+BJSBpCSYA52BTIAsZTARlthEaTyGWC3s+dUMzLap2gTzYi JQz/ABFb1H/SbBlLfWbbQ7ELjZwQLGh+tlEUsWUq8lSwMaDlJ3oKC8kkUlZCzlZLT61tqjGUBOzq 1FKoM1kAAnCrPHNZGvPPJ8H8dUZbJOPn9/8A86O2Uwhu4uyKlZ8mpc5kPah3en7hcbYLmIuqDT2V iw6vWrsTzEMOQcAfH3y8HyzGYpaFZjO6VopKP7n+7v790wtNa/Qd8SGRtuSybas7WvakZhpekhqu pocq0JZ6m08fMrfkjJDIGK5ss/2dhk0Yo0PSyDNJAQGfwfj+/wCwH+q60+ro9llbafAKeNJZsMld 0h2ya/d4ZSxrYaItkWBMfEQPagchDgvloKSPyZmV1d5t9HwtII8AH4Bv58/gAPz2ZWdoOS/RpRDy X/UsBaqBYbgsOyVaJL7jUNbVXw9ohreBhDX0+xgHaVVMbYrtBMZ5vfAB/wA+A+ggAWGUpHDBq5kC PHg23u+JYpTp2X6bUenqdoLIQY6MYJWSqBNNIktTaSA1WcDcxmwKYgrzIlHbeuzJu1suJit09kfA de6bnGwtnqADaNsNBICrFlsoUrJDimCEN8mJ5iEP2OBYAGCHZhavyYn2u2Q5wHYP38AAKbkujTI7 gz90Zd1rjgGh6oZSRYShp30zPYGTVCHFxgVWn3uhXwt4wwZ6BZQJOp+zMabGvGDrjg84H8GDFgwf 0F9CswfaljSK9QxbKMGu7haImwFZkH2FW6GebHIohj04OYQ94sCtziHxKctkxj5V+BM4E1Du2/7B wE/v/uH6d490JFduyaKJDUlcMdvSF5J5Cs1vgdxgZVq88ZE9btRaX3yxuPtpxb2xoaEZGeTYM3v4 ACAPgOA9FBpoocliWGDcueeGCleHVzySS6ggD+LPJF+7PbsY410DzM1ROrzuONx5B2ooURRqu2cY 4owqKuR8E8XQXsjLujNFjXKVMbQLRZCSWX8TBBeDgQOoUCLD2gtmPhh3AeYBqTAeRg61WYto4yd9 7RwAPz9+wANgf0Ok3+8yrhb+lah1Iwh6ewnMDxcewvmMqke0rhhxBluBPWx9WUfZdwHlWtyZNoV9 PIw5hshx9AfQT/H+jDVowWfpzmW0ByiSRXraHku6PM09vCQn6g4tDVffHb+7K3Mck+yI9aWAAOOD NUCHuYw4btFJBvx8+g/v+wVQOMmvhSltWjxocI1M1pcFXae08Dkr8tPps82U2ecGBkp+1HxPrcfj zxgbeN7Y0Pe2I92G0nDj78f/ANvn7llmnQCFYXhblZL3YF0jY7kqyKBIsjUuBSCTbxaxZXoTFCrE MZg6bEKtW3uT+psvamWM4jc4SSTEsMiMhc/fmW0T7MT7kXKTJQ219Ny7AhjWCkTFXIdsOSvZBBkf WSt8Jg8N4/g9kDCbTV7N2rNpGH//AHz9qEcpajJcFb2WH1ULbraF8aS2ExYVwXB/NK4kCrwyMN8o dPT5jA4b8vnkfkyMVaBn5ROWicfn4AfwAH8fYbONFbu7gSTcq2km5sqtyTvZDhZDhyQDSN86gmhw IOEOq0Mw+MGFxdwLL5JWaM0bmzbIknPAbBsAA/v69rJLIQJlMhuzLtfzbDwbMFuvV/8Ao2zXxDQ+ NuFqLbgtkJn5QgVWyLNltAtGWTmO9+58/wA+5B54ZAs0bl0RnwKMzrnlmVANWtY4nizdjkVyyNdi SN1dzuOqxSI23VmmLJTZeVoZD5+TwSTLkDlK/ZA9NwwieuEpKm8GENPbHBXsa2FdNZB5jjcPT2n1 eG36wB4OYUZhbQTZv2TkH/YOA9agaev20cA5qG7GyTJC+W4BzFkNkwXF54UcCDInokO1A4+Z5D2W 6zZvyYMwSQjsD/7C/AH7ojfK3bN0uWy21kf3YNpiksOlbOr28F7tK5Lya5cfhoa4tviGnh0cCwKU FkZeL8GWQnNjewPx9BQcD/gJ4GnlDymeiz4dXWdXyHGiWABZCBaYUsYTXNjQ2AzDmKEMw4MiOhp/ cUPWbNaHaBG3u7KTB/2DYAB8+pVVI21D+nGzl28NszrhQ+3PayPNLmWHC0AYy+ovxtOj5AVJwLpH +y77jTXQ4FdL05R94C1umdV/MAml20batqwk+t8lXLTALkw88Q+YfcGSqx/3yv7aOIf1dDJvJwIa 3w+/YbAv8+xX4GjzDZQ96Ld/TyQQlarhGiEDJ6MprZ75fKFvZ5hhOZJg+GqodgKVH2pxnlDNwf8A v4DwB9f2E/ZA4n0vQTgyJDu4WjbSlUqlLH2FfCOkGBaakPlyLa8yJ8N8Qoa+YVZ7ApHA/JtRn2be 3arjiDbu/wDH0E+A6orqM1GGIoNDyU2wls9aBgKJsgCk1ekWPF7eygNkOExwDmVswP2Oy08fhVay zC/cn5sJagDwHAfY+fNWklD4ineMxs45LyPW0K4q8X+T/wBOi2YoX3gH2krtd8sCcRwcR7q/wjnp 2UmDXwLJT6mGpkbZEpVsiXp3Q5iOw79K1YJspkHwk/khgwPhtYFP4rDJk1f8vgggQ3j/AP0FAwbV mA5hl0ST1fXBaEM87NsS0GrJHsMz5UQpw9hY7Hp+Hxtg4r/P1ynrKzqMKbmd7o84AYbAgn0HYD6T ZGR81BSOWu9p3ZQzRxtTsBqWqnpzdK5LJsVktB8D8krcywGNh4k8Mgzi6vj2OCf1Bv8AwF+Ae/Sx ZIdqGkPTHqHTeSJLHaZJhaE/Jju7gLTRLRV5hwD8wDmAw8M8AR6Hccxmt8pxjfcUlJeNgfj9un9/ PdHhLqJZJw/9GRV0bpEd52CBEmzRpIrpsWidbJbMNS0l2RI2Ss9yu8dkkePPYxDVllTcfb1dcfaD Q+A73ylx2tFwY5gReqe7O6GFkVL290lxRDB9PmLdkD7Irmen2X3I4yr/AJMB2iEdkbnx9+P8+fuv qWPoPKqu8rz1YXNGhHkOioket6lgS2R8PO4t8cOHp8N8hp9gGPgMClvCMslEOs8KrdglXPB9+/8A c/0gWw4tNDwttspwf7mPODawmLgVXBIQ4vcJNAvn5gW5lwByCGCgL7a8IbyTQ9sRqrChOcL78wPw D9/YBswD0v1LqAzraKDZJKr5jbEMWcNV3eG+Hl+K+Pjgnsdb2R4/524KfJFkYLfbM8I7JP8AT+IA /sB/rK0MepTELtuZt5dvsdOFtdMyjb03xuFITu9mQAQdPE7ws4d7zQqgYxPG8b4YyOkcst3RIVih HJBN9rydKLyzxgDmq9nP7Ux2oSd6fagNTrzJXNjS1eLaY+YtmK3mPlocqtqn7LeITyMV8dQow59J B7+A/QB4ADmKa3hpzod3nuwTnmcEwaGSGHs2ZYwtslFIXzA7IhzE9Ph1yAQICr+6C3n82BHa8LdQ T+wIIDfwF0jBRgY7AhrkaiBpKubC08YWBQ9EU+whhYvTghvhggyd7JjhDwMe2oBE+YTvLgZMl7gw nAfP/wCWOAHIeA9X1eYAocM2SSMGSnBzU+WDWRhyA1PUot8nmFuGt3Zjw+uQNP8Az2TjPA1nY/8A p4ABv/Aej3FEiiQPJtujq0a5I1GiFexd8WceD8c8W0e1W21PJnUO3LFjtyyR8xSou2ThZIaTIGji EDNXs4LbDxTGyx6rGGhkpcE7Cnr/AMx8illcpyBbM8wsgPAh/PYIAPtnwPjIwHib2M/wE/8A5b/G 5lkTHK1KZaCiTGPIaSyKbTNJamCycr6c3cXKmEQ92TGR83BwVa0r98R0Pa1er2as3g1hvngPoO/g OnkPB2e0GHBczXYJnd1ED8wAU/5gsWw1KrzB8MOtlw5j7xUv1Wk1kYU4N7G+1xzz/gMeQdV1Fw6b V6vs4zlXlf2SeslkrLhNhB2JkV9L9hLBRkYA76tl5iePh/AP6ecDLMTFoZNZO44OxzgH9P7/ALA5 gsiyqjojypgqpPV2ASSdvkgkUKF35HSo3+nl000g3EgfMm8K5Xgmm91f7V4N9SR2i/4pbYzq10R1 729qq8n5eq8lQIazflIYloTENgsdwT6rY7IwmA1Ng7cLdmPOHGWbGrsEkHUQAAA/VfPgIdwT2wC+ J+/WQShlE4lLaKBsgg7h00+JTWiGwLcMPjZEMgycS+Aq47YUKM3uk8338Bv4A/v/AESVNflQV7S9 2GbLfBrhfudV1ZVPp1p9fSWQCBiAXKHw98ZA8wwPshqQ3DTS8B1mzUN8ZsQZsGbww4CvgQF+8B66 9TGZaj5R9e2Mr1jonTw1wVdZ1P3xRtD8kPHpcWr09ftRk1OTFuEwYTp7gA42z8nuT9fCHNgt7nwA AAP9L0ciiYq6f3mMvEZ5UiJbci08oZZJZod3HMqQo7e0kjMU3URugEqS7V7MxWJcL8kR3k1RpZ21 rstvOXAhuEewSCquFHBts6fksgmt9nkO4er7QiXyUmcPqsw4Ia2wJ6rqHHz3gOTGPn2ZHNO3gP8A YL9v59+1PmLbk4PlSq9MkmUyHjFngk+PEN9pFzYUOm6T/nK3hmGP3VVJgUZy4Ms0YUGWY8JFopPA QL8APnkAAwH00fT3BDiHtRibYUaZxV/7PLd8csqtNcpdoXIhsDGyVWYEWqwQ523nka1EYn/TOyVc ER0E+g7AfAPz8AbLhRmmsDXa2dM6hFtb1StV+2wkGNK5hsuy+EKhotNoZGE3mC5nuA+2K3OOCOnL PA3vkx1KdXZ4XwCFv6+BX9gNpYmdcdQ7zah0STCtRu5D1SbKbWdKALe8f1ytUkjBURoEhoRqilaj NYqT3XjjwaF2eB0jqrMELQBtVXns52dp+QN3CjclfsJklFGGVbTg4TLsDuCfZFgMiqBHHvhs6xzw YM83diOAxP7AfPn+uM6LmVplkosDJkwyA03Ztfks5gLQ9+r2xkMOQfGTupVa3vEF8T+Kw/q6usjN 79/6Bfj/AOmPWmZR+WGIZ0oW7yT0DO2myDzJxOYhyl5ycltfDuAd8Tw9gTAaGwwHjDgzQ0bYDN75 +/gPf32CHkTBZ63K9PLgBJr0yqrglHJLbREhxRe1yk74fdSG+cwT+Wr75O2wZ9G/zNg/f/582LBS oUHRsAqmz7zW2h4Pv7qI8Y8gknoVijDxGRcNQjiR2ssVjQDNqAF1kOL5vpnVQwFDJRvHi88knHg+ 0tCTVY9I/iMlWFd28MCGHtSn9MQevzE7b0OuU95WbkaKz2M2kuyOA+gr+/8AUYlvAho08OC5mQ36 2mf8UBlzOk4GE7T7MqYUnv7JC0xvkS4HFwnTx4E37rNNqwwliFxxxAAQGOADAAAxVjI203Xy/DKA VW/iVXDVKWHMBx8St4vy9QTQnuExkQw7IYYDEECnVo1BifKEPnKObdgm/vyD/q774Xvw1R5euu0w 9xwNFFBAqHpqv6nD4zTNZTJNYV8BrkM/2PdiHakxjX8AaCv3S0p6yjq5R3rM3gEq8HjjsB7Fgxx6 AywiQFNNaR+quoEGz/HXuTUSQZySFu+RHasVyReCxMlLC31W4aji5O4I4E+67X2ZVQHfkRa1z55U uYBn+1dGKThiBckltL2AtjWCvU8o5CYtoGF4PVacYT7UX4bwevCfOmDPdXJvOyJJsGg9on5+AX51 ZzVJckd8mW1bQoa6vjHUpvBfrGGrxHCua5Xqlq/bzAcOyU+XHw2oCwPirDeXlDKec82cPgH4/sH0 DrSjxw9GWjTLlm5zahxckHqEM1JDX5a2hAZaa0Ia+nh1sOY7XzJ1tJ75OW7yrNXV9zqvsm7A0E+A t1A3/f8ApwPFN2QmvF5BWhbG1KmHkAqrvle1/YRg9/XnHvhp+EMz8w42sEBVZHlmF8mJ+ENnLdYD +G/7B1FRWnzZtyHZCxiaWvTnI3kU4Hztx2f0BQ6hZo42TB4nE0rFWFYyLt7bjzeFtY4vIWRXSBF3 ADn3RUpqgg8avSbIt1kYpk9GXq3fD0TUvXMz4fbd8MUmPMcuH2XagcZwNXJ4A975w/cffvvwDob0 92Q0Pl4LeaBoG9XDUjMdrC0/5NM0uvTNPoF3POcMhMuBPZLUmOEwHS1X1ps/fLFX1M6enjB28/v/ AIACA2BkNhRkrlPtrZrgW4R6Z/DLqQqV2q9IrdXPd7uXuD44Vun3xCIOEFSYJ6OYRbMaFf8AKf8A fwGL9jsHAT8CltD4UtyZqlqVwvUwxh0iwrQtQOHbDFjPhZ7irbBMmGGRwmXAh2MQr/Y8eMtHGd8x pQJ4AAv7+/bB1nMG5FGGLl5EMKTZYfU4yum1NIA2G7GIpUanw3HSm9zNBVZyt27PLKY1AWOF1heW NkW2/wCW6sLF2psY0bcUFnUS0513Q7WtrTgrvCTfLgitSlqhvjUJUF0Kr6CAqOZcIZpE0XeKwkN2 Vhd86zCAex80fMYnYTPhlDzE1y8cGctnXlV611CsyezNQHR0p6g5kqwrXyW9zFBayuyeNc/Rarrm m1tmfDA5uIFjeR/jxjkcpILf4jYtn15+9cfDMbvXIkZ0Y06gADVTACgBxwBh/wDrn/f8cwtqQabR wgg8j8HssXX681+fx07Fe1KTtBLMEKvPah6ZytN9tO+oBkDuGnBb1GVzTj2+TKfT8XCq0Kq+2+/E EOq1soTFvmqsmcq4JwhgAH0E/wA+39BsW2WxIp+zLCF1VbUmk0hkUkgfMZK/sO7bQi3GBih6vp98 vitgxghDVQNf2WqzFkm0Vf2zeLRCBKrfn6oX76DsGCxHyMyqhjU0TySTVavWAReX2RqV69h6gqvS LGtBbtBwrdbh1XMIMiO+af8AUtxtmxF2gss3a5JNnP3/AGBBAYr7IqdL1MT4afo8u52QLId3C7Cy O4zB5YOdtCnNRgHCv94W32biwfBgV++KrIs1mrtGnqzP7Fz/AGBBfufY9NEWDf3iRGQamN43QRDZ 87RYRxRgxw92UjEmmFKKNqV5CjtE+DrplUIYRLu+pBFSsdPPjIN3JI6XcIIy7bClfJCu7i+ZWDWM a1LLJEi1gXYn5DYYTQOJRomDvmY1vVZghDBqRHlS34u0GZG9zeGJ8+A3/f8ApwA8yl4qfqoozVeS bTxnm1sL+ntJDiQ9cnl4o5THCGYW9nDsC3BUvOVWL5RuYztdsmwfv+/8BwrqcOQ7GpevWhcdqlAn gQRhq9kp94lsiuepx8PKDhScSt4czh62cqXlsFOZfxezMxwJ+wPwDYH7kD91PbhHDV3cEANZz/ny mqri1kVXXshTuCxld3ixQ46H2fW3AOPMQYE9tVXCzBn5yRtkq524/wC58/h58AmHTqY63Js/qZGV 9z2SQytFJEyle+NqRnFplwPtsvfUsoYlEXchVnhQY3HKfScvzd09DHjnnqBr+jnjUOwp+n0XkIDg GZBrxZBi1LobPlRV5XtBPHp5hwMw7TT+6kDnhzjIyrxfbP8ArbYNgfj6D0mWBTvS0EusRll2p3gS ElbU2CsWQwWh2NaC80K8MhMDh/vg/nDan0thW9mbpgjEzgPznAffz/TrZNKi3d0xDtXTQn2QHFp9 J2E4WokkCxgCed5QGGwTLsQ08PiQ9qzT60nB0YYr85Z/Nu2B/gIDwHn2HIfJjk4AbBnuwRklDWRI rbhRCvJlcgWHSqLT18PM42tmXBkalK0OKzHknzzkyOEScAe/nz/AT/T0eWTb1CMjoEldXd9qePHa sDT0+efH9VccR7suMbLGd3M4THCuBJBqaBB/wZbX/bc/ddB+Y0HbBKU/PgadPmBVvS7Ep9br1fSN qV0hETYTA+U/dkxDWx/zrLT/AJz4MsxoaBn3bm2B/wDYP1AdbbIeKrq+0NLs/S+72QefDCkWj2pe VkRLIx0+qd8Sg6eYhmK3TzHzFX+RVUNmRimCys+E8Bv/AD4+e2Dpho9kGLBhodN1ynyVuVUtkXHZ BJw3YxSMqImyuPsggwhsnIFt4n8tOMhNH9uTA97dgewIOGAAAwH8a6smFXtDASqqVYSSNaPjO7wH iOHw5QFIaJRggyOC3DhzF8xYz44NrXthQZtmx/d+en+ffv4DqEYkiZLh0qRrJz78vafHaBgb93n9 dNkXMqsJymneR4z42628hXORNija1V1+LIr7RZjuDA2W5XN2fqC8luwl9wsJwr292jabGtBPq/vx W5hDrdghzkNPfJzJWVGtFoLKzR3Nt8X35BfgH9/UhyOyGWgDVRREGuFqzG1TaSVSp69DsYCJlAQ/ JOH2Qnp497sayl/GnXyshgvtmT3t2d0f2P8AnwABBPzy3VchyHp/PLOlPjbkoAlGziTRL37ESBQz HGzPdSGhkA848vqWzo3A8Rmx/wClfPtgQefdKpwp4HTbpnGf8ZtG0PWNOWw8JNPh+eK9jKdjckX+ SOFV2QYIB+5Y89+rMLQxjNVZv+gefILB+/n1LExjZrhEhdpY0h8GTsVGZr/oxrGg47zZtfHRSSqW 7O9B7X8ZeL7ear/U/wDnqwDIQbKgzMkXcirZFeiyf4v+WrxDAEW2WgVDkOYWpDmri+YR1K8KH5h5 Rosz8XY9q7dQX79/38+NR7oj1AQMGcow7KrdZFbie7Q0ww1XaAteTbGW1+t1u+JlPsjBMOVLX0+c YGeK84kpLscAP+D8ggD/AESKdmNlQTIYuVcBJ200niQlHA2E0XE4OdXidRjkhj1u+HCk2R8X0M5U pDuoYZyf3mjTqT4M+AxxAc+38+scyt6jXOYYZVP1dksaStxGjOs4OkBxcX7QHsB8UDCeYQx8OCeX 31Hrf752y3wI7ffgADgJ8AwIJ90kkQiDMXj2k09SZ7u8J/prngkUCRMt/vRIJq20ydcl6oaaeaeL RQRJLqZNSY1hG1DGzxQvIiyb0qRvngwUtLHt9xG5dBnLbQHM2Bqust31LpNkWrnP4mwEmHZAh8A2 gkAabZB9JoSFT4cwPWwbbaF0wnCzN0q9ZeXirjiT/X3/AOmlkMA9Xw+k6Rt/Jq6uLehskut945DT 9XptxvkV8sD5lkTWWt8WM42kOK7YMF85Jgzbsb9n5BP+f6GwH8Peayw7Qo0bW+JSsdPC9qwA21YC QHAFFP4odf8A2fZ6fT+5dgXxY0wpWSGriyZz32M/v4AB1iPT4cNp/wBJeoIzXqkqaRtStkcgD0nb DYY1Ld2LuF1vYH5IuzTehr8M4B55XKfzmr1es3o4ECG/PsGwb+g1FhkWWDYTVxy7aTlpoAdPtyTY 6YZwvozLuS39MtRyGHc3Di3pm3vptSsr6QxoZosYpdueKZFwrBllhaSN8+6wrdmPk302mRosTQ9D 1IaLaWA1LYbbdkanEdqs4ewp9ocsKRZnG7UD7xD4HBUhz4qhyayrUPZgzZKTNmz78gW6A8AA6ajR X8xoeFuuWlVXE+y6HSbusi1E+p0iq+42nur3xwYGRkT2RPWyDgDbU9DgzEYYhi+cvDt2u38/9fP9 U/MR2RtzDttJC3JAwK9kpEcw7J5bhsViV1eGPren0Nkhh2AxVfMICNMJjGl8/ZDZsG/e58+Aw+vm 0PsmruCqBSGS0q3SD1SrxAESX2wyftC7tVVNGN4fDDg4TfB8wso5DrMYUq9mWeE7IcAbB+h/z+vb UNIYlSHy0gRP5JIYtNGznkVnVgc4C1trvpCSMSSxuqC+BUa90acDnbkVHs+ccaF2CRbzBalMrGK7 3Abr1cG1xMr4lDj8lKPn3z8bdk3FPmfMOT6P7xGCWPKP1+knNgAc+Afv69KI+ZFkGGjh9bpNIraS 20dkmKfLTLkqWZYwGGvhw9kGENwIGJx7lqriMZnwpwbm1XY44gD6Dz4Bv4CxTwQKaLdRFAxSlhVd qhsGZTdhWAHqtXXkMo5RCljQ09cshEuCyDI58ONxA8jp4x5+8jAZs2bB+Ax8BsB+Hjvj5d0O5kOt KTGnhV5DbD1ENTKnxENWixJT4HH2p3ImMncCnoNluGniq+DM1Xoby81UkhOcH0G3QHPgADHpZ/kj kXuSTaxOUqE7lg/xyR3jQPdd3wFo5MjZnWVZDczPnJxWINFRXz7W54/NfmBr+QHrSYHlHluyEMpX rsWXyR5XEh+Glv5NwmJ8yYYh88eHxwPfMJ1BV5Tc6PCJJs4fAP2C/i/AD/XHbCdcjkt0/Q7kSpPO DIg1haA40jXpmK0CXxomL4cwHcHyG4B/n8tVVsmjVeVRhhwIb/YD/wB+wXz4APy70S1xfh83ZDSG m2H29+GBMMMw9KYU1X3AOthw8wwnmEbcFI4uIzy0bm8nHZJ5z/X78/H9/PyRgUjlA9nSmh2STy5n Rngg+KpBhcJLlQ3Mltw/nE9khsAexp6+BR5iysboMGfsZz3YAD9yD9VJFFNqBqJf6ErGNPPqbLQF 8v8A6U8i44/cTfFGNNIujm0kcaCGVEjdUGFxiWKbE+bG5DGwPGIUjnKwHo+n/SfbTZEocoHG5z4t kmEOSzh7vW5Rp36uf6w5JMZXDnAG8KzqtbJjBdX7Z7OxvwCCf+gnz/TORx+k+grgSYrk7f4IYa/t i/amorTPSO1i+0toJ/MFtD4eHT4YN8T3wHMJrNoIjyjWok/+P1FjgfwPr9FXyRQdBXYBPBiT/qcT IenivSGSHV4jIBilpR4O4Q/uBgOvw2rmFaTTCKTF93xiObdquBn/AO/nwHtd6qGAXYNZqoupaxjO 1aNVkbhnWov2bcFyHizmUZHCYHp+4HwOwIbVpaXwPk3kqLWXnvZaITj5/YNgP9outUkjlmRp0kSR I3YRdu3eVLEbbavnI02dLwuPOdI2DA7SZphnFINxO+SGJch2ZVmW+PB/xWKu2YDq88+adTL4qjal pskt0ijvlzSIkOxjynXNjIc9bre1LTMBx8OdZdgbHMJ4FFcYjg+Em9/QQHPj6Dbr8AganqOq9Oep QbSyakktYCuSJWEO09p8e2A/A7NiuVqD1unzETjdgVv2lcHyuXzkxQXtmyYfqf8AP7B0/SOZo5TQ mpRWZ5moayNTWc31lW+muvXFemgU1T9PIwDhgyPTIt4TJsDF8Ic3RmjB6Rt6COqOwYvwDn5/DDqu FuB6fqpLduOgeNmQ7v8Azie4MExoF7WeMMCf8xPhht4eMU9SrkMTWd093jZDewYe337gAC1ZXyoM MXZCxXCQY1yj22N/cKPgc9UI8GgdezTyyZqYprCbwWwRgMqxBBsXbcCubx5cyaUOWFVV+uGnhOt/ n9sdzrgcMWQ9V66e2fjcPTGHmVvPmNTavn+Sc5pu0NzwN72jn/oJ/gPn6dA7MFtsPODJpg2yC3YK JjmM4gkQ7QtCp3KKyXBvFJGE8wQquqzyeeazCyTKFMSZzZDZz3AH/fwPRUDbCESyFWwc2yP8A8Yr dTkKsNoiTGgC2WMBMMIf4bIoJ7BM4iQstH40TF7pvm9mznAT/AUE/h0+GSRdDlUdtO644EklylqV 8h74sIewhxVX2ELcjBC1IdVp9PhyEz5/LQe2VAUocYs/dvAvwB+P9RW2kGIsyOiRoe1Fu8i8tNj5 FDDmjyD5ORUdobWkhhfIg5O2GGOEdLlfN94xoWTfBeY0r6rKC3jTI7h1JqzbUUq9kMiHU7vUFS1K kPjkh2BW9bzS7g4YLc4FqQ+CtlCYvc1nhJsIjnz/AIDf+fdU6oeOHcih5DulqbeBvi07mK9r1flh wMotd+zp8yGt3wHwHuH++E/F5V0Pk2yWi7gwADYAAA+f9uys3Su8oxc10njzJamoKYSYVdPp+pxM zFN+LTdVkK35g4WQyMBi4tPA/TxVb4M+0LPBwiSko58B4DwGHTOjhl93ZK9FpjIOfCkwJLT7OTzI nhsqJY138PZJgcO+Mi/DBnk5SnB9PTNV74875shvn+AD/vwC4zKFCS4F5CGZo02kaQVmyozGOPOx YknXkcFqNAFjJeVGdscVCM2b7fG2ka0t4d2R4skcCuWon2Q0QKvrHKV31tuwpMq5gYbCA4Vk4OVS 6WhdSzCC24VvMT1tgD2NAr+f/Uz4rrOAMIk/ftg/fz/IF6rlBbQ8fKApLJcGa4Ru5FPslbiTCI0F nKUhkE+Ghhw8NxfDgIehvG2ExbQ875zbYwGwYgUHz6Cwlut7AsfT3WLHlU+S7cNVx17V6Tk0fbAa LcbDFsZ9cO6ifdlb8gWwd0/avJi8GdFBm0nwD8AfuA+A6CXSs49fHO32SyDTGVW6AkGKfs5orHng u2EPeCEP4bh8weYrm+F488ODMsq5RY2M5vZw+AAH/oL8f6VDCpd8QibaZ9iEZUVFEqzxH8gxySVZ BA7bce9cz750jdj5qvAybKVvnmSR/NqFtsrFadzEMzcmnuVUr5UrJFbyUSQ1LZivVsoCLHlf+cDh 0+HCITAdtMDaDm4DKvKclR7R2Tz/AOvaI/j1SfMIaf6bsw9VQuZjMulDQL5kWFVYdsDgZUSxgMOw A8OHajJMX2S1J5DTTBWxjMrq6MMtTA2cxAfl1+QQH2C10NkpdjsCww1l3lJJW/D48YqUwrsO142a +PjgQmLYeyON8D4lwIGHRkYpwYYjhEkIj93dg/r7DryStyh81ceDzlZedGW3yvX9tkNUNo/2m5Ab I42HhvhhwITK5nuM9qZEZZfPs3CcP3//AKH8OrgLTtOI80/iXviljzkYNthNxY8kkxYpIt+DaDiw nrTxwsUSRJM8GWWycNstkMOPcAOTxY69adJn/Fc08adE+wU9DfdcNG+k/bjQ7NNcqNe6Nz6YDZi4 dZHfFUDDqrjG0iCHrYVcDZctgj7lnzhU7NzvV6cPX6MnKzqm1hHQtfFRifOY6XQp4gDBzZyt6LTb lBOiyTOdMP8AqL1bKVXWSpOVbN/oK+hzX2pQLHFL0SWEmqrJT1BFeDChZ1nk0muLsU18KIWOKbOl bFbFLlsi6BoGhfHAvhseqxRFwvFFF5eaAF+3pq6eDFi6oNW9tVhquW6kojuFp5lV8BzdOFaQ5Ncq ZM/DIPcSq4YhDPuISprRug3CxZ3xCt8XveOKPvwEDhhifA9cdRlLEzUvT3Uu8XHQNS9/qy1AZ1YM EpbocXXrkmh19PcLhQ7UrceXuLb8YLJue6I2+JIQ3hv79sG/nwHTsh6g6ztpLs6tG3OW6rQ2q2lP UQyZO0uDRTensWhw8GT4dbp8wgHsatGDg4jk2BQmTwNu3+dRcBAb/j0kyhBwV3BVdwOntbGhs5bw sh2VE93MRD1OCnvug4Q0+yENwuAxBgL/ABUwMsy+MVl5B0m7Vd2DAHwFRAD/AOXTePTJIiiOY0jP FptQc9Q+1Dpo2EisDLL7VIzlOGZC+SSK7rxtIXR5cokl1ccku2c88SqQyQRmsWsKq+RZ6gUukz5S s74Ut+fzCa+SbDT2RbHsMOz3KwnKm+YXAhvl2Ib4wTJwEeBVbIZidoPhMmcNhN88/UIA/UT8/dWD stDELldB81ZiYWSMT5VfU/CAu+o6HE1AqTOrqEB8hWPinTIGNPNtYPbsIwZactFGKWoEC0qbYAQD BetzH/lQFXqvIWJftmaj3HNdo1bvcxjYLXJJ2Nsh06W2OStVa/hqErdbiVuRZUiCwIcGYsrNYFRt mA0rVEknD4A+fxfj9u9Kxo1E3IuVtTIuUNoqHbVPrde6Rxteo6nMrm7q9Q1dbTw8OHqEDzLA/o98 nWp+6I3B/Ngz+wH0DYMdgZNxHp5RPCiajUnEM/e2QQGFkobMjEDbmyfCm9Nr4qP05XSSJ89NCrkn tj9IVuLJzuxrlcsWKZAp6grptFHgPX0ebjedY1KHzbI+WPMODA779aAnGKtr5gOHpPh/w+IjwJxw WbMaNzZv87U/f9g/fzyn7czKHaKYv2AeSbClOyS2K+oSYObLUtoCvVzEW/yoH1IfMX98UrAgTvs3 KFkYc7ohNgwfkHE/jz7rsOHEOpRZKh21PoHJlTJKQR0orce7odjFWFDsat94T6Tsit3BPhVy2jx7 UZZkZoKExlVuwS7PvwAAf59j0q4YdLsZwGsbHp7dgK5T9b1lV+dYdgS7gAi6n36YvJ+8akK3hp+A SAPbbUMMxPi4smDNhOcP3AQGIABj0oJ9RYVZiiuyWkX8102meCfM1HJIhfLba9oLXNgmO2UVXhMk iK6szSiOO+HSWKWCPccxs6MquNrMMS2QBG7QzHStCg0Dcl2SZjQkmyysNAtDYtq1SiXyVD2dPqtw pPw9xe6kDcCe18GJnAgTfMd/PgN/Ab+NugcRYxAxQVgtSk7LjgELEKfmRxJhXaF5olB2BbDodqQ4 bAHsZ8cO3NbjBlYFBgtHSd8OH8bd/fz790bKCWwVphMY2Oh0hIsZ8G2a8NUOv75muRQSrvsPtWtL d2IbIvzEdD+ecT+5nPGYn/EO7cH/AH/YN/2BgnGDNd9Pb5LpamVt3zbmuNIr92yU+JDuS0FOrwAf mBgxT9qJzgHncfstUTyaNaDQsowNJ7JgwB8/wE/59+eHwlWJBjhOYS13neNMRQqqPFnz56GONWka yjZJkMGyxww4PA92XB/R454EI+ZV6RS9YZR6yJJltAhC2neGH0/lmRoV4j5FTyEOq0Ot3AxYC3O7 H2ZxsnZivaFG2/wnezh8AwbA+/fgDUT48ygrwW7uKIdtW00OBtejzA9XtYe2nITFTQ7BZEP+TfGC JBQ7gAgw6yMfMLLGWoEtE28AAGAABj7nz4pDzNK8Wq0+AApi/qZTXarl4OyOFfxIdjgVPX0mp7BZ Biq5kMwQD07Ar8CDcO5jQ0MzNgb2TDYEEAgn9/YD6+XxdoLifZCQ4kltVPWcpTKefBqeJMHkOJFl zE+yK3fEOYYYA5w9885MGFN0WSZw4Eq5HQQGL8vr5/f8c7ZzLK5TF2TBnWLZkOQDEo+T1hGsjkUc sAOLsVtRoYUDoqKgjjVHiltxiVUmNzjmbot4xNBuadmoy66Dd74uzKUg9o2Rpo1XNtOID4BeJf8A D4hpGoK2lsgHQ9Zlwe9fQ/r/APODLyxfEbfPNo78fPgEHwGB9GyDjY0avLIvh8o0bpXV0NSXrgM1 6rloiGr4Hk2iK/DQ7Hp9kXE9bB8fPPAd5KfefNpPOV9+AgT+PgMOOG0ZlS13Dt+1Q6iBiob+JHzF sPEZLGKcoKPg9kuBCp+7ENgMHFJfbTaftiuLJjDlXBO6gDj+wb+/P3T+c5ifF0v15V/bG0YZmsac bLYW63IXHW9oIf8ADketRPY0O7Fsun8kriliAEEYrNmfBbMMqs2k4f0Cgn9/AAOij242iiwmk3pI wzZblSCSKR5KoVmYlGN/vI1RYytKLaRBhwmZqkNBUB5vCjZ48jgfKlBi49lg63qrKMbbb4EavL4F VR3et+GiYtjQ8N4fIaeyL7KDrTto1IdZ1mUGdzAeyJO/4AD4A/iAAH+xXkL6ZIZDOnhDq6wl1VW3 cgSr22fPAYhS0JlgB63uDRnQ4cetg6lHUtBrZZGWhcoz+9vG/wDs/H0EB0YOCO4OwMbPq5wZE+yl sa73g1XYvu6eLQ7ZfSj5X9b2R2fD3AP+DP8AnvBhZKNCuTJo7vaIQHsB+ocH4/1I1PDXP4SIbRaC E2VW2LZJrHvc1OVESumiqIwFPgGGW+KHe4Z9asZsnzjnGGa46ceSn6++OGK/gAwfmD1MYMiPPLO0 2cjGOKOHHVq702zGNxqkmk3HUfdyOMLYQp3YooDt5wx7zzygxiAWZLYp2+V+Df6rlfLduVGGjjSm VailktGIRsH2Eqh3eGeV6RxV4fzA4dwMMg/Y7LH2W8B2ZmVyiMzb2bCYH3/YD4B+xx6cEy1Cjuh/ 4SvT6kyWgHZPj3ldi+j4WNV+wi+Ph5i24QzBDEGhsDbBDowxDFsyyD2R2/YNgP8AgOhtTrtbaLEa jTcyWQqlLr03xLQSdnYVsWUpyLaCGQmVW+GHBw4ejT6PPI5hGRrkV2ZZeLRCf7+/YEFg64xZVkaF fJd0NkN0y0WpGlr4epaHYYb4hNhSkbgIB2QPDDmLBZMIDh85bWdr7mebNVccQT+P37pZw74wqM4+ nzRZLkiM2YXcXDt/jYr3U9N4rlibsapOUdImeRBIRcb4YEvC1i5EyoNXp5eGzoI2HUZAyr5OVmgS WdYKTyyQNyQ/+o3xWhbITfmWQyw0/AH4FHZGas2j7OCCbJ+n0Hz/ALnk1bsRoqNbgPmdUqJWieFE yKrWx8RblJve4pMT3AxM09sjeQZHhDYJ7xVayzPmO5gwn3g+A8B9g60mChB3tAPXMWt5Om98PVdE aIedYBaYeKFmiVMIMj4+zTK0vhzkBPbZzITJi0N6WfCBPZ+58g4bAA6nrEugWZsGvMqoNPdXaezK 3UrC0WrXzxYXKQJa5KbcGEPDcFtkZCDhB7XW0c4yTaBb0TRzbtsfAX7+vt/fowYMSRmkFCJNncxj IBWJWzFydpwWvU55XDkYFBGAZU+pdoJ3kbFNtMfWmajUEeR3Y678k71x5UrQQW3yZbUtjuwaenoa TEthwviQ2ODkUa9+Q19bmLbJVcMcyQZ9gKX0blCGzDKruwIEBn/AYYIJ/wBySHSenNcsV2sEFqWJ Idl6eyTDdHbG+F4OUAtkqua3X4ZhkmbOnh/n88gshMYh7nUDw7JPn/v3gP0c1lunf23LC1SngLa+ z743Wr9RQ2n1OyFcC7gYq2QquGHMLcxgDqvH1FVWxm6CxjNve98+APz8A4CfwPocfU+Yrh1Vpn6e yTJAtpA7T0PYVPy8a5PCZUV8TzEPCGZmcw4GQ7VTLMWShSoFk5+UQdRH+Anz/IMOmjcjXcCvHIEY xo6ETrHGUxjEF92ORBbcX4GPQoyyPS2NtEDs026jSc5SO+CbOdDFcXuj3dvNutREyGLsx2cr4tpS zu1cntPMQ9N7ZuiakIbRDr8xW/Z+yIdfvnPGCf3IZhnF2as3h27XWofwt0AAQPvwCt+nNksDSrbk OAx3NJG5VAjROpBwloEuHQ/eOILDD1sPagdkuAeyUDZdwAUd8GDCiHxn/RMG/bD9gw3/AK46vT6b SAV/HqVuCiqTiXA7MNfWEh1eJmK7RU8VXmU8+IQeyFu7F9ktTj885/QaujewQIbR/wAu8+39+QUG XdO39l5Cqpz9K6SZgVvaFrmLsuan7jL2g0MIGIt4mENlWg5gcyBD9IPs5bWXjniMtfdklHPcBPr5 9+xAAKliSVFSR0KDyEOd2EDWe3G42kQVZ7y32U1whoyJIUQuKJLyFNuMY5uBg2dWLHb/AKm66jrg ZB6lYB4C+W02w3xwNiU/+JZHti1HJXsIpbVqML5T74tzDA5kqvtdAVWV5ZqvQ0ZZw3tJB7AfPn37 n3TOV3hPDJxLUEhquktqKDNPCRX7sNR2Ha7apECLQiH8Qm8MjJR4euHxPsyuQ6yzPiGsjLUdtPFo vH6AP9/Hw8oYrOql8O+Rc6nBuU1IEQheWcj1OyNAGnLaKGHCZDTnyG+EG9HQx9aPCG8rP8RlZrOD skm3jYH7gJ/+oAkfDbKpzHZSXHyQBrncncfNJUfLmWNKYZT4HT7sD6teN2oAhnAI+y4LIMrMpVyy jI9XO1oo4AAAP7/+/wAJcqioPYiqT+axAP68Hjni+elIFCu7i0XHI37bPHHzdV/2+enwvhw9QVWN /hy+PYWVnNlxq2TnD2xwVwRapQKenmafcENwshgMA55BtR/vNXq9ZjNkScDngF9BP/Qajre0C7Qb fhWXKAEsZ4eN3AQ69YC0woAXijkHT/sYeHyBkgz6/fAQcZ9oRsN8N/8ATDEAf2AA8dOanXaYUMV8 pE7ISdSLtZDDT4Fwsj5ttSlMDF4/s6fQ+ntbIMk4CwPlcviNjqLFvJM5dnNjh8/UR8+AwPn+kEuO ifFHtQEC7Sluy1tt4O7VK4d4KRA1Pciu+L6f8y1IbIOsgGfTwKoH3MWLszYzfe1Hvw+ggAHAQCC/ RxWTASB2xaNHTDOPwrhsmq+bFGuBZvi1X2ESbema8WxzxrC+LW7sfI4Hzd9EiWUsBIKOytXOd8OB qKq6Yr3nXgd389tbRt6GyB9ncPhtR6wJ+zLLy+K4z25sk7AAAYsGPgD7CqcolLiuqytUum/vwBmV K2VfQ9SoHD4tX2FYwswwOHL3xkcCHgbBUge5/Q3n+idj5B+uwdQLpbDgx6hENjyiRsMZZAneBkGB 5lP7DWVci1tfW+Np9kBuSHLar7s6tvNmY7mMBu2ynH4AvoPPt/A9ZIT1dj3gUUPDOW/JYXlPsKr0 fi/c0ohuLAHhzA5gwQh2MpD+KB1l55QzDPCb5sHtsG/9DGGeOEzLsu6afUlPfjll2ZUl1/ixHz28 dNm21mmWF96p3hjOOG4YggLe5sbzHHdX5qyE/pvKWJYKmt1KeatgXA4SWvnocjjcXTnp7aU1wr9D Q7gsjeCBiCPr88qmCbMUKYoxw2EduAn9/AAN/AAHZHFjuNjSmVZ1gctAqUQfZC3YAmnxcpsiyoY+ HW+GnuZVfJGo9R6kq2R3ftGr/BhEl2w8AggN/PgD6ZtmRXbQYDz4thSVtjSVKInuCTILGFcXXu67 fChw5sPmBg42p++cZ++POxhAlo8B2DBBx/f7UOPyEPR2eVzOCBQJkOpCdTGkVVcF6IetCWLKQ2AM tw63+Gvvhyyx7bPhs3KFcmsgwgT6CAP/AL/hh0yaCdtp4dLCsM8zQkqtSfZvMkv2btx2MTWC8kHp UcscSMjO5miQvKUbDKihUEd9eGo2eSeDfR5orr+9L4YLCzTIcbWKa1EkhorFUz2FPPRbCV9QMMgZ 8wYsghDeG2wHuctrDNQ7S8oyPV3gwADHYD76AAdJ9wU47OQMZp6jQiHcGTwjblu+N4cpUSLSK38O JyRkMJ7JXPMUOAno1Z4i3nY0k3SZwAgn0Hf/AL8g1XT6zF1nmKvcGGbT4thjV6v2TOpct/8Aea0+ lFtfZTCfDW2UgYqs8Q+dMswYhvjyMePuwNBAYgAHgen9Iug2kMfctNGoBjKzgjbX+NV2BbDI5Jol yV7IIJ8NbmUnDHrc5Sq+fOh1AzCijOzHAmN2I/AefbBv4DoYjqYmldVtJnV9O8BzkSAxxROA1LgZ xEhBo0VqjVk3wdVhKvA/OQdfFlCObF+D+KsfnrzA1h3rq3arkzpj2KVqfNxVkDkYV7pFU6Oi1eCj TvTKPer1FVKXYMorXlhE55mcVc0o3jFLwZ03JKTBw3Ex6IEfOvaFV16hkuU5ZogjateZDm4znnMr ahr6ryp6wr/0mxQaONWl5IvJKZ7BHejYhwkznSpk+KHKZhfcl0QICyYcDJzrUo0yKiDTf2lSIijO aXOlVR3ZFjkaN2xNnya6Xvany2r0ztwWdXQKx4JICxKoBrgAAUTx0j2FfXqtrunrfUgQyJYzZkao M+A1evJzPSZTCFM+un3ZfKAiUPNhkGGaZmOBpbYe58qwonprnOyqvWoq3XuX6lr13s0w6eq11Rf8 UzUJp/twGIkI6gw6jUKRJRE2uajOOmQsVdUB4OwuubVKUmhyZ3Ei4TsT8YeFEqrtFgC4L2sM0PLm 5M/Os65esdxHI4dg6pCFcMQwFvwGuwP0DXQxACRaAF6qzXFn8n9/vrzyvhnKaX6t0v2TSPpGKViX F/wvgF82E5zgohyLn23VCzuKxcILNyXmEyCMhCMAFRXFhE7IF5YxSjgB/rWcBcj5WdJt/d2k+kj9 64WvgqRg7A0NLUcPChUUVmKcpg9T3lB5h4euGRheCslCZ+PCsMjnKeALLkOo+Hj6cnLVMv1KuZnW daoif/UylnB9LqQ632uLg4ZfDDk8EEcnrY6I39jSsyqzRzaXbYqC0eWeWBItcqGWNXQvwOqfZyoh tWkt2a8a9TV0kng4rOnYqYzPB5ieZbxgUkX9amVyZuYxLYf1lAogp6FIMahJ2ZOGw8yYvy/RkenL wGq0gt9v/wDEAtWgsy4LlrGs/Tp5q5rnAaWsApWcUy9+hyW3dasAqPB+jALnN9fO5z1tVdkI4mLG UJ4oAOFwctdCwQmXnWdGpO2OTxHKw58MuGLD/MtnE+RZo9YSAPAA4XwK+B1fgOjZmQm/8WDLeXFu uxh0Xy78tehnS8M1dsg8uvsQs5IzUdmjC656UidjZQ9eAlnUflqMQZlMoUQbTISfJGQMI9YdMF/t hmo6jes8MtQzuoFmLKbziI5QIiQUkSxXOlZlfpuQPaI/qUa7L5HrzjJZAEZuSn5xHPzBkQLCTsfQ rejOs6W7u0+pyZmqd6yYmrq6smvA/wCnWuNVWNMVC3d4gC+U8158n/qevxBQhObQFm5/pnHIosCe QJkJZhEvVCXvQ81pZNe1SBtuPGjZWXND2yRVfVn5TY6rxANObsZxEcwZc5cITAWcwUitFlut21Mo n6jXwmTTrZRX1wMTxUlkCCBBUFqo7MFSD8kwR9cNWgl2qYtBDE4sAiFWqXNnCiOK1X2Wm51nTfEU jj3Lhi33LY5o+RdC6PPz1U/8h/2//Drj08V2GubT/dToyyiAj0q4TT1AHJyl6BIJCzo1yKLu9nvQ RWPQKkR5vqA+mcTUFPMzM7D1jVWfh65/qLNYhdaQyTsQzl1ppfTrcEAlsoZd1cA3yFw6Fi56YDLG CVTJhT0gwo7a874BAVYXr9c+AcIG48/OUFCPO9MkTkHxjDnWdU5P0+q5P8x/8gf+Olp7l/2/8J16 drS7AxbLKFBc0ip+iCna+myNmrJObCjeg5WitWTgif8AMuys6cn+tdWHe4XZ5FoXqXMa9yHHPEsG CpjPBCs2NTfPi41T/wAB/SjrNX55whaLw42wWz1phY2AnVKv62jItLJOREWv/QTijlDJn5dcruTn Sg+fkF8YGYbD7nsjAXGy86zpEABkjsX6qHn8i6P+o/PVt7JP3GwP7Bqwf0fkdVcql6MO/qxRhnp9 FaAIFNaVLBXcK1IMAcoqtFyUbW1OXJ6wxs0aYS8hctCvHYmvsSEfmG6/FRoIbBKVlT0j8PTm2cpU PM1FBKJsC5nGyHM1n1/X1lzvTjZDsu+kmyWRDMOLj6yRVSOAGeZlzmlZiHQ8zNP4m0sjKlZyKXWf 8AVgMzrOtOpASKB1AVtpUyXhsHYZJYo4tQyW6ahYNDpOmJMmpsk+t8m/ON+fz89UytHLJrr7bGny OyMefWkbIR5ceD6SOAQ5kyy9QuV7ZEnLaVPIXWHD1hHpRAYjfRiQxyJIUdFFsGUc9MaJnR7o6m9Y lx3jSw+zpfqUa2f7XXrlrV7c6rVYIBxMqanpSwsTCD6XQ162VwgciK6bkcSz+keeixiKyZdwcePB jsXp9UDOs6VIB9XEa5F0fkfxeD8dPj50Oqvmtpx+nUPiw/DLZxbyLNEdJj/hxMbrq10o3ERebEsZ IYtOtbW4IrZrqB6ZUJijxSxChcsjkGZkcjPjlhRYfYrCNalPNiZSRYHpywxixlluZwg09HbGdX8q ihutYnXz87xi2ka1rAyq/IG+HMnpacmY1aZsj/mscMaT5i2fKwO/Tlmg2oQFXXFezBqfgBYh2StQ 8r151nStP36PU59/r/f3ebvzfmhf5rpuoJjnUxkxk3eHb4269tfk9b82dbbDYo/OZ9QluNExqqSq vQwzj2XV86SePRR+ql5HuTNh20y47kzwSxtrh+rMdY7EGLhWsiMYwprKEqHqWrGaSaaVtRGqiw65 sLPlxhKyW01egUXRxKZXzPFFamVRjzGZWgGk9UEZoFIr9cToNfVCjrGUDU0ivirKs7OUjsBLNzs6 zqRABYgAAO7xx8p0pv8AinPycbPyeekJOqZUOimCnSvpmy1OvILq9jf1gZGcXmvgErqAnAjwuKPy FTPUoNhLeMr1Lw1bFQ3CKaJZlnc8MwlkwvQFZUKvjNJGl2ZNanNmL3Doh1328wH2nPVy5wMV0ak7 ISqdX1cj6lXJzBwOOGOZXqIlpmBOwR80LBkpDwnbm15bJnWdaGJyXk8SykfosYsiPwTQs/NC+lx+ 50+xkgDJ9jBdzEMvghbOIIIFmvJ6M12vjmm3UPXUSmrmulJw1FjoHptiSIbx8Gean0eASTK0eDzo QCLKTGNi9fqMjbAOJuaBIuYZsaxhXP8AVHM52Ho/cKp14dqHuNe9JA9NOk9Jz/Zti2UUmxCVhW61 W1odzdUbsQfyUsfmA8onOuBe9RqC1Iq8kvAaAXliRTTEih07BXzrOssYB1IcgF3giLuR3MVyxLN5 Yrk2JJNWaqz04E/T6Hk8GQD9BtnID8BqF15oX46SOqK0PSQS7/PjK3qZS9FIaXdPN8V8IVkiNBiD n6QeupTm4Sy8yWRcJyqXiAs0yypmcz4LDe5MLG7tww62To5iFEUssEa+0Q6V9YCQ7Na5c03UDbq3 kyo+UokFgeNkaIy1zTsrIWDioVHEMkhLnm6+mDT+BkL66wPEFvLF5U7IEmxmdZ1usnT6ZiSWbPJi bZqaKrJ5NWas8Wfz1kcAzoSBZu/37fP56YFZ+gZcFHWtcjGK2tlY3ILRzSPV2F1DhGWn7I0zVhbL bXZT04tEo3krpUk0T1Wd6BJwZOKI8YcDNTikiLiSzFZYzW0riTR9vjWZgz2I5Is2lo4VkMkHlGW1 8ZZRpLAmFlLe5DKBHmF8LDieoYLkRJqH6yeXnFiaWRIESsifnWdZk92m/USgfoApQH4A/HU1juul 1GLMtyMTixFm15NEWf2eeoW4dZ1zhE+6a+F+tUHgytE6fXw9IGANnLHCSAsNqeMDyCAaaP8AUKUi I2yyecWV1jLAiPkCRuQIjiBRNzGNd1aJUIl3UlpjlHzLUuErW0y1Nftjz1JmL5GW4t5DXkCjkxZo CxSWRTkLRGSkqhORG9C/lGsuaEi5UM7FG5kofIzrOsWpJTVRRoSkazR4opKotizSilFnk0Oeugiq wkyUNUMlZAGrVLq78/PVoNEv/Dg08anKU7kv3pYxx30OTMB9OUuwa3zMrNhxcyIU9GcQKttdtjWb m4SjEvIjSDrGTxEA8gOpgfSJUl1eBC86zrOu3HLKFUCSSuPvb8p++uPJHGXclEJLMSSqkk35Jr9D /p1//9k= " - y="0" - x="0" - id="image9" - height="260" - width="260" /> - </pattern> - <linearGradient - id="linearGradient4336"> - <stop - style="stop-color:#ffffff;stop-opacity:0;" - offset="0" - id="stop4338" /> - <stop - id="stop5884" - offset="0.5" - style="stop-color:#ffffff;stop-opacity:0;" /> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="1" - id="stop4340" /> - </linearGradient> - <linearGradient - id="linearGradient4304"> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="0" - id="stop4306" /> - <stop - style="stop-color:#000000;stop-opacity:0.39655173;" - offset="1" - id="stop4308" /> - </linearGradient> - <linearGradient - id="linearGradient4296"> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="0" - id="stop4298" /> - <stop - style="stop-color:#000000;stop-opacity:0.28627452;" - offset="1" - id="stop4300" /> - </linearGradient> - <linearGradient - id="linearGradient4276"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4278" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop4280" /> - </linearGradient> - <linearGradient - id="linearGradient6735" - osb:paint="gradient"> - <stop - style="stop-color:#000000;stop-opacity:0.31764707;" - offset="0" - id="stop6737" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop6739" /> - </linearGradient> - <marker - inkscape:stockid="Arrow1Lend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Lend" - style="overflow:visible"> - <path - id="path3850" - d="M -10.666667,0 -14.933333,4.2666667 0,0 -14.933333,-4.2666667 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.85333335pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend" - style="overflow:visible"> - <path - id="path3856" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <inkscape:path-effect - effect="skeletal" - id="path-effect3841" - is_visible="true" - pattern="m 0,5 10,5 V 0 Z" - copytype="single_stretched" - prop_scale="1" - scale_y_rel="false" - spacing="0" - normal_offset="0" - tang_offset="0" - prop_units="false" - vertical_pattern="false" - fuse_tolerance="0" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-5" - style="overflow:visible"> - <path - id="path3856-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-0" - style="overflow:visible"> - <path - id="path3856-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-58" - style="overflow:visible"> - <path - id="path3856-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-9" - style="overflow:visible"> - <path - id="path3856-54" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-3" - style="overflow:visible"> - <path - id="path3856-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-03" - style="overflow:visible"> - <path - id="path3856-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-2" - style="overflow:visible"> - <path - id="path3856-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-4" - style="overflow:visible"> - <path - id="path3856-00" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-7" - style="overflow:visible"> - <path - id="path3856-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-76" - style="overflow:visible"> - <path - id="path3856-64" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-6" - style="overflow:visible"> - <path - id="path3856-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-65" - style="overflow:visible"> - <path - id="path3856-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-1" - style="overflow:visible"> - <path - id="path3856-01" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-29" - style="overflow:visible"> - <path - id="path3856-60" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-71" - style="overflow:visible"> - <path - id="path3856-83" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-26" - style="overflow:visible"> - <path - id="path3856-67" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-61" - style="overflow:visible"> - <path - id="path3856-86" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-48" - style="overflow:visible"> - <path - id="path3856-867" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5244" - style="overflow:visible"> - <path - id="path5246" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5248" - style="overflow:visible"> - <path - id="path5250" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5252" - style="overflow:visible"> - <path - id="path5254" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5256" - style="overflow:visible"> - <path - id="path5258" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5260" - style="overflow:visible"> - <path - id="path5262" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5264" - style="overflow:visible"> - <path - id="path5266" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-05" - style="overflow:visible"> - <path - id="path3856-52" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-33" - style="overflow:visible"> - <path - id="path3856-38" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-61-6" - style="overflow:visible"> - <path - id="path3856-86-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-64" - style="overflow:visible"> - <path - id="path3856-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-43" - style="overflow:visible"> - <path - id="path3856-33" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-33-5" - style="overflow:visible"> - <path - id="path3856-38-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-60" - style="overflow:visible"> - <path - id="path3856-96" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-59" - style="overflow:visible"> - <path - id="path3856-969" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-36" - style="overflow:visible"> - <path - id="path3856-02" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-8" - style="overflow:visible"> - <path - id="path3856-80" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-08" - style="overflow:visible"> - <path - id="path3856-28" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-81" - style="overflow:visible"> - <path - id="path3856-89" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-57" - style="overflow:visible"> - <path - id="path3856-66" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-22" - style="overflow:visible"> - <path - id="path3856-31" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-42" - style="overflow:visible"> - <path - id="path3856-50" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-84" - style="overflow:visible"> - <path - id="path3856-06" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-04" - style="overflow:visible"> - <path - id="path3856-62" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-32" - style="overflow:visible"> - <path - id="path3856-866" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-66" - style="overflow:visible"> - <path - id="path3856-78" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-72" - style="overflow:visible"> - <path - id="path3856-19" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-49" - style="overflow:visible"> - <path - id="path3856-34" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-96" - style="overflow:visible"> - <path - id="path3856-61" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-23" - style="overflow:visible"> - <path - id="path3856-18" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-10" - style="overflow:visible"> - <path - id="path3856-87" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-63" - style="overflow:visible"> - <path - id="path3856-317" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-01" - style="overflow:visible"> - <path - id="path3856-10" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-16" - style="overflow:visible"> - <path - id="path3856-55" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-86" - style="overflow:visible"> - <path - id="path3856-51" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62" - style="overflow:visible"> - <path - id="path3856-91" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-7" - style="overflow:visible"> - <path - id="path3856-91-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-06" - style="overflow:visible"> - <path - id="path3856-26" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79" - style="overflow:visible"> - <path - id="path3856-20" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37" - style="overflow:visible"> - <path - id="path3856-59" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-12" - style="overflow:visible"> - <path - id="path3856-93" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45" - style="overflow:visible"> - <path - id="path3856-03" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1" - style="overflow:visible"> - <path - id="path3856-20-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320" - style="overflow:visible"> - <path - id="path3856-615" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-4" - style="overflow:visible"> - <path - id="path3856-615-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-5" - style="overflow:visible"> - <path - id="path3856-615-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374" - style="overflow:visible"> - <path - id="path3856-525" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-7" - style="overflow:visible"> - <path - id="path3856-525-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30" - style="overflow:visible"> - <path - id="path3856-786" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8" - style="overflow:visible"> - <path - id="path3856-786-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1" - style="overflow:visible"> - <path - id="path3856-786-4-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2" - style="overflow:visible"> - <path - id="path3856-786-4-4-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2-8" - style="overflow:visible"> - <path - id="path3856-786-4-4-0-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-3" - style="overflow:visible"> - <path - id="path3856-525-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367" - style="overflow:visible"> - <path - id="path3856-53" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5228" - style="overflow:visible"> - <path - id="path5226" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-606" - style="overflow:visible"> - <path - id="path3856-261" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5228-8" - style="overflow:visible"> - <path - id="path5226-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-6" - style="overflow:visible"> - <path - id="path3856-91-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6" - style="overflow:visible"> - <path - id="path3856-53-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597" - style="overflow:visible"> - <path - id="path3856-76" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-3" - style="overflow:visible"> - <path - id="path3856-53-1-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699-6" - style="overflow:visible" - inkscape:isstock="true"> - <path - inkscape:connector-curvature="0" - id="path12697-3" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1-9" - style="overflow:visible"> - <path - id="path3856-20-0-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-1" - style="overflow:visible"> - <path - id="path3856-59-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-0" - style="overflow:visible"> - <path - id="path3856-03-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4336" - id="radialGradient7151-3" - cx="359.77701" - cy="645.03406" - fx="359.77701" - fy="645.03406" - r="88.283775" - gradientTransform="matrix(1,0,0,0.45837941,1046.7373,309.93065)" - gradientUnits="userSpaceOnUse" /> - <linearGradient - gradientTransform="translate(946.65782,48.302653)" - inkscape:collect="always" - xlink:href="#linearGradient7283" - id="linearGradient7285-8" - x1="548.74939" - y1="603.33936" - x2="548.74939" - y2="671.01959" - gradientUnits="userSpaceOnUse" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3" - style="overflow:visible"> - <path - id="path3856-53-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-0" - style="overflow:visible"> - <path - id="path3856-53-8-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8" - style="overflow:visible"> - <path - id="path3856-53-8-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-7" - style="overflow:visible"> - <path - id="path3856-53-8-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-09" - style="overflow:visible"> - <path - id="path3856-25" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-09-2" - style="overflow:visible"> - <path - id="path3856-25-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-4" - style="overflow:visible"> - <path - id="path3856-53-8-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5" - style="overflow:visible"> - <path - id="path3856-53-8-86" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-0-4" - style="overflow:visible"> - <path - id="path3856-53-8-4-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8-4" - style="overflow:visible"> - <path - id="path3856-53-8-8-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8-2" - style="overflow:visible"> - <path - id="path3856-53-8-8-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-7-0" - style="overflow:visible"> - <path - id="path3856-53-8-7-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31" - style="overflow:visible"> - <path - id="path3856-103" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0" - style="overflow:visible"> - <path - id="path3856-53-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1" - style="overflow:visible"> - <path - id="path3856-103-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3" - style="overflow:visible"> - <path - id="path3856-53-3-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3-6" - style="overflow:visible"> - <path - id="path3856-53-3-8-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0" - style="overflow:visible"> - <path - id="path3856-103-9-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-0-6" - style="overflow:visible"> - <path - id="path3856-03-8-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-1-8" - style="overflow:visible"> - <path - id="path3856-59-2-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-3-2" - style="overflow:visible"> - <path - id="path3856-53-1-6-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597-9" - style="overflow:visible"> - <path - id="path3856-76-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-0" - style="overflow:visible"> - <path - id="path3856-53-1-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699-3" - style="overflow:visible" - inkscape:isstock="true"> - <path - inkscape:connector-curvature="0" - id="path12697-2" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1-1" - style="overflow:visible"> - <path - id="path3856-20-0-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker7637-9" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart" - inkscape:collect="always"> - <path - inkscape:connector-curvature="0" - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path7635-9" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-1" - style="overflow:visible"> - <path - id="path3856-03-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-9" - style="overflow:visible"> - <path - id="path3856-59-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-0" - style="overflow:visible"> - <path - id="path3856-20-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-7-5" - style="overflow:visible"> - <path - id="path3856-91-0-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-70" - style="overflow:visible"> - <path - id="path3856-91-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-14" - style="overflow:visible"> - <path - id="path3856-69" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9" - style="overflow:visible"> - <path - id="path3856-53-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42788" - style="overflow:visible"> - <path - id="path42786" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88" - style="overflow:visible"> - <path - id="path3856-868" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42794" - style="overflow:visible"> - <path - id="path42792" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42798" - style="overflow:visible"> - <path - id="path42796" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42802" - style="overflow:visible"> - <path - id="path42800" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-5" - style="overflow:visible"> - <path - id="path3856-868-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9" - style="overflow:visible"> - <path - id="path3856-868-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4" - style="overflow:visible"> - <path - id="path3856-868-6-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9-8" - style="overflow:visible"> - <path - id="path3856-53-2-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-1" - style="overflow:visible"> - <path - id="path3856-868-6-1-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0" - style="overflow:visible"> - <path - id="path3856-868-6-1-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7" - style="overflow:visible"> - <path - id="path3856-868-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker61712-0" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path61710-6" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#7777ff;fill-opacity:1;fill-rule:evenodd;stroke:#7777ff;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4-8" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7-6" - style="overflow:visible"> - <path - id="path3856-868-7-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3-6-6" - style="overflow:visible"> - <path - id="path3856-53-3-8-4-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0-9" - style="overflow:visible"> - <path - id="path3856-103-9-0-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-6" - style="overflow:visible"> - <path - id="path3856-53-8-86-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-7" - style="overflow:visible"> - <path - id="path3856-53-8-86-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-2" - style="overflow:visible"> - <path - id="path3856-53-8-86-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-5" - style="overflow:visible"> - <path - id="path3856-53-8-86-92" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0-9-9" - style="overflow:visible"> - <path - id="path3856-103-9-0-1-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-02" - style="overflow:visible"> - <path - id="path3856-53-8-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-51" - style="overflow:visible"> - <path - id="path3856-53-8-10" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-50" - style="overflow:visible"> - <path - id="path3856-53-8-64" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4336" - id="radialGradient5882-9-2" - cx="-308.42361" - cy="215.26414" - fx="-308.42361" - fy="215.26414" - r="82.355362" - gradientTransform="matrix(0.97462339,0.03065639,-0.00222587,0.92717931,-7.2787813,25.071964)" - gradientUnits="userSpaceOnUse" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4-9" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker14034-2-9" - style="overflow:visible" - inkscape:isstock="true" - inkscape:collect="always"> - <path - inkscape:connector-curvature="0" - id="path14032-9-7" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597-9-5" - style="overflow:visible"> - <path - id="path3856-76-6-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3" - style="overflow:visible"> - <path - id="path3856-868-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9" - style="overflow:visible"> - <path - id="path3856-868-1-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9-3" - style="overflow:visible"> - <path - id="path3856-868-1-6-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9-3-4" - style="overflow:visible"> - <path - id="path3856-868-1-6-3-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-1" - style="overflow:visible"> - <path - id="path3856-868-78" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7528" - id="linearGradient7538" - x1="-868.78088" - y1="1372.24" - x2="-808.41711" - y2="1391.2367" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.4884955,0,0,1.4560331,399.01813,-638.72217)" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7528" - id="linearGradient7569" - x1="1352.9781" - y1="805.4386" - x2="1403.3633" - y2="835.65717" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(1.3436662,0,0,1.3436662,-483.65524,-280.21446)" /> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient7690" - id="linearGradient7692" - x1="1393.2487" - y1="848.74982" - x2="1314.9019" - y2="761.10052" - gradientUnits="userSpaceOnUse" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9-6" - style="overflow:visible"> - <path - id="path3856-53-2-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9-2" - style="overflow:visible"> - <path - id="path3856-53-2-99" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-0-0" - style="overflow:visible"> - <path - id="path3856-53-1-2-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-0-6" - style="overflow:visible"> - <path - id="path3856-20-7-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9-8-2" - style="overflow:visible"> - <path - id="path3856-53-2-9-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-70-9" - style="overflow:visible"> - <path - id="path3856-91-4-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0-9-9-9" - style="overflow:visible"> - <path - id="path3856-103-9-0-1-7-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-7-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-9-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-6-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-1-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8-4-9" - style="overflow:visible"> - <path - id="path3856-53-8-8-0-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-2-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-3-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-2-2" - style="overflow:visible"> - <path - id="path3856-53-8-86-3-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-2-5" - style="overflow:visible"> - <path - id="path3856-53-8-86-3-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-0-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-6-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76" - style="overflow:visible"> - <path - id="path3856-868-73" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <clipPath - clipPathUnits="userSpaceOnUse" - id="clipPath4663-1"> - <path - inkscape:connector-curvature="0" - id="path4665-4" - d="m -271.05789,1210.0412 a 2.696785,2.696785 0 1 0 -4.67096,2.6968 c 5.0617,8.7665 3.23435,19.8443 -4.37646,26.5184 -7.61086,6.6741 -18.83242,7.0411 -26.8638,0.8787 -8.03135,-6.1624 -10.58122,-17.0975 -6.10408,-26.1761 4.08261,-8.2784 12.94463,-12.8563 21.88939,-11.6128 -0.88712,1.1542 -1.99278,2.1555 -3.29743,2.9254 l 20.14237,1.0263 -14.67953,-13.83 c 0.35969,1.6142 0.37477,3.2419 0.0897,4.7959 -11.69625,-2.3122 -23.64426,3.489 -28.98068,14.3099 -0.70001,1.4194 -1.26239,2.879 -1.69088,4.3574 -2.99958,10.3492 0.55726,21.7355 9.34721,28.4799 10.04564,7.7079 24.18077,7.2468 33.70064,-1.1014 9.51986,-8.3482 11.8258,-22.303 5.49454,-33.2684 z" - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:7.18866682;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /> - </clipPath> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient5876" - id="linearGradient26409" - x1="646.16797" - y1="875.3656" - x2="650.64648" - y2="804.4024" - gradientUnits="userSpaceOnUse" - gradientTransform="matrix(0.77810044,0,0,0.77810044,625.96494,284.11797)" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-8" - style="overflow:visible"> - <path - id="path3856-868-73-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-7" - style="overflow:visible"> - <path - id="path3856-868-73-53" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-83" - style="overflow:visible"> - <path - id="path3856-868-73-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-9" - style="overflow:visible"> - <path - id="path3856-868-73-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-9-6" - style="overflow:visible"> - <path - id="path3856-868-73-7-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-76-3" - style="overflow:visible"> - <path - id="path3856-868-73-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient4304" - id="linearGradient13243" - x1="1062.8518" - y1="400.22534" - x2="1257.9207" - y2="400.22534" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(4.1797945,-2.0898972)" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-0-0-2" - style="overflow:visible"> - <path - id="path3856-53-1-2-2-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient1694" - id="linearGradient1364-8-7" - x1="415.74805" - y1="495.00006" - x2="415.74805" - y2="215.43314" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(904.95036,-71.333648)" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597-9-5-1" - style="overflow:visible"> - <path - id="path3856-76-6-3-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-34" - style="overflow:visible"> - <path - id="path3856-868-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="1" - inkscape:pageshadow="2" - inkscape:zoom="1.0500861" - inkscape:cx="72.674772" - inkscape:cy="568.52482" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="true" - showguides="true" - gridtolerance="1" - inkscape:window-width="2548" - inkscape:window-height="1415" - inkscape:window-x="0" - inkscape:window-y="0" - inkscape:window-maximized="1" - fit-margin-top="0.5" - fit-margin-left="0.5" - fit-margin-right="0.5" - fit-margin-bottom="0.5" - units="px" - inkscape:snap-global="true" - inkscape:snap-bbox="true" - inkscape:bbox-paths="false" - inkscape:bbox-nodes="false" - inkscape:snap-bbox-edge-midpoints="true" - inkscape:snap-bbox-midpoints="true" - inkscape:snap-midpoints="true" - inkscape:snap-object-midpoints="true" - inkscape:object-paths="true" - inkscape:snap-intersection-paths="true"> - <inkscape:grid - type="xygrid" - id="grid3065" - empspacing="5" - visible="true" - enabled="true" - snapvisiblegridlinesonly="true" - units="cm" - spacingx="37.795276" - spacingy="37.795276" - originx="-1038.3034" - originy="95.554798" /> - </sodipodi:namedview> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-1038.3034,-81.024808)"> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1065.9954" - y="133.45045" - id="text3021-8-4-1-8-8-2-3"><tspan - sodipodi:role="line" - x="1065.9954" - y="133.45045" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672" - id="tspan56267">Ramps:</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1309.1692" - y="511.25677" - id="text3021-8-4-1-8-8-2-6"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-1" - x="1309.1692" - y="511.25677" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672">Blinkies</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-885.51392" - y="1093.7063" - id="text3021-8-4-1-8-8-2-4" - transform="rotate(-90)"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-81" - x="-885.51392" - y="1093.7063" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672">Strobes</tspan></text> - <path - style="opacity:1;fill:url(#linearGradient13243);fill-opacity:1;stroke:#060000;stroke-width:2.1329999;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:5.11920023;stroke-opacity:1;paint-order:markers fill stroke" - d="m 1068.0981,341.48719 118.2226,0 74.8741,113.29651 h -193.0967 z" - id="rect13226" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <rect - style="opacity:1;fill:url(#linearGradient1364-8-7);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect1356-0-3" - width="37.795277" - height="264.56693" - x="1320.6984" - y="144.09947" /> - <image - y="145.69688" - x="1339.1499" - id="image21186" - xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAMgCAYAAADVw8ezAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI WXMAAC4mAAAuJgFVH1qAAAAAB3RJTUUH4wgWFywjmzkvJwAABGZJREFUeNrt08ENg0AQBEFjbf6R 9vP+kMUKoeoQpjTXOef+6TX9TQBEQIAICBABASIgQAREQIAICBABASIgQAREQIAICBABASIgQARE QIAICBABASIgQAREQIAICBABASIgQAREQIAICBABASIgQAREQIAICBABASIgQAREQIAICBABASIg QAREQIAICBABASIgQAREQIAICBABASIgQAQEiIAICBABASIgX28qK3iIgAARECACAkRAgAiIgAAR ECACAkRAgAiIgAARECACAkRAgAiIgAARECACAkRAgAiIgAARECACAkRAgAiIgAARECACAkRAgAiI gAARECACAkRAgAiIgAARECACAkRAgAiIgAARECACAkRAgAgIEAERECACAkRAgAgIEAERECACAkRA gGivqazgIQICRECACAgQAQEiIAICRECACAgQAQEiIAICRECACAgQAQEiIAICRECACAgQAQEiIAIC RECACAgQAQEiIAICRECACAgQAQEiIAICRECACAgQAQEiIAICRECACAgQAQEiIAICRECACAgQAQEi IEAERECACAgQAQEiIEAERECACAgQAQGivaaygocICBABASIgQAQEiIAICBABASIgQAQEiIAICBAB ASIgQAQEiIAICBABASIgQAQEiIAICBABASIgQAQEiIAICBABASIgQAQEiIAICBABASIgQAQEiIAI CBABASIgQAQEiIAICBABASIgQAQEiIAAERABASIgQAQEiIAAERABASIgQAQEiPaaygoeIiBABASI gAARECACIiBABASIgAARECACIiBABASIgAARECACIiBABASIgAARECACIiBABASIgAARECACIiBA BASIgAARECACIiBABASIgAARECACIiBABASIgAARECACIiBABASIgAARECACAkRABASIgAARECAC AkRABASIgAARECDaayoreIiAABEQIAICRECACIiAABEQIAICRECACIiAABEQIAICRECACIiAABEQ IAICRECACIiAABEQIAICRECACIiAABEQIAICRECACIiAABEQIAICRECACIiAABEQIAICRECACIiA ABEQIAICRECACAgQAREQIAICRECACAgQAREQIAICRECAaK+prOAhAgJEQIAICBABASIgAgJEQIAI CBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgAgJE QIAICBABASIgAgJEQIAICBABASIgAgJEQIAICBABASIgQAREQIAICBABASIgQAREQIAICBABAaK9 prKChwgIEAEBIiBABASIgAgIEAEBIiBABASIgAgIEAEBIiBABASIgAgIEAEBIiBABASIgAgIEAEB IiBABASIgAgIEAEBIiBABASIgAgIEAEBIiBABASIgAgIEAEBIiBABASIgAgIEAEBIiBABASIgAAR EAEBIiBABASIgAAREAEBIiBABASI9noABIsdhY+pbIsAAAAASUVORK5CYII= " - preserveAspectRatio="none" - height="261.36438" - width="17.741749" /> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:0.30000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.80000007,1.80000007;stroke-dashoffset:2.19000029;stroke-opacity:1" - d="m 1339.1499,145.69688 0,261.36438" - id="path15687-2-6-9" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-4" - width="416.73956" - height="363.7735" - x="1058.2677" - y="101.00932" /> - <rect - style="opacity:1;fill:none;fill-opacity:1;stroke:#009d00;stroke-width:2.1329999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect14693" - width="192.66586" - height="169.39575" - x="1405.2867" - y="520.16724" - rx="37" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3)" - d="m 1423.7634,525.54094 c 0.4636,-0.36597 1.7694,-0.51555 5.2997,-2.53158" - id="path5213-6-8-4-9-9-56-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-47" - width="399.48456" - height="260.94336" - x="1301.3027" - y="480.43896" /> - <path - style="fill:url(#linearGradient26409);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.55620086;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.316" - d="m 1132.6303,910.35848 h 17.5073 l -12.5835,21.63623 h 9.1098 l -18.3734,33.90788 5.8654,-23.97411 h -10.2792 z" - id="path26401" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cccccccc" /> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-6" - width="349.56042" - height="310.40146" - x="1058.2677" - y="758.40918" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-02)" - d="m 1597.9772,563.34418 c 0.4636,-0.36597 -0.021,1.8809 -0.045,6.26246" - id="path5213-6-8-4-9-9-56-6-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-51)" - d="m 1577.5842,684.90662 c 0.4636,-0.36597 -1.5747,0.4784 -6.1098,2.54774" - id="path5213-6-8-4-9-9-56-6-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-50)" - d="m 1405.234,654.99099 c 0.4636,-0.36597 0.5015,-1.74928 0.3311,-4.86628" - id="path5213-6-8-4-9-9-56-6-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <rect - style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect14693-4" - width="192.66586" - height="169.39575" - x="1405.2867" - y="520.16724" - rx="37" /> - <g - id="g14799" - transform="translate(-1.0079016)"> - <path - sodipodi:nodetypes="csscsscsssccsscsssssscssssssssscccssscsssssssssssssscsssscsscssssccc" - style="fill:#ffffff;fill-opacity:0.99504945;stroke:#000000;stroke-width:3.20000005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 1405.6649,642.61454 c -0.4528,-0.77951 -1.0803,-1.93107 -1.3944,-2.55904 -1.0737,-2.14685 -4.3131,-7.98949 -5.8699,-10.58711 -4.3266,-7.21903 -7.6037,-10.33824 -10.9596,-10.43127 -1.1186,-0.0309 -1.3542,0.0431 -2.4508,0.77103 -1.2711,0.84373 -2.1683,1.85544 -3.5537,4.00743 -0.4567,0.70938 -0.958,1.29061 -1.114,1.29161 -0.156,0.001 -0.9033,-0.54296 -1.6607,-1.20878 -7.1051,-6.24594 -14.3753,-9.53314 -19.4236,-8.7823 -3.48,0.51759 -5.0204,1.56173 -6.3938,4.33401 l -0.8858,1.78805 0.011,2.61009 c 0.011,2.85728 0.4129,4.7602 1.6033,7.59226 1.304,3.10248 4.2705,7.39835 7.3473,10.63996 0.8946,0.9425 1.5704,1.71317 1.5019,1.71263 -0.4463,-0.003 -7.9187,-2.69233 -10.6412,-3.82902 -9.6708,-4.03772 -16.4977,-8.35341 -21.7399,-13.74329 -4.3679,-4.49084 -7.1775,-8.79859 -8.874,-13.60588 -1.423,-4.03226 -1.7223,-8.61526 -0.7973,-12.20916 1.2721,-4.94273 4.1587,-9.44906 9.1295,-14.25253 8.9547,-8.65325 21.3332,-14.86929 39.844,-20.00822 2.5963,-0.72078 4.771,-1.26013 4.8325,-1.19854 0.062,0.0616 -0.1838,0.42841 -0.5455,0.81514 -3.4867,3.729 -6.1245,8.13223 -6.7635,11.29025 -0.8015,3.96135 0.9707,8.08749 4.5023,10.48189 3.6869,2.49979 7.1211,3.43584 12.0741,3.29111 2.5161,-0.0735 2.8886,-0.1349 3.94,-0.64934 2.5533,-1.24918 4.3142,-3.15132 6.057,-6.54273 1.7409,-3.38781 2.0096,-4.74402 2.7417,-13.83851 0.2853,-3.54386 0.5748,-6.74799 0.6434,-7.12032 0.2923,-1.58661 0.8641,-1.01936 2.6229,2.60221 0.6806,1.40141 1.4217,2.64659 1.6468,2.76707 0.2884,0.15436 1.0531,0.1497 2.5905,-0.0158 1.632,-0.17572 2.9123,-0.17461 5.085,0.004 2.867,0.2362 2.9101,0.23344 3.3901,-0.21752 0.2674,-0.25122 0.8726,-1.35826 1.3449,-2.46008 0.4722,-1.10183 1.099,-2.36999 1.3928,-2.81817 l 0.5342,-0.81485 0.2758,0.52623 c 0.4689,0.89501 0.8326,3.8019 1.4248,11.38899 0.497,6.36774 1.4643,9.24832 4.3881,13.06838 2.6506,3.46298 4.5846,4.27584 9.7379,4.09266 3.3642,-0.11958 5.0057,-0.46765 7.4657,-1.58306 4.2373,-1.92126 6.8173,-4.97803 7.4071,-8.77563 0.4545,-2.92687 -0.5377,-6.24976 -2.9384,-9.84036 -1.1827,-1.7688 -2.4781,-3.40213 -3.8135,-4.80832 -0.5385,-0.5671 -0.7241,-0.88226 -0.5195,-0.88226 0.4593,0 9.5442,2.56459 12.622,3.56306 22.3994,7.26655 37.858,19.25169 41.1432,31.89844 1.8774,7.22754 -0.9294,15.82998 -7.7794,23.84266 -2.308,2.69978 -3.5406,3.82883 -7.087,6.49171 -6.1933,4.65046 -11.5703,7.47767 -20.5514,10.80591 -2.9406,1.08974 -6.411,2.26689 -6.7199,2.27938 -0.043,0.001 0.5459,-0.65721 1.3072,-1.46427 4.3463,-4.60728 7.433,-9.51352 8.6471,-13.74407 0.6134,-2.13752 0.7622,-5.66081 0.313,-7.41075 -0.6515,-2.53772 -1.9946,-4.20202 -4.2556,-5.27337 -1.3335,-0.63187 -1.4404,-0.64784 -4.2739,-0.63813 -2.6104,0.01 -3.086,0.0691 -4.6708,0.59188 -3.9756,1.31118 -8.4584,3.98094 -12.5592,7.47975 -1.1418,0.97413 -2.1694,1.76995 -2.2835,1.76848 -0.1142,-10e-4 -0.6268,-0.63027 -1.139,-1.39734 -2.7305,-4.08839 -5.1372,-5.32966 -8.1429,-4.19963 -1.7271,0.64937 -3.2592,2.01781 -5.3119,4.74462 -2.2156,2.9433 -4.0421,5.9743 -8.3381,13.83722 -1.7466,3.19688 -3.2017,5.8431 -3.2335,5.88048 -0.032,0.0373 -0.4282,-0.56984 -0.881,-1.34934 z" - id="path3202-5-9-8" - inkscape:connector-curvature="0" /> - <path - sodipodi:nodetypes="csscsscsssccsscsssssscssssssssscccssscsssssssssssssscsssscsscssssccc" - style="fill:url(#radialGradient7151-3);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 1405.6649,642.61454 c -0.4528,-0.77951 -1.0803,-1.93107 -1.3944,-2.55904 -1.0737,-2.14685 -4.3131,-7.98949 -5.8699,-10.58711 -4.3266,-7.21903 -7.6037,-10.33824 -10.9596,-10.43127 -1.1186,-0.0309 -1.3542,0.0431 -2.4508,0.77103 -1.2711,0.84373 -2.1683,1.85544 -3.5537,4.00743 -0.4567,0.70938 -0.958,1.29061 -1.114,1.29161 -0.156,0.001 -0.9033,-0.54296 -1.6607,-1.20878 -7.1051,-6.24594 -14.3753,-9.53314 -19.4236,-8.7823 -3.48,0.51759 -5.0204,1.56173 -6.3938,4.33401 l -0.8858,1.78805 0.011,2.61009 c 0.011,2.85728 0.4129,4.7602 1.6033,7.59226 1.304,3.10248 4.2705,7.39835 7.3473,10.63996 0.8946,0.9425 1.5704,1.71317 1.5019,1.71263 -0.4463,-0.003 -7.9187,-2.69233 -10.6412,-3.82902 -9.6708,-4.03772 -16.4977,-8.35341 -21.7399,-13.74329 -4.3679,-4.49084 -7.1775,-8.79859 -8.874,-13.60588 -1.423,-4.03226 -1.7223,-8.61526 -0.7973,-12.20916 1.2721,-4.94273 4.1587,-9.44906 9.1295,-14.25253 8.9547,-8.65325 21.3332,-14.86929 39.844,-20.00822 2.5963,-0.72078 4.771,-1.26013 4.8325,-1.19854 0.062,0.0616 -0.1838,0.42841 -0.5455,0.81514 -3.4867,3.729 -6.1245,8.13223 -6.7635,11.29025 -0.8015,3.96135 0.9707,8.08749 4.5023,10.48189 3.6869,2.49979 7.1211,3.43584 12.0741,3.29111 2.5161,-0.0735 2.8886,-0.1349 3.94,-0.64934 2.5533,-1.24918 4.3142,-3.15132 6.057,-6.54273 1.7409,-3.38781 2.0096,-4.74402 2.7417,-13.83851 0.2853,-3.54386 0.5748,-6.74799 0.6434,-7.12032 0.2923,-1.58661 0.8641,-1.01936 2.6229,2.60221 0.6806,1.40141 1.4217,2.64659 1.6468,2.76707 0.2884,0.15436 1.0531,0.1497 2.5905,-0.0158 1.632,-0.17572 2.9123,-0.17461 5.085,0.004 2.867,0.2362 2.9101,0.23344 3.3901,-0.21752 0.2674,-0.25122 0.8726,-1.35826 1.3449,-2.46008 0.4722,-1.10183 1.099,-2.36999 1.3928,-2.81817 l 0.5342,-0.81485 0.2758,0.52623 c 0.4689,0.89501 0.8326,3.8019 1.4248,11.38899 0.497,6.36774 1.4643,9.24832 4.3881,13.06838 2.6506,3.46298 4.5846,4.27584 9.7379,4.09266 3.3642,-0.11958 5.0057,-0.46765 7.4657,-1.58306 4.2373,-1.92126 6.8173,-4.97803 7.4071,-8.77563 0.4545,-2.92687 -0.5377,-6.24976 -2.9384,-9.84036 -1.1827,-1.7688 -2.4781,-3.40213 -3.8135,-4.80832 -0.5385,-0.5671 -0.7241,-0.88226 -0.5195,-0.88226 0.4593,0 9.5442,2.56459 12.622,3.56306 22.3994,7.26655 37.858,19.25169 41.1432,31.89844 1.8774,7.22754 -0.9294,15.82998 -7.7794,23.84266 -2.308,2.69978 -3.5406,3.82883 -7.087,6.49171 -6.1933,4.65046 -11.5703,7.47767 -20.5514,10.80591 -2.9406,1.08974 -6.411,2.26689 -6.7199,2.27938 -0.043,0.001 0.5459,-0.65721 1.3072,-1.46427 4.3463,-4.60728 7.433,-9.51352 8.6471,-13.74407 0.6134,-2.13752 0.7622,-5.66081 0.313,-7.41075 -0.6515,-2.53772 -1.9946,-4.20202 -4.2556,-5.27337 -1.3335,-0.63187 -1.4404,-0.64784 -4.2739,-0.63813 -2.6104,0.01 -3.086,0.0691 -4.6708,0.59188 -3.9756,1.31118 -8.4584,3.98094 -12.5592,7.47975 -1.1418,0.97413 -2.1694,1.76995 -2.2835,1.76848 -0.1142,-10e-4 -0.6268,-0.63027 -1.139,-1.39734 -2.7305,-4.08839 -5.1372,-5.32966 -8.1429,-4.19963 -1.7271,0.64937 -3.2592,2.01781 -5.3119,4.74462 -2.2156,2.9433 -4.0421,5.9743 -8.3381,13.83722 -1.7466,3.19688 -3.2017,5.8431 -3.2335,5.88048 -0.032,0.0373 -0.4282,-0.56984 -0.881,-1.34934 z" - id="path3202-5-9" - inkscape:connector-curvature="0" /> - <text - id="text3021-8-4-1-8-1-6" - y="611.77692" - x="1340.5275" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="611.77692" - x="1340.5275" - id="tspan3023-4-0-1-9-7-2" - sodipodi:role="line">BattCheck</tspan></text> - </g> - <g - id="g14764"> - <ellipse - ry="29.092394" - rx="67.643234" - cy="688.51257" - cx="1497.9803" - id="path3639-4-4-3-7-2" - style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <ellipse - ry="29.092394" - rx="67.643234" - cy="688.51257" - cx="1497.9803" - id="path3639-4-4-3-7" - style="fill:url(#linearGradient7285-8);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-60-5" - y="695.24451" - x="1435.9058" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672" - y="695.24451" - x="1435.9058" - id="tspan3023-4-0-1-9-2-3" - sodipodi:role="line">TempCheck</tspan></text> - </g> - <g - id="g14731"> - <ellipse - ry="29.092394" - rx="67.643234" - cy="604.77051" - cx="1593.5562" - id="path3639-4-4-9-1" - style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-2-8" - y="612.58954" - x="1546.8853" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="612.58954" - x="1546.8853" - id="tspan3023-4-0-1-9-63-8-83" - sodipodi:role="line">Beacon</tspan></text> - </g> - <g - id="g21356"> - <g - id="g21349"> - <ellipse - style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-9-1-6" - cx="1502.1442" - cy="519.8219" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:85.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1501.6129" - y="529.14062" - id="text3021-8-4-1-8-8-2-8-8"><tspan - sodipodi:role="line" - x="1501.6129" - y="529.14062" - style="font-size:25.60000038px;line-height:85.00000238%;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:1.06666672" - id="tspan14716">Sunset<tspan - id="tspan23871" - style="font-size:25.60000038px;line-height:85.00000238%;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:1.06666672" /></tspan></text> - </g> - </g> - <g - id="g14689" - transform="translate(0.47473145)"> - <text - id="text3021-8-4-1-8-8-7-4" - y="699.71509" - x="1639.6669" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:1;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:18.66666603px;line-height:1;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672" - y="699.71509" - x="1639.6669" - id="tspan3023-4-0-1-9-63-3-3" - sodipodi:role="line">Thermal</tspan><tspan - id="tspan4199-0" - style="font-size:18.66666603px;line-height:1;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672" - y="718.38177" - x="1639.6669" - sodipodi:role="line">Cfg</tspan></text> - <ellipse - ry="31.258007" - rx="50.681404" - cy="699.95654" - cx="1638.769" - id="path3639-4-4-6-3" - style="fill:none;stroke:#ff0000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333344, 2.13333344;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09)" - d="m 1513.2522,717.92736 c 2.42,16.34201 29.9911,22.87705 72.4182,-3.30651" - id="path5213-6-8-4-9-9-8-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g14683"> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5" - y="511.39166" - x="1639.1299" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:85.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:18.66666603px;line-height:85.00000238%;text-align:center;text-anchor:middle;stroke-width:1.06666672" - y="511.39166" - x="1639.1299" - id="tspan3023-4-0-1-9-63-8-83-9" - sodipodi:role="line">Beacon</tspan><tspan - style="font-size:18.66666603px;line-height:85.00000238%;text-align:center;text-anchor:middle;stroke-width:1.06666672" - y="527.2583" - x="1639.1299" - sodipodi:role="line" - id="tspan14667">Cfg</tspan></text> - <ellipse - inkscape:transform-center-y="8.5053065" - inkscape:transform-center-x="-3.1895436" - ry="21.797352" - rx="50.681404" - cy="512.03644" - cx="1639.2438" - id="path3639-4-4-9-1-4" - style="fill:none;stroke:#000000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09-2)" - d="m 1655.5374,617.2342 c 16.7016,16.23216 46.3164,-11.31808 11.0065,-81.1781" - id="path5213-6-8-4-9-9-8-4-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-312.03278" - y="1346.9868" - id="text3021-8-4-1-8-8-3-4" - transform="rotate(-90)"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-6-2" - x="-312.03278" - y="1346.9868" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Ramp</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1268.1858" - y="201.6805" - id="text3021-8-4-1-8-6-14-2-4-7-7-9" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1268.1858" - y="201.6805" - id="tspan3613-9-7-5-6" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Ceil</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1263.0579" - y="417.30948" - id="text3021-8-4-1-8-6-14-2-4-7-7-3-1" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1263.0579" - y="417.30948" - id="tspan3613-9-7-5-5-0" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Floor</tspan></text> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-70)" - d="m 1419.75,188.60753 0,174.38457" - id="path5213-6-8-2-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:12.79799938,2.1329999;stroke-dashoffset:7.46549964;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-7-5)" - d="M 1400.1843,359.40373 V 191.75683" - id="path5213-6-8-2-9-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-239.43126" - y="1515.5392" - id="text3021-8-4-1-8-6-14-2-4-7-7-3-3-2" - transform="matrix(0,-1.0975814,0.91109416,0,0,0)"><tspan - sodipodi:role="line" - x="-239.43126" - y="1515.5392" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672" - id="tspan2698-2">Turbo</tspan></text> - <path - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-79-0)" - d="m 1159.4045,270.23739 c 108.4581,4.22547 23.1574,-88.17063 154.3238,-89.5992" - id="path5213-6-8-4-9-9-8-2-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker7637-9);marker-end:url(#Arrow1Mend-45-1)" - d="m 1314.3007,333.29999 c -90.8252,5.74785 -43.5378,-60.02663 -137.7344,-45.56247" - id="path5213-6-8-4-9-9-6-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" - d="m 1320.7414,332.0074 h 37.7525" - id="path15687-90" - inkscape:connector-curvature="0" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1109.0515" - y="-593.28467" - id="text16320-2" - transform="rotate(42.138927)"><tspan - sodipodi:role="line" - id="tspan16318-8" - x="1109.0515" - y="-593.28467">Mem</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="-399.5589" - y="1453.8257" - id="text16326-8" - transform="rotate(-90)"><tspan - sodipodi:role="line" - id="tspan16324-0" - x="-399.5589" - y="1453.8257">Regulated Hybrid -------------- Direct Drive</tspan></text> - <g - id="g16453-4" - transform="translate(988.22664,-147.99262)"> - <path - inkscape:connector-curvature="0" - id="path16424-0" - d="M 453.54332,291.02364 V 555.59057" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-9" - d="M 467.5047,555.59057 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-5-1" - d="M 467.5047,480.00002 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-3-9" - d="M 467.5047,291.02364 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:7.30000019;stroke-opacity:1" - d="m 1319.7047,178.2642 h 69.7795" - id="path15687-2-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0)" - d="m 1131.0344,258.42719 c 48.1809,-3.99296 64.2076,-2.68523 79.9712,-42.47521 42.8072,-108.05255 130.8373,-147.401507 128.5867,-35.74184" - id="path5213-6-8-4-9-9-9-29-5-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1434.2471" - y="787.48492" - id="text3021-8-4-1-8-8-2-3-0"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-8-2" - x="1434.2471" - y="787.48492" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672">Ramp Cfg</tspan><tspan - sodipodi:role="line" - x="1434.2471" - y="802.48492" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39566" /><tspan - sodipodi:role="line" - x="1434.2471" - y="802.48492" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39568" /><tspan - sodipodi:role="line" - x="1434.2471" - y="802.48492" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39570" /><tspan - sodipodi:role="line" - x="1434.2471" - y="802.48492" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39590" /></text> - <g - transform="translate(9.0949204,-123.27684)" - id="g16522-3"> - <text - inkscape:transform-center-y="-2.0513889" - inkscape:transform-center-x="1.8963668" - transform="rotate(-0.20350505)" - id="text7289-7-6-21-8-8" - y="915.03876" - x="1617.4175" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="915.03876" - x="1617.4175" - id="tspan7287-5-5-7-5-6" - sodipodi:role="line"> 4 Clicks</tspan></text> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-1-3-8-4-0" - d="m 1620.8968,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9-3)" /> - </g> - <g - transform="translate(9.0949217,89.635331)" - id="g16522-3-8"> - <text - inkscape:transform-center-y="-2.0513889" - inkscape:transform-center-x="1.8963668" - transform="rotate(-0.20350505)" - id="text7289-7-6-21-8-8-8" - y="915.03876" - x="1617.4175" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="915.03876" - x="1617.4175" - id="tspan7287-5-5-7-5-6-9" - sodipodi:role="line"> 4 Clicks</tspan></text> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-1-3-8-4-0-7" - d="m 1620.8968,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9-3-4)" /> - </g> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-4-9" - width="275.93164" - height="310.87778" - x="1424.8558" - y="758.40918" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1444.4535" - y="806.21515" - id="text39556"><tspan - sodipodi:role="line" - x="1444.4535" - y="806.21515" - id="tspan39558">1. Floor</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="822.34851" - id="tspan58144"> (click N times for level N)</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="838.48181" - id="tspan39562">2. Ceiling</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="854.61517" - id="tspan58146"> (click N times for Nth highest)</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="870.74847" - id="tspan39606">3. Number of steps</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="886.88184" - id="tspan43997"> (stepped ramp only)</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1444.4535" - y="929.23431" - id="text39623"><tspan - sodipodi:role="line" - id="tspan39621" - x="1444.4535" - y="929.23431">1. Current temperature</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="945.36768" - id="tspan14663"> (click N times for N deg C)</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="961.50098" - id="tspan14661">2. Temperature limit</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="977.63434" - id="tspan39625"> (click N times for N + 30 C)</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1444.4535" - y="1019.1274" - id="text39629"><tspan - sodipodi:role="line" - id="tspan39627" - x="1444.4535" - y="1019.1274">1. Beacon speed</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="1035.2607" - id="tspan39631"> (click N times</tspan><tspan - sodipodi:role="line" - x="1444.4535" - y="1051.394" - id="tspan43995"> for N seconds per flash)</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-14)" - d="m 1012.9365,299.28188 c 26.3813,0.76852 22.4829,57.6582 -8.9055,81.08668 -31.38843,23.42848 -96.78863,5.87049 -137.72403,-26.36711" - id="path5213-6-8-4-9-9-1-42" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <g - id="g47455" - transform="translate(-742.72705,222.13423)"> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5-64" - y="119.67136" - x="1502.3363" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="119.67136" - x="1502.3363" - id="tspan3023-4-0-1-9-63-8-83-9-1" - sodipodi:role="line">Ramp</tspan></text> - <ellipse - inkscape:transform-center-y="11.351831" - inkscape:transform-center-x="-4.2569368" - ry="29.092394" - rx="67.643234" - cy="122.72764" - cx="1535.9958" - id="path3639-4-4-9-1-4-2" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5-6-8" - y="142.59866" - x="1515.2289" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="142.59866" - x="1515.2289" - id="tspan3023-4-0-1-9-63-8-83-9-9-8" - sodipodi:role="line">Cfg</tspan></text> - </g> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.6915,166.15809 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1498.5459,209.88219 c 49.5295,21.01119 54.6565,-32.82141 113.6548,0" - id="path5213-6-8-4-9-9-9-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:0.21333334;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.0847,386.36671 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-8-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:2.55959988;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.0847,431.64591 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-1-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1508.8501" - y="130.56808" - id="text3021-8-4-1-8-6-1-5-3"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-6-4-1-8" - x="1508.8501" - y="130.56808" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Actions</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1387.957" - y="205.90257" - id="text3021-8-4-1-8-6-14-2-4-0" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1387.957" - y="205.90257" - id="tspan3613-9-4" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">1 Click</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1397.882" - y="254.90924" - id="text3021-8-4-1-8-6-14-2-4-6-7" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1397.882" - y="254.90924" - id="tspan3613-9-8-6" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Hold</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1384.182" - y="447.44418" - id="text3021-8-4-1-8-6-14-2-4-7-8" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1384.182" - y="447.44418" - id="tspan3613-9-7-9" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">3 Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1363.9153" - y="497.13034" - id="text3021-8-4-1-8-6-14-2-4-1-0" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1363.9153" - y="497.13034" - id="tspan3613-9-1-6" - style="font-size:17.06666756px;line-height:1.25;fill:#7777ff;fill-opacity:1;stroke-width:1.06666672">Other Action</tspan></text> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-8" - width="129.83826" - height="363.63089" - x="1491.3889" - y="100.98911" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9)" - d="m 1499.2534,277.65781 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-56-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.80000067, 2.13333344;stroke-dashoffset:2.98666692;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9)" - d="m 1498.1078,321.38191 c 49.5295,21.01119 54.6565,-32.82141 113.6548,0" - id="path5213-6-8-4-9-9-9-29-90" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1384.207" - y="328.28253" - id="text3021-8-4-1-8-6-14-2-4-12-3" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1384.207" - y="328.28253" - id="tspan3613-9-70-3" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">2 Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1372.457" - y="377.28925" - id="text3021-8-4-1-8-6-14-2-4-6-9-3" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1372.457" - y="377.28925" - id="tspan3613-9-8-3-7" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">Click, Hold</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:58.66666794px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-454.34503" - y="1684.3434" - id="text5250-2" - transform="rotate(-90)"><tspan - y="1684.3434" - x="-454.34503" - sodipodi:role="line" - id="tspan6532-6">Andúril‎ UI</tspan></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:4.26599979,4.26599979;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-5)" - d="m 1151.6852,495.69893 c 78.9733,-34.68373 144.1831,19.3203 183.6703,76.26436" - id="path5213-6-8-4-9-9-8-3-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9)" - d="m 1079.887,532.80239 c -12.1825,60.27066 -9.0869,152.20049 5.6808,220.10165" - id="path5213-6-8-4-9-9-1-3-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4)" - d="m 1109.1006,543.61207 c -5.3744,57.689 -10.8606,99.77877 39.243,100.48777" - id="path5213-6-8-4-9-9-1-3-0-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(969.27179,76.164687)" - id="g23629-5-4-8"> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-0-8-6" - cx="140.59442" - cy="435.21741" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="112.51038" - y="444.62402" - id="text3021-8-9-7-2"><tspan - sodipodi:role="line" - id="tspan3023-4-6-0-4" - x="112.51038" - y="444.62402" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - </g> - <path - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-8)" - d="m 1364.0175,147.54301 c 29.3791,49.772 28.7391,140.19451 -0.7576,180.57634" - id="path5213-6-8-4-9-9-56-7-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1436.6729" - y="910.76184" - id="text3021-8-4-1-8-8-2-3-0-5"><tspan - sodipodi:role="line" - x="1436.6729" - y="910.76184" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39596-4">Thermal Cfg</tspan><tspan - sodipodi:role="line" - x="1436.6729" - y="925.76184" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39590-9" /></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1434.2471" - y="1000.3971" - id="text3021-8-4-1-8-8-2-3-0-3"><tspan - sodipodi:role="line" - x="1434.2471" - y="1000.3971" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39590-4">Beacon Cfg</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0)" - d="m 1127.941,552.67567 c 8.2381,55.86142 12.4246,16.66987 28.876,-16.227 18.1418,-36.27675 65.1509,-72.19798 76.5732,0.99224" - id="path5213-6-8-4-9-9-1-3-0-0-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7)" - d="m 1300.9995,480.43896 c -47.6705,-9.8516 -110.3689,-9.28576 -158.1487,2.96046" - id="path5213-6-8-4-9-9-3-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:none;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4)" - d="m 1104.0483,552.32849 c 0,0 25.6454,8.80842 22.0934,-6.76915" - id="path5213-6-8-4-9-9-1-3-0-0-6-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:none;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4-8)" - d="m 1366.1809,151.11654 c 0,0 8.8213,16.58792 -2.1634,-3.57353" - id="path5213-6-8-4-9-9-1-3-0-0-6-4-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2" - inkscape:transform-center-x="1.1517845" - inkscape:transform-center-y="-2.5788507" - transform="translate(11.068361,12.736197)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-6" - id="textPath20030"><tspan - id="tspan7287-5-5-6"> 4 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - transform="translate(3.9941843,-3.1212455)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0" - id="textPath20018"><tspan - id="tspan7287-5-5-6-6"> 5 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-6" - inkscape:transform-center-x="-1.5564693" - inkscape:transform-center-y="-1.9746618" - transform="translate(4.5029255)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0" - id="textPath20024"><tspan - id="tspan7287-5-5-6-6-4"> Click, Click, Hold (3H)</tspan></textPath></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7-6)" - d="m 1058.2677,758.40918 c 0.4912,-26.15636 0.9882,-169.24427 7.3904,-226.98309" - id="path5213-6-8-4-9-9-3-4-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g14617" - transform="translate(-13.294351,-32.815344)"> - <path - sodipodi:nodetypes="csc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-9-4-6-4-2" - d="m 1215.6497,872.07607 c -92.2951,14.34989 -90.2875,-65.11743 -29.8514,-66.50842 51.6628,-1.18906 77.3999,68.69862 -5.9066,54.96341" - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0-9)" /> - <text - id="text34914-9-6-7" - y="832.58008" - x="1186.5371" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="832.58008" - x="1186.5371" - id="tspan34912-3-2-0" - sodipodi:role="line">Brighter</tspan><tspan - id="tspan7172" - y="852.58008" - x="1186.5371" - sodipodi:role="line">/ Faster</tspan></text> - </g> - <g - id="g14623" - transform="translate(-13.294351,-29.307693)"> - <text - id="text35803-5-7-3" - y="827.94098" - x="1277.6576" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="827.94098" - x="1277.6576" - id="tspan35801-6-5-6" - sodipodi:role="line">Dimmer</tspan><tspan - id="tspan7174" - y="847.94098" - x="1277.6576" - sodipodi:role="line">/ Slower</tspan></text> - <path - sodipodi:nodetypes="csc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-9-4-6-4-2-3" - d="m 1298.1704,855.8694 c 75.92,10.10449 72.6994,-54.50393 12.2633,-55.89492 -51.6628,-1.18906 -74.3675,75.06672 15.6104,66.18339" - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:12.798, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0-9-9)" /> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1172.5502" - y="720.89923" - id="text3021-8-4-1-8-8-2-8-5-64-5" - inkscape:transform-center-x="-5.2422885" - inkscape:transform-center-y="10.020862"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-83-9-1-8" - x="1172.5502" - y="720.89923" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Muggle</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1158.3502" - y="648.50262" - id="text3021-8-4-1-8-8-2-8-5-64-7" - inkscape:transform-center-x="-5.2422885" - inkscape:transform-center-y="10.020862"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-83-9-1-2" - x="1158.3502" - y="648.50262" - style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672">Momentary</tspan></text> - <path - sodipodi:type="star" - style="opacity:1;fill:none;fill-opacity:0.99504945;stroke:#000000;stroke-width:6.38363266;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path18710" - sodipodi:sides="3" - sodipodi:cx="180.12621" - sodipodi:cy="633.72162" - sodipodi:r1="74.637772" - sodipodi:r2="62.512047" - sodipodi:arg1="0.20456675" - sodipodi:arg2="1.2517643" - inkscape:flatsided="false" - inkscape:rounded="0.337" - inkscape:randomized="-6.93889e-18" - d="m 253.20771,648.88376 c -4.74931,22.89166 -31.27534,36.8627 -53.47475,44.19551 -22.19942,7.33281 -51.8282,11.91057 -69.2783,-3.64828 -17.45011,-15.55885 -16.28638,-45.51659 -11.53707,-68.40825 4.74931,-22.89167 15.59924,-50.83982 37.79866,-58.17263 22.19941,-7.33281 47.56171,8.65388 65.01182,24.21274 17.4501,15.55885 36.22895,38.92924 31.47964,61.82091 z" - transform="matrix(0.95651011,0,0,0.42184838,1047.3385,446.51946)" - inkscape:transform-center-x="0.37162569" - inkscape:transform-center-y="0.78560035" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4)" - d="m 1105.7807,594.68687 c -0.286,50.1308 -6.5453,119.74711 44.2016,125.06625" - id="path5213-6-8-4-9-9-1-3-0-0-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-9" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - x="4.0937777" - y="-2.4259422" - transform="translate(3.7169557,-2.2115172)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-3" - id="textPath20021"><tspan - id="tspan7287-5-5-6-6-1"> 6 Clicks</tspan></textPath></text> - <path - style="fill:none;stroke:none;stroke-width:1.32938921;stroke-miterlimit:4;stroke-dasharray:1.32938933, 1.32938933;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4-9)" - d="m 1400.1843,364.54546 c 0,0 -0.017,-16.32727 -0.084,-0.91459" - id="path5213-6-8-4-9-9-1-3-0-0-6-4-9" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:4.05333376;stroke-opacity:1;marker-start:url(#marker14034-2-9);marker-end:url(#Arrow1Mend-597-9-5)" - d="m 954.34165,198.62656 c 67.98625,-0.44112 68.74305,-36.42258 0.1793,-35.70399" - id="path5213-6-8-4-9-9-8-7-3-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g18567" - transform="translate(-191.75097,7.3367765)"> - <text - id="text56273" - y="160.56241" - x="1067.6877" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan56275" - y="160.56241" - x="1067.6877" - sodipodi:role="line">Smooth </tspan></text> - <ellipse - ry="14.669211" - rx="39.313492" - cy="154.67567" - cx="1101.8171" - id="path11546" - style="opacity:1;fill:none;fill-opacity:1;stroke:#010109;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <g - id="g16522" - transform="translate(9.094912)"> - <text - inkscape:transform-center-y="-2.0513889" - inkscape:transform-center-x="1.8963668" - transform="rotate(-0.20350505)" - id="text7289-7-6-21-8" - y="915.03876" - x="1617.4175" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="915.03876" - x="1617.4175" - id="tspan7287-5-5-7-5" - sodipodi:role="line"> 4 Clicks</tspan></text> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-1-3-8-4" - d="m 1620.8968,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9)" /> - </g> - <g - id="g18572" - transform="translate(-281.95292,43.516866)"> - <rect - ry="3" - rx="3" - y="142.29279" - x="1152.8596" - height="25.367319" - width="78.318939" - id="rect11665" - style="opacity:1;fill:none;fill-opacity:1;stroke:#010109;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text56273-7" - y="160.56241" - x="1154.8745" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan56275-6" - y="160.56241" - x="1154.8745" - sodipodi:role="line">Stepped</tspan></text> - </g> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-4)" - d="m 1105.4067,642.42175 c 0.045,-2.13304 0.1257,-3.76647 -0.02,-8.64889" - id="path5213-6-8-4-9-9-1-3-0-0-3-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g25629"> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-20" - d="m 1293.1165,869.27992 c 22.9934,5.0006 51.8174,18.31502 72.3787,39.21347" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-7)" /> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-2" - d="m 1094.1498,915.50098 c 17.8272,-22.80331 42.9724,-34.59893 64.3085,-42.39665" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-0)" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-0-0)" - d="m 1094.1498,915.50098 c 17.8272,-22.80331 42.9724,-34.59893 64.3085,-42.39665" - id="path5213-6-8-4-9-9-56-6-28-2-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-7" - d="m 1099.1838,1002.8716 c -10.8263,-13.32961 -17.2825,-22.994 -19.3174,-41.90761" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2)" /> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-8" - d="m 1386.1562,953.29137 c -0.01,16.47992 -3.5377,27.95532 -16.4966,45.71352" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-6)" /> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-9-6" - d="m 1286.1122,1044.9041 c -32.6374,7.6868 -68.0318,7.3275 -98.7961,1.9808" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-8-4)" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-7-0)" - d="m 1293.1165,869.27993 c 22.9934,5.0006 51.8174,18.31502 72.3787,39.21347" - id="path5213-6-8-4-9-9-56-6-28-20-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-6-0)" - d="m 1386.1562,953.29137 c -0.01,16.47992 -3.5377,27.95532 -16.4966,45.71352" - id="path5213-6-8-4-9-9-56-6-28-8-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-8-4-9)" - d="m 1286.1122,1044.9041 c -32.6374,7.6868 -68.0318,7.3275 -98.7961,1.9808" - id="path5213-6-8-4-9-9-56-6-9-6-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#f6fcf6;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-0)" - d="m 1099.1838,1002.8716 c -10.8263,-13.3296 -17.2825,-22.994 -19.3174,-41.9076" - id="path5213-6-8-4-9-9-56-6-28-7-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(0.00410028,-36.452254)" - id="g7243"> - <g - id="g28835" - transform="translate(81.09879,-12.221496)"> - <text - id="text3021-8-4-1-8-8-2-7" - y="981.17542" - x="1222.7643" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="981.17542" - x="1222.7643" - id="tspan3023-4-0-1-9-63-8-7" - sodipodi:role="line">Bike</tspan></text> - <ellipse - ry="29.092394" - rx="67.643234" - cy="986.1272" - cx="1248.0287" - id="path3639-4-4-9-5" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-2-7-4" - y="1005.0751" - x="1202.3188" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="1005.0751" - x="1202.3188" - id="tspan3023-4-0-1-9-63-8-7-8" - sodipodi:role="line">Flasher</tspan></text> - </g> - <g - id="g28877" - transform="translate(-82.541209,-37.878365)"> - <text - id="text3021-8-4-1-8-8-2-7-2" - y="1087.1008" - x="1357.3134" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="1087.1008" - x="1357.3134" - id="tspan3023-4-0-1-9-63-8-7-89" - sodipodi:role="line">Party</tspan></text> - <ellipse - ry="29.092394" - rx="67.643234" - cy="1091.3002" - cx="1388.598" - id="path3639-4-4-9-5-3" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-2-7-4-6" - y="1111.7531" - x="1345.8983" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="1111.7531" - x="1345.8983" - id="tspan3023-4-0-1-9-63-8-7-8-8" - sodipodi:role="line">Strobe</tspan></text> - </g> - <g - id="g28919" - transform="translate(-88.581451,-166.13611)"> - <text - id="text3021-8-4-1-8-8-2-7-2-2" - y="1219.2247" - x="1200.4392" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="1219.2247" - x="1200.4392" - id="tspan3023-4-0-1-9-63-8-7-89-1" - sodipodi:role="line">Tactical</tspan></text> - <ellipse - ry="29.092394" - rx="67.643234" - cy="1218.9089" - cx="1247.527" - id="path3639-4-4-9-5-3-0" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-2-7-4-6-5" - y="1239.3618" - x="1204.8273" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="1239.3618" - x="1204.8273" - id="tspan3023-4-0-1-9-63-8-7-8-8-1" - sodipodi:role="line">Strobe</tspan></text> - </g> - <g - id="g28961" - transform="translate(-2.2028768,-134.13011)"> - <text - id="text3021-8-4-1-8-8-2-7-2-2-0" - y="1109.4977" - x="1088.8826" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672" - y="1109.4977" - x="1088.8826" - id="tspan3023-4-0-1-9-63-8-7-89-1-8" - sodipodi:role="line">Lightning</tspan></text> - <ellipse - ry="29.092394" - rx="67.643234" - cy="1109.5366" - cx="1139.1631" - id="path3639-4-4-9-5-3-0-5" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-2-7-4-6-5-0" - y="1131.0537" - x="1106.3962" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672" - y="1131.0537" - x="1106.3962" - id="tspan3023-4-0-1-9-63-8-7-8-8-1-6" - sodipodi:role="line">Storm</tspan></text> - </g> - <g - id="g5944" - transform="translate(2.1928969,2.1881554)"> - <text - id="text3021-8-4-1-8-8-2-7-2-2-0-6" - y="923.39539" - x="1182.9138" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25.60000038px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="923.39539" - x="1182.9138" - id="tspan3023-4-0-1-9-63-8-7-89-1-8-7" - sodipodi:role="line">Candle</tspan></text> - <ellipse - ry="29.092394" - rx="67.643234" - cy="913.85162" - cx="1227.4263" - id="path3639-4-4-9-5-3-0-5-5" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - </g> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-8-3-5" - d="m 1262.9626,853.74322 c 45.3646,10.29118 76.432,-7.96445 88.9489,-15.20313" - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:2.13333344;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-1)" /> - <text - id="text39623-3" - y="857.24713" - x="1342.4323" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan39625-1" - y="857.24713" - x="1342.4323" - sodipodi:role="line">+30 min</tspan></text> - <g - id="g7705"> - <circle - style="opacity:1;fill:url(#linearGradient7569);fill-opacity:1;stroke:url(#linearGradient7692);stroke-width:1.71500003;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path7491" - cx="1375.8579" - cy="821.88452" - r="22.470001" /> - <ellipse - style="opacity:1;fill:#fcfcfd;fill-opacity:1;stroke:none;stroke-width:1.83983243;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path7491-8" - cx="1375.8579" - cy="821.88452" - rx="20.29092" - ry="20.7346" /> - <path - style="opacity:1;fill:url(#linearGradient7538);fill-opacity:1;stroke:none;stroke-width:1.84021866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path7491-5" - sodipodi:type="arc" - sodipodi:cx="-821.88452" - sodipodi:cy="1375.8579" - sodipodi:rx="20.743311" - sodipodi:ry="20.29092" - sodipodi:start="0" - sodipodi:end="3.1415927" - sodipodi:open="true" - d="m -801.14121,1375.8579 a 20.743311,20.29092 0 0 1 -10.37166,17.5725 20.743311,20.29092 0 0 1 -20.74331,0 20.743311,20.29092 0 0 1 -10.37165,-17.5725" - transform="rotate(-90)" /> - <path - style="opacity:1;fill:none;fill-opacity:1;stroke:#7b7b7b;stroke-width:1.3436662;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 1355.307,821.88451 h 3.8436" - id="path7493" - inkscape:connector-curvature="0" /> - <path - style="opacity:1;fill:none;fill-opacity:1;stroke:#7b7b7b;stroke-width:1.3436662;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 1396.1468,821.88451 h -3.3507" - id="path7495" - inkscape:connector-curvature="0" /> - <path - style="opacity:1;fill:none;fill-opacity:1;stroke:#7b7b7b;stroke-width:1.3436662;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 1375.8579,801.14199 v 3.54788" - id="path7497" - inkscape:connector-curvature="0" /> - <path - style="opacity:1;fill:none;fill-opacity:1;stroke:#7b7b7b;stroke-width:1.3436662;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 1375.8579,842.61913 v -3.64646" - id="path7499" - inkscape:connector-curvature="0" /> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#010109;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.01549935;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" - d="m 1374.5713,821.88451 1.1658,17.72796 h 0.34 l 1.0673,-17.72796 z" - id="path7505" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.3436662;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" - d="m 1392.31,822.12981 c 0,7.79405 -7.5434,14.85118 -14.018,14.85118 v 1.34367 c 7.4212,0 14.1074,-7.62913 14.1074,-16.19485 z" - id="path7594" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99419165;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" - d="m 1388.7657,822.05276 c 0,5.76689 -5.5816,10.98852 -10.3722,10.98852 v 0.9942 c 5.4909,0 10.4382,-5.64487 10.4382,-11.98272 z" - id="path7594-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#0b0b0b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.65623033;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" - d="m 1385.327,822.06555 c 0,3.80652 -3.6842,7.25313 -6.8462,7.25313 v 0.65624 c 3.6244,0 6.8899,-3.72599 6.8899,-7.90937 z" - id="path7594-36" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - </g> - </g> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-6)" - d="m 1499.2534,277.65781 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-56-7-15" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#fcfffc;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:2.98620009;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-2)" - d="m 1498.1078,321.38191 c 49.5295,21.0112 54.6565,-32.82141 113.6548,0" - id="path5213-6-8-4-9-9-9-29-90-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0-0)" - d="m 1131.0344,258.42719 c 48.1809,-3.99296 64.2076,-2.68523 79.9712,-42.47521 42.8072,-108.05255 130.8373,-147.401511 128.5867,-35.74184" - id="path5213-6-8-4-9-9-9-29-5-2-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-79-0-6)" - d="m 1159.4045,270.23739 c 108.4581,4.22547 23.1574,-88.17063 154.3238,-89.5992" - id="path5213-6-8-4-9-9-8-2-0-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(980.51459,-148.00986)" - id="g23629-5-4"> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-0-8" - cx="140.59442" - cy="435.21741" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="112.51038" - y="444.62402" - id="text3021-8-9-7"><tspan - sodipodi:role="line" - id="tspan3023-4-6-0" - x="112.51038" - y="444.62402" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - </g> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-8-2)" - d="m 1364.0175,147.54301 c 29.3791,49.77199 28.7391,140.19451 -0.7576,180.57634" - id="path5213-6-8-4-9-9-56-7-1-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-70-9)" - d="M 1419.75,188.60753 V 362.9921" - id="path5213-6-8-2-4-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g25632"> - <path - sodipodi:nodetypes="csc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-9-4-6-4-2-3-7" - d="m 1284.876,826.56171 c 75.92,10.10449 72.6994,-54.50393 12.2633,-55.89492 -51.6628,-1.18906 -74.3675,75.06672 15.6104,66.18339" - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-31-1-0-9-9-9)" /> - </g> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-7-0" - d="M 23.378604,46.366264 C 12.552304,33.036664 6.0961038,23.372264 4.0612038,4.458664" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-2)" /> - <path - sodipodi:nodetypes="cc" - inkscape:connector-curvature="0" - id="path5213-6-8-4-9-9-56-6-28-7-29" - d="M 23.378604,46.366264 C 12.552304,33.036664 6.0961038,23.372264 4.0612038,4.458664" - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-3-5-2-5)" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76)" - d="m 1282.1305,1141.8934 c 50.2683,-0.2481 46.5806,-28.9567 108.0573,-27.528" - id="path5213-6-8-4-9-9-1-3-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-9)" - d="m 1282.1305,1141.8934 c 50.2683,0.2481 46.5806,27.9715 108.0573,26.5428" - id="path5213-6-8-4-9-9-1-3-6-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(1091.3148,706.581)" - id="g23629-5-4-1"> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-0-8-5" - cx="140.59442" - cy="435.21741" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="112.51038" - y="444.62402" - id="text3021-8-9-7-9"><tspan - sodipodi:role="line" - id="tspan3023-4-6-0-7" - x="112.51038" - y="444.62402" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1072.3127" - y="366.15677" - id="text3021-8-4-1-8-8-2-3-0-39"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-8-2-0" - x="1072.3127" - y="366.15677" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672">While On:</tspan><tspan - sodipodi:role="line" - x="1072.3127" - y="381.15677" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39566-8" /><tspan - sodipodi:role="line" - x="1072.3127" - y="381.15677" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39568-8" /><tspan - sodipodi:role="line" - x="1072.3127" - y="381.15677" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39570-5" /><tspan - sodipodi:role="line" - x="1072.3127" - y="381.15677" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - id="tspan39590-0" /></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1510.0886" - y="165.4404" - id="text39623-4-9"><tspan - sodipodi:role="line" - x="1510.0886" - y="165.4404" - id="tspan39625-9-1">1C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1510.017" - y="209.22543" - id="text39623-4-9-1"><tspan - sodipodi:role="line" - x="1510.017" - y="209.22543" - id="tspan39625-9-1-5">1H</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1510.3357" - y="386.13828" - id="text39623-4-9-0"><tspan - sodipodi:role="line" - x="1510.3357" - y="386.13828" - id="tspan39625-9-1-3">3C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1510.3572" - y="276.87189" - id="text39623-4-9-04"><tspan - sodipodi:role="line" - x="1510.3572" - y="276.87189" - id="tspan39625-9-1-4">2C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1510.2855" - y="320.65692" - id="text39623-4-9-1-4"><tspan - sodipodi:role="line" - x="1510.2855" - y="320.65692" - id="tspan39625-9-1-5-4">2H</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1312.6547" - y="1103.8405" - id="text39623-7"><tspan - sodipodi:role="line" - x="1312.6547" - y="1103.8405" - id="tspan5550">Brightness: Off, Low, High, Blinking</tspan></text> - <g - id="g5486" - transform="translate(4.1797945,-2.0898972)"> - <text - id="text39623-4" - y="384.38208" - x="1070.4884" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="384.38208" - x="1070.4884" - id="tspan39621-8" - sodipodi:role="line">3C. Smooth /</tspan><tspan - id="tspan5240" - y="400.51541" - x="1070.4884" - sodipodi:role="line" /><tspan - id="tspan5223" - y="416.64874" - x="1070.4884" - sodipodi:role="line">4C. Ramp Cfg</tspan><tspan - id="tspan5225" - y="432.78207" - x="1070.4884" - sodipodi:role="line">5C. Manual Memory</tspan><tspan - id="tspan5397" - y="448.91541" - x="1070.4884" - sodipodi:role="line">5H. Automatic Memory</tspan></text> - <text - id="text39623-4-5" - y="400.5062" - x="1099.3933" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan5397-7" - y="400.5062" - x="1099.3933" - sodipodi:role="line">Stepped ramp</tspan></text> - </g> - <g - id="g10115" - transform="matrix(0.80339488,0,0,0.80339488,265.139,209.38804)"> - <image - clip-path="url(#clipPath4663-1)" - transform="matrix(0.53333333,-0.92376043,0.92376043,0.53333333,462.65209,269.62078)" - width="62.81348" - height="62.813423" - preserveAspectRatio="none" - xlink:href="data:image/png;base64,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 " - id="image4618-1" - x="-325.4772" - y="1191.9255" /> - <g - transform="matrix(0.26666665,0,0,0.26666665,1109.8963,1020.4347)" - id="g7109"> - <path - style="fill:#000000;stroke-width:0.94693667" - d="m 1208.1597,502.25824 c -34.6326,-4.32593 -67.5133,-28.57627 -82.383,-60.75944 -12.8467,-27.80465 -12.8467,-61.60147 0,-89.40612 9.7942,-21.19809 29.0191,-40.74595 50.1059,-50.94757 35.3274,-17.09113 78.1788,-13.2618 109.0602,9.74593 53.9998,40.23171 58.8228,116.96375 10.2511,163.09238 -23.5191,22.33627 -54.3614,32.35596 -87.0342,28.27482 z m 24.1827,-6.50306 c 11.6943,-1.34018 21.6651,-4.13325 31.6647,-8.87003 12.0012,-5.68495 19.4819,-10.91833 28.505,-19.9414 39.0774,-39.0771 39.0935,-101.2754 0.036,-140.33228 -39.0376,-39.03726 -101.332,-39.03726 -140.3694,0 -39.0308,39.03052 -39.0308,101.48596 0,140.33228 9.0823,9.03938 16.5684,14.26979 28.5413,19.9414 16.6467,7.88554 34.0777,10.88063 51.6221,8.87003 z m -35.0726,-11.94697 c -9.3898,-2.7671 -19.4507,-7.43387 -25.7886,-11.96212 l -4.4827,-3.20262 3.6968,-3.60972 3.6968,-3.60972 2.8267,2.01277 c 5.0825,3.61909 18.4812,9.53498 25.7326,11.36174 l 7.1021,1.78909 0.2862,4.84668 c 0.2809,4.75606 0.2366,4.84572 -2.3673,4.79626 -1.4594,-0.0276 -6.2756,-1.11778 -10.7026,-2.42236 z m 37.1179,-2.3739 0.2863,-4.84668 7.1019,-1.78909 c 7.2608,-1.82911 20.6519,-7.74381 25.7486,-11.37297 l 2.8424,-2.02399 3.3864,3.38644 c 4.0359,4.03586 3.7514,4.63405 -4.6241,9.7219 -9.1961,5.58624 -26.2972,11.70606 -32.8476,11.75482 -2.0306,0.0152 -2.1604,-0.31623 -1.8939,-4.83043 z m -18.1791,-33.97762 c 0,-13.75716 -0.2786,-17.99392 -1.1837,-18.00099 -0.651,-0.005 -3.503,-1.0889 -6.3379,-2.40846 l -5.1543,-2.39923 -12.6012,12.5752 -12.6012,12.5752 -4.4848,-4.48478 -4.4848,-4.48478 12.5753,-12.60113 12.5753,-12.60114 -2.3992,-5.15422 c -1.3197,-2.83482 -2.4035,-5.68686 -2.4085,-6.33789 -0.01,-0.90508 -4.2439,-1.18366 -18.0011,-1.18366 h -17.9919 v -6.15507 -6.15507 h 17.509 17.5088 l 2.8794,-6.35003 2.8792,-6.35003 -12.5632,-12.58899 -12.5631,-12.58899 4.4848,-4.48478 4.4848,-4.48478 12.7147,12.68842 c 12.5449,12.51897 12.745,12.66857 14.9832,11.20209 1.2476,-0.81748 4.0486,-2.01969 6.2244,-2.67158 l 3.956,-1.18525 V 345.9849 328.14305 h 6.1552 6.1551 v 17.99174 c 0,13.75717 0.2785,17.99392 1.1837,18.00099 0.6509,0.005 3.503,1.0889 6.3378,2.40848 l 5.1543,2.39921 12.6012,-12.5752 12.6013,-12.5752 4.4847,4.48478 4.4849,4.48478 -12.5633,12.58899 -12.5632,12.58899 2.8794,6.35003 2.8791,6.35003 h 17.5091 17.509 v 6.15507 6.15507 h -17.9919 c -13.7573,0 -17.9941,0.27858 -18.0011,1.18366 0,0.65103 -1.0889,3.50307 -2.4085,6.33789 l -2.3993,5.15422 12.5753,12.60114 12.5754,12.60113 -4.4849,4.48478 -4.4847,4.48478 -12.6013,-12.5752 -12.6012,-12.5752 -5.1543,2.39923 c -2.8348,1.31956 -5.6869,2.40338 -6.3378,2.40846 -0.9052,0.007 -1.1837,4.24383 -1.1837,18.00099 v 17.99174 h -6.1551 -6.1552 z m -69.1946,-0.23673 c -5.9183,-8.15484 -12.4981,-24.40033 -13.7718,-34.00256 l -0.6225,-4.69292 4.9758,0.29071 4.9759,0.29069 1.6922,6.68101 c 2.1584,8.52045 5.8931,17.38899 10.0783,23.93151 l 3.29,5.14302 -3.0934,3.1915 c -1.7013,1.75533 -3.4332,3.19151 -3.8485,3.19151 -0.4154,0 -2.0696,-1.81102 -3.676,-4.02447 z m 143.1258,0.78233 -3.1425,-3.24213 2.0104,-2.82319 c 3.6169,-5.07942 9.5331,-18.47971 11.3593,-25.72909 l 1.7891,-7.102 4.8467,-0.28622 c 4.5851,-0.27078 4.8467,-0.16151 4.8467,2.02467 0,3.81305 -4.6291,18.63822 -8.0317,25.72262 -3.3326,6.93875 -8.4893,14.67748 -9.7804,14.67748 -0.4152,0 -2.1693,-1.45897 -3.8976,-3.24214 z m -157.2619,-65.16212 c 0,-3.20372 2.5101,-12.53902 5.2863,-19.66057 2.8865,-7.40436 10.7727,-20.83254 12.2348,-20.83254 0.5754,0 2.4603,1.45896 4.1887,3.24214 l 3.1423,3.24213 -2.0103,2.82317 c -3.6168,5.07943 -9.533,18.47971 -11.3592,25.7291 l -1.7891,7.10201 -4.8468,0.28621 c -4.5329,0.26769 -4.8467,0.14263 -4.8467,-1.93165 z m 169.0832,0.93523 c -0.1978,-0.65101 -0.8545,-3.31427 -1.4598,-5.91833 -1.6166,-6.95664 -5.4897,-16.21493 -9.6798,-23.13832 l -3.6877,-6.09352 3.7084,-3.70837 3.7084,-3.70837 4.3952,7.0518 c 5.09,8.16635 8.6536,16.43448 11.1242,25.80904 2.7635,10.4857 2.6529,10.88974 -2.9848,10.88974 -2.9886,0 -4.8985,-0.4412 -5.1241,-1.18367 z m -131.5545,-55.50477 -3.574,-3.66016 6.4205,-4.05491 c 3.5313,-2.2302 8.7227,-5.07302 11.5364,-6.31737 6.2701,-2.77292 20.3792,-6.92768 23.5255,-6.92768 2.1862,0 2.2955,0.26156 2.0247,4.84667 l -0.2862,4.84666 -6.9183,1.75257 c -8.1686,2.06927 -16.7209,5.70295 -23.6389,10.04357 -2.7444,1.72194 -5.1081,3.13081 -5.2528,3.13081 -0.1445,0 -1.8712,-1.64707 -3.8369,-3.66016 z m 94.5694,0.33445 c -5.7493,-3.87473 -14.7706,-7.65362 -23.6734,-9.91647 l -6.6286,-1.68477 -0.2863,-4.84666 c -0.2665,-4.51421 -0.1367,-4.84556 1.8939,-4.83044 2.9913,0.0222 14.331,3.09568 20.6454,5.59553 6.6994,2.65224 19.8858,10.54927 19.8858,11.90916 0,1.02385 -5.8283,7.16495 -6.6738,7.03199 -0.2356,-0.0371 -2.559,-1.50331 -5.163,-3.25834 z" - id="path7087" - inkscape:connector-curvature="0" /> - <ellipse - style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.49778914;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path7089" - cx="1222.4409" - cy="396.8504" - rx="34.040714" - ry="34.040607" /> - <path - style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.49778926;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path7089-3" - sodipodi:type="arc" - sodipodi:cx="1222.4409" - sodipodi:cy="396.8504" - sodipodi:rx="34.040714" - sodipodi:ry="34.040607" - sodipodi:start="4.712389" - sodipodi:end="1.5707963" - d="m 1222.4409,362.8098 a 34.040714,34.040607 0 0 1 34.0407,34.0406 34.040714,34.040607 0 0 1 -34.0407,34.04061 l 0,-34.04061 z" /> - </g> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1352.7787" - y="1188.7327" - id="text39623-7-4"><tspan - sodipodi:role="line" - x="1352.7787" - y="1188.7327" - id="tspan5550-1">Color: R, Y, G, C, B, V, W, Rainbow, Volts</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-3)" - d="m 1555.1266,1141.8934 c -50.2683,-0.2481 -46.5806,-28.9567 -108.0573,-27.528" - id="path5213-6-8-4-9-9-1-3-6-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-76-9-6)" - d="m 1555.1266,1141.8934 c -50.2683,0.2481 -46.5806,27.9715 -108.0573,26.5428" - id="path5213-6-8-4-9-9-1-3-6-7-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(1258.9411,301.76378)" - id="g58162-9-5"> - <ellipse - ry="29.092394" - rx="67.643234" - cy="838.49103" - cx="358.68741" - id="path3639-4-4-0-6" - style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text3021-8-4-1-8-8-20-3" - y="847.32025" - x="310.00983" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" - y="847.32025" - x="310.00983" - id="tspan3023-4-0-1-9-63-1-9" - sodipodi:role="line">Lockout</tspan></text> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1007.1519" - y="1445.0747" - id="text39623-7-6" - transform="rotate(-15)"><tspan - sodipodi:role="line" - x="1007.1519" - y="1445.0747" - id="tspan5550-4">7C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1598.1183" - y="771.31158" - id="text39623-7-6-3" - transform="rotate(15)"><tspan - sodipodi:role="line" - x="1598.1183" - y="771.31158" - id="tspan5550-4-3">7H</tspan></text> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-4-9-8" - width="642.51971" - height="113.38567" - x="1058.2677" - y="1084.7245" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1067.4176" - y="1115.4191" - id="text3021-8-4-1-8-8-2-6-8"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8-1-8" - x="1067.4176" - y="1115.4191" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672">Aux /</tspan><tspan - sodipodi:role="line" - x="1067.4176" - y="1152.0857" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672" - id="tspan10106">Button</tspan><tspan - sodipodi:role="line" - x="1067.4176" - y="1188.7524" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672" - id="tspan10108">LEDs</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1713.5479" - y="710.49811" - id="text39623-7-6-9" - transform="rotate(15)"><tspan - sodipodi:role="line" - x="1713.5479" - y="710.49811" - id="tspan5550-4-2">3C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1122.6094" - y="1505.6223" - id="text39623-7-6-3-5" - transform="rotate(-15)"><tspan - sodipodi:role="line" - x="1122.6094" - y="1505.6223" - id="tspan5550-4-3-4">3H</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="979.65771" - y="185.57895" - id="text39623-4-9-0-0"><tspan - sodipodi:role="line" - x="979.65771" - y="185.57895" - id="tspan39625-9-1-3-5">3C</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text39623-4-9-0-9" - transform="translate(2.6868986,-3.5825314)"><textPath - xlink:href="#path5213-6-8-4-9-9-8-3-7" - id="textPath13205"><tspan - id="tspan39625-9-1-3-4"> 3 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1046.6205" - y="1179.0468" - id="text39623-4-9-0-6" - transform="rotate(-15)"><tspan - sodipodi:role="line" - x="1046.6205" - y="1179.0468" - id="tspan39625-9-1-3-9">3C</tspan></text> - <path - style="fill:none;stroke:#040404;stroke-width:2.18300009;stroke-miterlimit:4;stroke-dasharray:13.09800053,2.18300009;stroke-dashoffset:6.76730027;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0-0-2)" - d="m 1130.3238,305.57915 c 48.1809,3.99296 64.2076,2.68523 79.9712,42.47521 42.8072,108.05255 131.144,142.50981 129.1171,41.94961" - id="path5213-6-8-4-9-9-9-29-5-2-7-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <g - id="g14919"> - <g - id="g58162-9" - transform="translate(861.28782,-266.43715)"> - <ellipse - style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-0" - cx="358.68741" - cy="838.49103" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="310.00983" - y="847.32025" - id="text3021-8-4-1-8-8-20"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-1" - x="310.00983" - y="847.32025" - style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Lockout</tspan></text> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.33333302px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1219.5195" - y="560.15283" - id="text3021-8-4-1-8-8-20-7"><tspan - id="tspan14800" - sodipodi:role="line" - x="1219.5195" - y="560.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Momentary</tspan><tspan - id="tspan14812" - sodipodi:role="line" - x="1219.5195" - y="568.48615" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14792" - sodipodi:role="line" - x="1221.642" - y="576.81952" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672"> </tspan><tspan - id="tspan14814" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14810" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14804" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14808" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14806" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14796" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14798" - sodipodi:role="line" - x="1219.5195" - y="585.15283" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672" /><tspan - id="tspan14794" - sodipodi:role="line" - x="1219.5195" - y="593.48615" - style="font-size:13.33333302px;line-height:1.25;text-align:center;text-anchor:middle;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Moon / Low</tspan></text> - </g> - <g - id="g14924"> - <path - inkscape:transform-center-y="3.5998252e-06" - inkscape:transform-center-x="-3.8865684" - transform="matrix(0.92707315,0,0,0.39837284,1506.7537,557.00764)" - d="m -228.62935,217.75388 c 0.12785,0.52537 -13.40141,4.84463 -13.59991,5.34758 -0.63708,1.61421 -6.04498,44.84898 -6.81448,46.40442 -0.23976,0.48464 -13.38015,-4.90306 -13.85549,-4.64537 -1.52563,0.82704 -33.45909,30.47067 -35.04838,31.16758 -0.49518,0.21714 -7.09816,-12.35655 -7.62794,-12.4647 -1.70031,-0.34709 -45.21732,1.83481 -46.88275,1.3471 -0.51891,-0.15196 2.50513,-14.02828 2.16882,-14.45166 -1.07941,-1.35883 -35.81787,-27.65959 -36.78017,-29.10372 -0.29983,-0.44995 10.93625,-9.13602 10.95076,-9.67652 0.0466,-1.73476 -9.65884,-44.21176 -9.46774,-45.93658 0.0596,-0.53741 14.25017,0.0311 14.60872,-0.37364 1.15075,-1.29896 21.01967,-40.07675 22.27476,-41.2752 0.39105,-0.37341 10.89628,9.18365 11.43109,9.10408 1.71649,-0.25538 41.86284,-17.18939 43.59465,-17.3007 0.53958,-0.0347 2.4439,14.03907 2.90473,14.32189 1.47906,0.90771 43.11793,13.74108 44.51611,14.769 0.43564,0.32027 -7.152,12.32546 -6.98077,12.83833 0.54955,1.64606 24.19764,38.24195 24.60799,39.92811 z" - inkscape:randomized="-6.9388939e-18" - inkscape:rounded="0.037" - inkscape:flatsided="false" - sodipodi:arg2="0.11055917" - sodipodi:arg1="0.026660495" - sodipodi:r2="68.11689" - sodipodi:r1="81.329819" - sodipodi:cy="215.58585" - sodipodi:cx="-309.93027" - sodipodi:sides="9" - id="path4327-0-3" - style="fill:url(#radialGradient5882-9-2);fill-opacity:1;stroke:#000000;stroke-width:3.75277472;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - sodipodi:type="star" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1221.3058" - y="659.65179" - id="text3021-8-4-1-8-8-20-7-5"><tspan - id="tspan14794-2" - sodipodi:role="line" - x="1221.3058" - y="659.65179" - style="font-size:12px;line-height:1.25;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke-width:1.06666672">On / Strobes</tspan></text> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.33333302px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1091.5458" - y="1212.6874" - id="text39629-1"><tspan - sodipodi:role="line" - x="1091.5458" - y="1212.6874" - id="tspan43995-1">Factory Reset: Loosen tailcap, Hold button, Tighten tailcap, Hold 3s (or 13H from Off)</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.29780102px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70212275px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1341.7825" - y="220.06078" - id="text39623-4-9-0-0-1" - transform="scale(0.99329477,1.0067505)"><tspan - sodipodi:role="line" - x="1341.7825" - y="220.06078" - id="tspan39625-9-1-3-5-0" - style="stroke-width:0.70212275px">3C</tspan></text> - <g - id="g21114" - transform="matrix(0.5165354,0,0,0.5165354,676.70758,110.93007)"> - <path - style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.13333344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:4.26666689;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" - d="m 1263.3125,222.54688 h 4.2676 v -2.13282 h -4.2676 z m 8.5332,0 h 4.2676 v -2.13282 h -4.2676 z m 8.5332,0 h 4.2676 v -2.13282 h -4.2676 z m 8.5352,0 h 4.2656 v -2.13282 h -4.2656 z m 8.5332,0 h 4.2656 v -2.13282 h -4.2656 z" - id="path5213-6-8-4-9-9-8-3-3" - inkscape:connector-curvature="0" /> - <path - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.85333344pt;stroke-opacity:1" - d="m 1267.5798,221.48082 4.2667,-4.26667 -14.9333,4.26667 14.9333,4.26667 z" - id="path21120" - inkscape:connector-curvature="0" /> - <path - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.85333344pt;stroke-opacity:1" - d="m 1297.3647,221.48082 -4.2667,4.26667 14.9333,-4.26667 -14.9333,-4.26667 z" - id="path21122" - inkscape:connector-curvature="0" /> - </g> - <path - style="opacity:1;fill:none;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4,4;stroke-dashoffset:3.4;stroke-opacity:1" - d="m 1319.7047,390.82553 h 19.4452 l 0,-16.40309 h 28.99 16.1451" - id="path15687-9-5-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="ccccc" /> - </g> -</svg> diff --git a/spaghetti-monster/anduril/anduril.txt b/spaghetti-monster/anduril/anduril.txt deleted file mode 100644 index 0a3dc4c..0000000 --- a/spaghetti-monster/anduril/anduril.txt +++ /dev/null @@ -1,191 +0,0 @@ -From off: - - Ramp shortcuts: - * 1 click: memorized level - * Hold: lowest level then ramp up - * 2 clicks: highest ramp level - * Click, hold: highest level then ramp down - - Blinkies: - * 3 clicks: specials (battcheck, goodnight, beacon, tempcheck) - * Click, click, hold: strobes - (candle mode, bike flasher, party strobe, tactical strobe, - lightning storm mode) - (remembers which you last used) - - Other: - * 4 clicks: lock-out - * 5 clicks: momentary mode (disconnect power to exit) - * 6 clicks: muggle mode - * On hardware with an indicator LED... - * 7 clicks: Change aux LED mode used in "off" mode. - (the modes are usually off/low/high/blinking) - * 7 clicks (but hold the last click): - Change aux LED color used in "off" mode. - -In steady / ramping mode: - * 1 click: off - * Hold: ramp up - * Click, hold: ramp down - * 2 clicks: to/from turbo (actual turbo, not just highest ramp level) - * 3 clicks: toggle smooth vs discrete ramping - * 4 clicks: configure current ramp - * 5 clicks: activate manual memory and save current brightness - * 5 clicks (but hold the last click): go back to automatic memory - -Smooth ramp config mode: - * Setting 1: low end - (click N times to set ramp floor to level N) - * Setting 2: high end - (click N times to set ramp ceiling to level "151 - N") - -Discrete ramp config mode: - * Setting 1: low end - (click N times to set ramp floor to level N) - * Setting 2: high end - (click N times to set ramp ceiling to level "151 - N") - * Setting 3: number of levels in discrete ramp - (click N times to make discrete mode have N stair-steps) - (minimum 2, maximum 150) - -"Strobe" group modes: - - Candle mode: - * 1 click: off - * 2 clicks: next "strobe" group mode - * 3 clicks: add 30 minutes to the timer - (light will shut off when timer expires) - (default is no timer) - * Hold: brighter - * Click, hold: dimmer - - Bike flasher: - * 1 click: off - * 2 clicks: next "strobe" group mode - * Hold: brighter - * Click, hold: dimmer - - Party / Tactical strobe modes: - * 1 click: off - * Hold: change speed (faster) - * Click, hold: change speed (slower) - * 2 clicks: next "strobe" group mode - (TODO: random/police strobe?) - - Lightning storm mode: - * 1 click: off - * 2 clicks: next "strobe" group mode - -"Blinky" group modes: - - Battcheck mode: - * 1 click: off - * 2 clicks: goodnight mode - - Goodnight mode: - * 1 click: off - * 2 clicks: beacon mode - - Beacon mode: - * 1 click: off - * 2 clicks: tempcheck mode - * 4 clicks: configure time between pulses - - Beacon config mode: - * At buzz, click N times to set beacon frequency to N seconds. - - Tempcheck mode: - * 1 click: off - * 2 clicks: battcheck mode - * 4 clicks: thermal config mode - - Thermal config mode: - * Setting 1: calibrate sensor: - At buzz, click N times for N degrees C. For example, if the light - is current at "room temperature" of 22 C, click 22 times. Is - intended to only be done once upon initial setup, or not at all. - * Setting 2: temperature limit: - At buzz, click N times to set thermal limit to roughly 30 C + N. - -Lockout mode: - * Hold: momentary moon (current ramp floor) - * Click, Hold: momentary moon (other ramp floor) - * 4 clicks: exit lockout (return to regular "off" mode) - * On hardware with an indicator LED... - * 3 clicks: Change aux LED brightness used in lockout mode. - (the modes are usually off/low/high/blinking) - * 3 clicks (but hold the last click): - Change aux LED color used in lockout mode. - -Momentary mode: - * Press button: Light on (at memorized mode/level). - (uses either a steady mode or a strobe-group mode) - * Release button: Light off. - * To exit, disconnect power. (loosen/tighten the tailcap) - -Muggle mode: - * 1 click: On / off. - * Hold: Ramp up / down. - * 6 clicks: Exit muggle mode. - -Indicator LED / aux LED support: - - The indicator LED (button LED), if there is one, tracks the brightness - of the main LED(s) during use. It'll be off, low, or high depending - on whether the main emitter is off, using only the first power - channel, or using a higher level. - - If front-facing aux LEDs are present, they stay off while the main - light is on. They only turn on when the main emitters are off. - - The indicator LED can stay on when the light is in the "off" state or - "lockout" state. These modes can have different settings, to make it - easier to see which one the light is in. To configure it: - - 1. Go to the standby mode you want to configure. This is either - "off" or "lockout". - 2. In "off" mode, click 7 times to switch to the next aux LED mode. - Or in "lockout" mode, click 3 times. - 3. Repeat step 2 until the desired mode is reached. - - The available aux LED / indicator LED modes vary depending on the type - of light, but they typically have the following modes: - - - Off - - Low - - High - - Blinking - - If the aux LEDs can change color, the user can configure the color - using exactly the same method... except hold the last click until the - desired color is reached. - - -TODO: - - change 6C to 6H for exiting muggle mode? - - move muggle mode from 6C to ... 8C or something? - - add 4H from lockout to turn light on and start ramping up? - - move config modes to 5C instead of 4C, and move manual memory to 4C? - - remove beacon config mode, and use a hold to set timing instead? - - rewrite muggle mode to split it into on and off states - * save settings in eeprom - * decide on "hold until hot" or "click N times" for thermal config mode - * test thermal regulation on an actual light - * improve thermal regulation - - a way to blink out the firmware version? - * indicator LED support - * a way to configure indicator LED behavior - * Go to lockout mode, then click three times. Hold the third click - to change regular "off" brightness, or make it a fast click to - change lockout mode brightness. - * add goodnight mode? - * add lightning mode? - * muggle mode: smooth ramp - * refactor to make config modes smaller - * move all config menus to four clicks - * candle mode timer, with three clicks to add 30 minutes - * diagram updates for 3-click special actions - * add a toggle for memory (manual vs automatic memory) - - candle mode: smoother adjustments? - - make sunset mode timer and brightness configurable? - - make beacon mode actually sleep between pulses diff --git a/spaghetti-monster/anduril/aux-leds.c b/spaghetti-monster/anduril/aux-leds.c deleted file mode 100644 index af59aa6..0000000 --- a/spaghetti-monster/anduril/aux-leds.c +++ /dev/null @@ -1,210 +0,0 @@ -// aux-leds.c: Aux LED functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "aux-leds.h" - - -#if defined(USE_INDICATOR_LED) -void indicator_led_update(uint8_t mode, uint8_t tick) { - //uint8_t volts = voltage; // save a few bytes by caching volatile value - // turn off when battery is too low - #ifdef DUAL_VOLTAGE_FLOOR - if (((voltage < VOLTAGE_LOW) && (voltage > DUAL_VOLTAGE_FLOOR)) - || (voltage < DUAL_VOLTAGE_LOW_LOW)) { - #else - if (voltage < VOLTAGE_LOW) { - #endif - indicator_led(0); - } - //#ifdef USE_INDICATOR_LOW_BAT_WARNING - #ifndef DUAL_VOLTAGE_FLOOR // this isn't set up for dual-voltage lights like the Sofirn SP10 Pro - // fast blink a warning when battery is low but not critical - else if (voltage < VOLTAGE_RED) { - indicator_led(mode & (((tick & 0b0010)>>1) - 3)); - } - #endif - //#endif - // normal steady output, 0/1/2 = off / low / high - else if ((mode & 0b00001111) < 3) { - indicator_led(mode); - } - // beacon-like blinky mode - else { - #ifdef USE_OLD_BLINKING_INDICATOR - - // basic blink, 1/8th duty cycle - if (! (tick & 7)) { - indicator_led(2); - } - else { - indicator_led(0); - } - - #else - - // fancy blink, set off/low/high levels here: - static const uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0}; - indicator_led(seq[tick & 15]); - - #endif // ifdef USE_OLD_BLINKING_INDICATOR - } -} -#endif - -#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) -uint8_t voltage_to_rgb() { - static const uint8_t levels[] = { - // voltage, color - 0, 0, // black - #ifdef DUAL_VOLTAGE_FLOOR - // AA / NiMH voltages - 9, 1, // R - 10, 2, // R+G - 11, 3, // G - 12, 4, // G+B - 13, 5, // B - 14, 6, // R + B - 15, 7, // R+G+B - 20, 0, // black - #endif - // li-ion voltages - 29, 1, // R - 33, 2, // R+G - 35, 3, // G - 37, 4, // G+B - 39, 5, // B - 41, 6, // R + B - 44, 7, // R+G+B // skip; looks too similar to G+B - 255, 7, // R+G+B - }; - uint8_t volts = voltage; - //if (volts < VOLTAGE_LOW) return 0; - - uint8_t i; - for (i = 0; volts >= levels[i]; i += 2) {} - uint8_t color_num = levels[(i - 2) + 1]; - return pgm_read_byte(rgb_led_colors + color_num); -} - -// do fancy stuff with the RGB aux LEDs -// mode: 0bPPPPCCCC where PPPP is the pattern and CCCC is the color -// arg: time slice number -void rgb_led_update(uint8_t mode, uint16_t arg) { - static uint8_t rainbow = 0; // track state of rainbow mode - static uint8_t frame = 0; // track state of animation mode - - // turn off aux LEDs when battery is empty - // (but if voltage==0, that means we just booted and don't know yet) - uint8_t volts = voltage; // save a few bytes by caching volatile value - #ifdef DUAL_VOLTAGE_FLOOR - if ((volts) && (((voltage < VOLTAGE_LOW) && (voltage > DUAL_VOLTAGE_FLOOR)) || (voltage < DUAL_VOLTAGE_LOW_LOW))) { - #else - if ((volts) && (volts < VOLTAGE_LOW)) { - #endif - rgb_led_set(0); - #ifdef USE_BUTTON_LED - button_led_set(0); - #endif - return; - } - - uint8_t pattern = (mode>>4); // off, low, high, blinking, ... more? - uint8_t color = mode & 0x0f; - - // always preview in high mode - if (setting_rgb_mode_now) { pattern = 2; } - - #ifdef USE_POST_OFF_VOLTAGE - // use voltage high mode for a few seconds after initial poweroff - // (but not after changing aux LED settings and other similar actions) - else if ((arg < (cfg.post_off_voltage * SLEEP_TICKS_PER_SECOND)) - && (ticks_since_on < (cfg.post_off_voltage * SLEEP_TICKS_PER_SECOND)) - && (ticks_since_on > 0) // don't blink red on 1st frame - ) { - // use high mode if regular aux level is high or prev level was high - pattern = 1 + ((2 == pattern) | (prev_level >= POST_OFF_VOLTAGE_BRIGHTNESS)); - // voltage mode - color = RGB_LED_NUM_COLORS - 1; - } - #endif - - const uint8_t *colors = rgb_led_colors + 1; - uint8_t actual_color = 0; - if (color < 7) { // normal color - actual_color = pgm_read_byte(colors + color); - } - else if (color == 7) { // disco - rainbow = (rainbow + 1 + pseudo_rand() % 5) % 6; - actual_color = pgm_read_byte(colors + rainbow); - } - else if (color == 8) { // rainbow - uint8_t speed = 0x03; // awake speed - if (go_to_standby) speed = RGB_RAINBOW_SPEED; // asleep speed - if (0 == (arg & speed)) { - rainbow = (rainbow + 1) % 6; - } - actual_color = pgm_read_byte(colors + rainbow); - } - else { // voltage - // show actual voltage while asleep... - if (go_to_standby) { - actual_color = voltage_to_rgb(); - // choose a color based on battery voltage - //if (volts >= 38) actual_color = pgm_read_byte(colors + 4); - //else if (volts >= 33) actual_color = pgm_read_byte(colors + 2); - //else actual_color = pgm_read_byte(colors + 0); - } - // ... but during preview, cycle colors quickly - else { - actual_color = pgm_read_byte(colors + (((arg>>1) % 3) << 1)); - } - } - - // pick a brightness from the animation sequence - if (pattern == 3) { - // uses an odd length to avoid lining up with rainbow loop - static const uint8_t animation[] = {2, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - frame = (frame + 1) % sizeof(animation); - pattern = animation[frame]; - } - uint8_t result; - #ifdef USE_BUTTON_LED - uint8_t button_led_result; - #endif - switch (pattern) { - case 0: // off - result = 0; - #ifdef USE_BUTTON_LED - button_led_result = 0; - #endif - break; - case 1: // low - result = actual_color; - #ifdef USE_BUTTON_LED - button_led_result = 1; - #endif - break; - default: // high - result = (actual_color << 1); - #ifdef USE_BUTTON_LED - button_led_result = 2; - #endif - break; - } - rgb_led_set(result); - #ifdef USE_BUTTON_LED - button_led_set(button_led_result); - #endif -} - -void rgb_led_voltage_readout(uint8_t bright) { - uint8_t color = voltage_to_rgb(); - if (bright) color = color << 1; - rgb_led_set(color); -} -#endif - diff --git a/spaghetti-monster/anduril/aux-leds.h b/spaghetti-monster/anduril/aux-leds.h deleted file mode 100644 index fa97e6b..0000000 --- a/spaghetti-monster/anduril/aux-leds.h +++ /dev/null @@ -1,65 +0,0 @@ -// aux-leds.h: Aux LED functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) -void indicator_led_update(uint8_t mode, uint8_t tick); -#endif -#if defined(USE_AUX_RGB_LEDS) && defined(TICK_DURING_STANDBY) -uint8_t setting_rgb_mode_now = 0; -void rgb_led_update(uint8_t mode, uint16_t arg); -void rgb_led_voltage_readout(uint8_t bright); -/* - * 0: R - * 1: RG - * 2: G - * 3: GB - * 4: B - * 5: R B - * 6: RGB - * 7: rainbow - * 8: voltage - */ -const PROGMEM uint8_t rgb_led_colors[] = { - 0b00000000, // 0: black - 0b00000001, // 1: red - 0b00000101, // 2: yellow - 0b00000100, // 3: green - 0b00010100, // 4: cyan - 0b00010000, // 5: blue - 0b00010001, // 6: purple - 0b00010101, // 7: white -}; -// intentionally 1 higher than total modes, to make "voltage" easier to reach -// (at Hank's request) -#define RGB_LED_NUM_COLORS 11 -#define RGB_LED_NUM_PATTERNS 4 -#ifndef RGB_LED_OFF_DEFAULT -#define RGB_LED_OFF_DEFAULT 0x19 // low, voltage -//#define RGB_LED_OFF_DEFAULT 0x18 // low, rainbow -#endif -#ifndef RGB_LED_LOCKOUT_DEFAULT -#define RGB_LED_LOCKOUT_DEFAULT 0x39 // blinking, voltage -//#define RGB_LED_LOCKOUT_DEFAULT 0x37 // blinking, disco -#endif -#ifndef RGB_RAINBOW_SPEED -#define RGB_RAINBOW_SPEED 0x0f // change color every 16 frames -#endif -#endif - -//#define USE_OLD_BLINKING_INDICATOR -//#define USE_FANCIER_BLINKING_INDICATOR -#ifdef USE_INDICATOR_LED - // bits 2-3 control lockout mode - // bits 0-1 control "off" mode - // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled) - #ifndef INDICATOR_LED_DEFAULT_MODE - #ifdef USE_INDICATOR_LED_WHILE_RAMPING - #define INDICATOR_LED_DEFAULT_MODE ((2<<2) + 1) - #else - #define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - #endif - #endif -#endif - diff --git a/spaghetti-monster/anduril/battcheck-mode-fsm.h b/spaghetti-monster/anduril/battcheck-mode-fsm.h deleted file mode 100644 index 5f8e8ec..0000000 --- a/spaghetti-monster/anduril/battcheck-mode-fsm.h +++ /dev/null @@ -1,18 +0,0 @@ -// battcheck-mode-fsm.h: FSM config for battery check mode in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define USE_BATTCHECK - -#ifdef USE_AUX_RGB_LEDS - // show voltage colors for a few seconds after going to standby - #define USE_POST_OFF_VOLTAGE - #ifndef DEFAULT_POST_OFF_VOLTAGE_SECONDS - #define DEFAULT_POST_OFF_VOLTAGE_SECONDS 4 - #endif - #ifndef POST_OFF_VOLTAGE_BRIGHTNESS - // level at which to switch from low to high aux brightness - #define POST_OFF_VOLTAGE_BRIGHTNESS (RAMP_SIZE/10) - #endif -#endif diff --git a/spaghetti-monster/anduril/battcheck-mode.c b/spaghetti-monster/anduril/battcheck-mode.c deleted file mode 100644 index 462540e..0000000 --- a/spaghetti-monster/anduril/battcheck-mode.c +++ /dev/null @@ -1,82 +0,0 @@ -// battcheck-mode.c: Battery check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "battcheck-mode.h" - -uint8_t battcheck_state(Event event, uint16_t arg) { - ////////// Every action below here is blocked in the simple UI ////////// - #ifdef USE_SIMPLE_UI - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - - // 2 clicks: next blinky mode - else if (event == EV_2clicks) { - #if defined(USE_THERMAL_REGULATION) - set_state(tempcheck_state, 0); - #elif defined(USE_BEACON_MODE) - set_state(beacon_state, 0); - #elif defined(USE_SOS_MODE) && defined(USE_SOS_MODE_IN_BLINKY_GROUP) - set_state(sos_state, 0); - #endif - return EVENT_HANDLED; - } - - #ifdef DEFAULT_BLINK_CHANNEL - // 3 clicks: next channel mode (specific to number blinky modes) - else if (event == EV_3clicks) { - cfg.blink_channel = (cfg.blink_channel + 1) % NUM_CHANNEL_MODES; - save_config(); - return EVENT_HANDLED; - } - #endif // ifdef DEFAULT_BLINK_CHANNEL - - #ifdef USE_VOLTAGE_CORRECTION - // 7H: voltage config mode - else if (event == EV_click7_hold) { - push_state(voltage_config_state, 0); - return EVENT_HANDLED; - } - #endif - - return EVENT_NOT_HANDLED; -} - -#ifdef USE_VOLTAGE_CORRECTION -// the user can adjust the battery measurements... on a scale of 1 to 13 -// 1 = subtract 0.30V -// 2 = subtract 0.25V -// ... -// 7 = no effect (add 0V) -// 8 = add 0.05V -// ... -// 13 = add 0.30V -void voltage_config_save(uint8_t step, uint8_t value) { - #ifdef USE_POST_OFF_VOLTAGE - if (2 == step) cfg.post_off_voltage = value; - else - #endif - if (value) cfg.voltage_correction = value; -} - -uint8_t voltage_config_state(Event event, uint16_t arg) { - #ifdef USE_POST_OFF_VOLTAGE - #define VOLTAGE_CONFIG_STEPS 2 - #else - #define VOLTAGE_CONFIG_STEPS 1 - #endif - return config_state_base(event, arg, - VOLTAGE_CONFIG_STEPS, - voltage_config_save); -} -#endif // #ifdef USE_VOLTAGE_CORRECTION - diff --git a/spaghetti-monster/anduril/battcheck-mode.h b/spaghetti-monster/anduril/battcheck-mode.h deleted file mode 100644 index b505b68..0000000 --- a/spaghetti-monster/anduril/battcheck-mode.h +++ /dev/null @@ -1,12 +0,0 @@ -// battcheck-mode.h: Battery check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -uint8_t battcheck_state(Event event, uint16_t arg); - -#ifdef USE_VOLTAGE_CORRECTION -void voltage_config_save(uint8_t step, uint8_t value); -uint8_t voltage_config_state(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/anduril/beacon-mode.c b/spaghetti-monster/anduril/beacon-mode.c deleted file mode 100644 index 5aff508..0000000 --- a/spaghetti-monster/anduril/beacon-mode.c +++ /dev/null @@ -1,53 +0,0 @@ -// beacon-mode.c: Beacon mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "beacon-mode.h" - -inline void beacon_mode_iter() { - // one iteration of main loop() - if (! button_last_state) { - set_level(memorized_level); - nice_delay_ms(100); - set_level(0); - nice_delay_ms(((cfg.beacon_seconds) * 1000) - 100); - } -} - -uint8_t beacon_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // TODO: use sleep ticks to measure time between pulses, - // to save power - - // 2 clicks: next blinky mode - else if (event == EV_2clicks) { - #if defined(USE_SOS_MODE) && defined(USE_SOS_MODE_IN_BLINKY_GROUP) - set_state(sos_state, 0); - #elif defined(USE_BATTCHECK) - set_state(battcheck_state, 0); - #elif defined(USE_THERMAL_REGULATION) - set_state(tempcheck_state, 0); - #endif - return EVENT_HANDLED; - } - // hold: configure beacon timing - else if (event == EV_click1_hold) { - if (0 == (arg % TICKS_PER_SECOND)) { - blink_once(); - } - return EVENT_HANDLED; - } - // release hold: save new timing - else if (event == EV_click1_hold_release) { - cfg.beacon_seconds = 1 + (arg / TICKS_PER_SECOND); - save_config(); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/beacon-mode.h b/spaghetti-monster/anduril/beacon-mode.h deleted file mode 100644 index df047ad..0000000 --- a/spaghetti-monster/anduril/beacon-mode.h +++ /dev/null @@ -1,9 +0,0 @@ -// beacon-mode.h: Beacon mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// beacon mode -uint8_t beacon_state(Event event, uint16_t arg); -inline void beacon_mode_iter(); - diff --git a/spaghetti-monster/anduril/build-all.sh b/spaghetti-monster/anduril/build-all.sh deleted file mode 100755 index b3fc5d3..0000000 --- a/spaghetti-monster/anduril/build-all.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh - -# Usage: build-all.sh [pattern] -# If pattern given, only build targets which match. - -if [ ! -z "$1" ]; then - SEARCH="$1" -fi - -UI=anduril - -date '+#define VERSION_NUMBER "%Y-%m-%d"' > version.h - -PASS=0 -FAIL=0 -PASSED='' -FAILED='' - -for TARGET in cfg-*.h ; do - - # maybe limit builds to a specific pattern - if [ ! -z "$SEARCH" ]; then - echo "$TARGET" | grep -i "$SEARCH" > /dev/null - if [ 0 != $? ]; then continue ; fi - fi - - # friendly name for this build - NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";') - echo "===== $NAME =====" - - # figure out MCU type - ATTINY=$(grep 'ATTINY:' $TARGET | awk '{ print $3 }') - if [ -z "$ATTINY" ]; then ATTINY=85 ; fi - - # try to compile - echo ../../../bin/build.sh $ATTINY "$UI" "-DCFG_H=${TARGET}" - ../../../bin/build.sh $ATTINY "$UI" "-DCFG_H=${TARGET}" - - # track result, and rename compiled files - if [ 0 = $? ] ; then - mv -f "$UI".hex "$UI".$NAME.hex - PASS=$(($PASS + 1)) - PASSED="$PASSED $NAME" - else - echo "ERROR: build failed" - FAIL=$(($FAIL + 1)) - FAILED="$FAILED $NAME" - fi - -done - -# summary -echo "===== $PASS builds succeeded, $FAIL failed =====" -#echo "PASS: $PASSED" -if [ 0 != $FAIL ]; then - echo "FAIL:$FAILED" -fi diff --git a/spaghetti-monster/anduril/candle-mode.c b/spaghetti-monster/anduril/candle-mode.c deleted file mode 100644 index ab47c34..0000000 --- a/spaghetti-monster/anduril/candle-mode.c +++ /dev/null @@ -1,136 +0,0 @@ -// candle-mode.c: Candle mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "candle-mode.h" - -#ifdef USE_SUNSET_TIMER -#include "sunset-timer.h" -#endif - -uint8_t candle_mode_state(Event event, uint16_t arg) { - static int8_t ramp_direction = 1; - #define MAX_CANDLE_LEVEL (MAX_LEVEL-CANDLE_AMPLITUDE-15) - static uint8_t candle_wave1 = 0; - static uint8_t candle_wave2 = 0; - static uint8_t candle_wave3 = 0; - static uint8_t candle_wave2_speed = 0; - // these should add up to 100 - #define CANDLE_WAVE1_MAXDEPTH 30 - #define CANDLE_WAVE2_MAXDEPTH 45 - #define CANDLE_WAVE3_MAXDEPTH 25 - static const uint8_t candle_wave1_depth = CANDLE_WAVE1_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_wave2_depth = CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_wave3_depth = CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_mode_brightness = 24; - - #ifdef USE_SUNSET_TIMER - // let the candle "burn out" and shut itself off - // if the user told it to - // cache this in case it changes when the timer is called - uint8_t sunset_active = sunset_timer; - // clock tick - sunset_timer_state(event, arg); - // if the timer just expired, shut off - if (sunset_active && (! sunset_timer)) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - #endif // ifdef USE_SUNSET_TIMER - - - if (event == EV_enter_state) { - ramp_direction = 1; - return EVENT_HANDLED; - } - #ifdef USE_SUNSET_TIMER - // 2 clicks: cancel timer - else if (event == EV_2clicks) { - // parent state just rotated through strobe/flasher modes, - // so cancel timer... in case any time was left over from earlier - sunset_timer = 0; - return EVENT_HANDLED; - } - #endif // ifdef USE_SUNSET_TIMER - // hold: change brightness (brighter) - else if (event == EV_click1_hold) { - // ramp away from extremes - if (! arg) { - if (candle_mode_brightness >= MAX_CANDLE_LEVEL) { ramp_direction = -1; } - else if (candle_mode_brightness <= 1) { ramp_direction = 1; } - } - // change brightness, but not too far - candle_mode_brightness += ramp_direction; - if (candle_mode_brightness < 1) candle_mode_brightness = 1; - else if (candle_mode_brightness > MAX_CANDLE_LEVEL) candle_mode_brightness = MAX_CANDLE_LEVEL; - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - ramp_direction = -ramp_direction; - return EVENT_HANDLED; - } - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - ramp_direction = 1; - if (candle_mode_brightness > 1) - candle_mode_brightness --; - return EVENT_HANDLED; - } - // clock tick: animate candle brightness - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == AUTO_REVERSE_TIME) ramp_direction = 1; - - // 3-oscillator synth for a relatively organic pattern - uint8_t add; - add = ((triangle_wave(candle_wave1) * candle_wave1_depth) >> 8) - + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8) - + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8); - uint16_t brightness = candle_mode_brightness + add; - - // self-timer dims the light during the final minute - #ifdef USE_SUNSET_TIMER - if (1 == sunset_timer) { - brightness = brightness - * ((TICKS_PER_MINUTE>>5) - (sunset_ticks>>5)) - / (TICKS_PER_MINUTE>>5); - } - #endif // ifdef USE_SUNSET_TIMER - - set_level(brightness); - - // wave1: slow random LFO - // TODO: make wave slower and more erratic? - if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1; - // wave2: medium-speed erratic LFO - candle_wave2 += candle_wave2_speed; - // wave3: erratic fast wave - candle_wave3 += pseudo_rand() % 37; - // S&H on wave2 frequency to make it more erratic - if ((pseudo_rand() & 0b00111111) == 0) - candle_wave2_speed = pseudo_rand() % 13; - // downward sawtooth on wave2 depth to simulate stabilizing - if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0)) - candle_wave2_depth --; - // random sawtooth retrigger - if (pseudo_rand() == 0) { - // random amplitude - //candle_wave2_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); - candle_wave2_depth = pseudo_rand() % (CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100); - //candle_wave3_depth = 5; - candle_wave2 = 0; - } - // downward sawtooth on wave3 depth to simulate stabilizing - if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0)) - candle_wave3_depth --; - if ((pseudo_rand() & 0b01111111) == 0) - // random amplitude - //candle_wave3_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); - candle_wave3_depth = pseudo_rand() % (CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/candle-mode.h b/spaghetti-monster/anduril/candle-mode.h deleted file mode 100644 index aab237d..0000000 --- a/spaghetti-monster/anduril/candle-mode.h +++ /dev/null @@ -1,13 +0,0 @@ -// candle-mode.h: Candle mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#ifndef CANDLE_AMPLITUDE -#define CANDLE_AMPLITUDE 25 -#endif - -uint8_t candle_mode_state(Event event, uint16_t arg); -// moved to fsm-misc.c because it's also used for tint ramping power correction -//uint8_t triangle_wave(uint8_t phase); - diff --git a/spaghetti-monster/anduril/cfg-blf-gt-mini.h b/spaghetti-monster/anduril/cfg-blf-gt-mini.h deleted file mode 100644 index 083f18e..0000000 --- a/spaghetti-monster/anduril/cfg-blf-gt-mini.h +++ /dev/null @@ -1,25 +0,0 @@ -// BLF/Lumintop GT Mini config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "hwdef-blf-gt-mini.h" -// Same as an Emisar D1S, except it has a lighted button -#include "cfg-emisar-d1s.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0322" - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING - -// too big, remove stuff to make room -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE -//#undef USE_RAMP_AFTER_MOON_CONFIG -//#undef USE_RAMP_SPEED_CONFIG -//#undef USE_VOLTAGE_CORRECTION -//#undef USE_2C_STYLE_CONFIG -//#undef USE_TACTICAL_STROBE_MODE - diff --git a/spaghetti-monster/anduril/cfg-blf-gt.h b/spaghetti-monster/anduril/cfg-blf-gt.h deleted file mode 100644 index 580318a..0000000 --- a/spaghetti-monster/anduril/cfg-blf-gt.h +++ /dev/null @@ -1,62 +0,0 @@ -// BLF GT config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0321" -#include "hwdef-blf-gt.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING - -#define RAMP_SIZE 150 - -// First 60 values: level_calc.py 1 60 7135 4 5.0 255 -// Remainder: all 255 (buck driver at 100% duty cycle) -#define PWM1_LEVELS 4,5,6,6,7,8,9,11,12,13,15,16,18,19,21,23,25,27,30,32,34,37,40,43,46,49,52,55,59,63,66,70,75,79,83,88,93,98,103,108,114,119,125,131,137,144,150,157,164,171,179,186,194,202,210,219,228,236,246,255, \ - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// First 60 values: all 25 (buck driver at 10% power) -// Remainder: values 61-150 of level_calc.py 1 150 7135 1 3 3000 -#define PWM2_LEVELS 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, \ - 26,27,28,29,30,31,32,33,35,36,37,38,40,41,42,44,45,47,48,50,51,53,54,56,58,59,61,63,65,67,69,70,72,74,76,79,81,83,85,87,89,92,94,96,99,101,104,106,109,112,114,117,120,123,125,128,131,134,137,140,143,147,150,153,156,160,163,167,170,174,177,181,184,188,192,196,200,204,208,212,216,220,224,228,233,237,241,246,250,255 -#define POWER_80PX 138 // 2.0 Amps out of maximum 2.5 Amps -#define MAX_1x7135 60 // where it switches from PWM to current control -#define DEFAULT_LEVEL 69 // nice -#define HALFSPEED_LEVEL 17 -#define QUARTERSPEED_LEVEL 6 - -// use 2.0 A as the ceiling, 2.5 A only for turbo -// start both ramps at the bottom; even moon throws a long way on the GT -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL POWER_80PX -// 1 23 46 [69] 92 115 138 -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL POWER_80PX -#define RAMP_DISCRETE_STEPS 7 - -// GT can handle heat well, so don't limit simple mode -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// smoother, more wobbly candle -#define CANDLE_AMPLITUDE 33 - -// turbo (i.e. "giggles" mode), low, tactical strobe -#define TACTICAL_LEVELS 150,30,(RAMP_SIZE+2) - -// stop panicking at 80% power, this light has plenty of thermal mass -#define THERM_FASTER_LEVEL POWER_80PX // throttle back faster when high - -// don't blink during ramp, it's irrelevant and annoying on this light -#undef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_FLOOR - -// too big, turn off extra features -//#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE - diff --git a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h b/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h deleted file mode 100644 index fc02619..0000000 --- a/spaghetti-monster/anduril/cfg-blf-lantern-t1616.h +++ /dev/null @@ -1,110 +0,0 @@ -// BLF Lantern config options for Anduril using the Attiny1616 -// Copyright (C) 2021-2023 (original author TBD), Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0622" -#include "hwdef-blf-lt1-t1616.h" -// ATTINY: 1616 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -#define DEFAULT_CHANNEL_MODE CM_AUTO -#define DEFAULT_BLINK_CHANNEL CM_BOTH - -#define CONFIG_WAITING_CHANNEL CM_BOTH -#define CONFIG_BLINK_CHANNEL CM_BOTH - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_BOTH - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -//#define TINT_RAMPING_CORRECTION 26 // prototype, 140% -#define TINT_RAMPING_CORRECTION 10 // production model, 115% - -#define RAMP_SIZE 150 -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -// level_calc.py 3.333 1 150 7135 32 0.2 600 --pwm 32640 -#define PWM1_LEVELS 4,35,38,41,45,50,55,61,67,74,82,91,100,110,121,133,146,160,175,192,209,227,247,268,291,314,340,366,395,424,456,489,524,560,599,639,681,726,772,820,871,924,979,1036,1096,1158,1222,1289,1359,1431,1506,1584,1664,1747,1834,1923,2015,2111,2209,2311,2416,2524,2636,2751,2870,2992,3118,3247,3380,3518,3659,3803,3952,4105,4262,4423,4589,4759,4933,5111,5294,5482,5674,5871,6073,6279,6491,6707,6928,7155,7386,7623,7865,8113,8365,8624,8888,9157,9432,9713,10000,10292,10591,10895,11206,11523,11846,12175,12511,12853,13202,13557,13919,14287,14663,15045,15434,15830,16233,16644,17061,17486,17919,18358,18805,19260,19723,20193,20671,21156,21650,22152,22662,23180,23706,24241,24784,25335,25895,26464,27041,27627,28222,28826,29439,30060,30691,31332,31981,32640 - -#define DEFAULT_LEVEL 75 -#define MAX_1x7135 75 -#define HALFSPEED_LEVEL 0 // always use tint ramping correction -#define QUARTERSPEED_LEVEL 2 // quarter speed at level 1, full speed at 2+ -//#undef USE_DYNAMIC_UNDERCLOCKING // makes huge bumps in the ramp - -#define USE_SET_LEVEL_GRADUALLY - - -// override default ramp style -#undef RAMP_STYLE -#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped -// set floor and ceiling as far apart as possible -// because this lantern isn't overpowered -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL 150 -#define RAMP_DISCRETE_STEPS 7 - -// LT1 can handle heat well, so don't limit simple mode -#define SIMPLE_UI_FLOOR 10 -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 5 - -// Allow 3C (or 6C) in Simple UI (toggle smooth or stepped ramping) -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 40 - -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_COLOR_STROBE_CH1 CM_CH1 -#define POLICE_COLOR_STROBE_CH2 CM_CH2 -// aux red + aux blue are the correct colors, but are dim -//#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -//#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) // high, low, police strobe - -// party strobe, tac strobe, police, lightning, candle, bike -#define DEFAULT_STROBE_CHANNELS CM_BOTH,CM_BOTH,CM_BOTH,CM_AUTO,CM_AUTO,CM_AUTO - -// the sensor (attiny1616) is nowhere near the emitters -// so thermal regulation can't work -#ifdef USE_THERMAL_REGULATION -#undef USE_THERMAL_REGULATION -#endif - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_FLOOR -#undef BLINK_AT_RAMP_FLOOR -#endif -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -// except the top... blink at the top -#ifndef BLINK_AT_RAMP_CEIL -#define BLINK_AT_RAMP_CEIL -#endif - -// for consistency with other models -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-blf-lantern.h b/spaghetti-monster/anduril/cfg-blf-lantern.h deleted file mode 100644 index 53c3203..0000000 --- a/spaghetti-monster/anduril/cfg-blf-lantern.h +++ /dev/null @@ -1,105 +0,0 @@ -// BLF Lantern config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0621" -#include "hwdef-blf-lt1.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -#define DEFAULT_CHANNEL_MODE CM_AUTO -//#define DEFAULT_BLINK_CHANNEL CM_BOTH // takes too much space - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -//#define TINT_RAMPING_CORRECTION 26 // prototype, 140% -//#define TINT_RAMPING_CORRECTION 10 // production model, 115% -#define TINT_RAMPING_CORRECTION 0 // none - -#define RAMP_SIZE 150 -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -// level_calc.py 3.333 1 150 7135 32 0.2 600 --pwm 32640 -#define PWM1_LEVELS 32,35,38,41,45,50,55,61,67,74,82,91,100,110,121,133,146,160,175,192,209,227,247,268,291,314,340,366,395,424,456,489,524,560,599,639,681,726,772,820,871,924,979,1036,1096,1158,1222,1289,1359,1431,1506,1584,1664,1747,1834,1923,2015,2111,2209,2311,2416,2524,2636,2751,2870,2992,3118,3247,3380,3518,3659,3803,3952,4105,4262,4423,4589,4759,4933,5111,5294,5482,5674,5871,6073,6279,6491,6707,6928,7155,7386,7623,7865,8113,8365,8624,8888,9157,9432,9713,10000,10292,10591,10895,11206,11523,11846,12175,12511,12853,13202,13557,13919,14287,14663,15045,15434,15830,16233,16644,17061,17486,17919,18358,18805,19260,19723,20193,20671,21156,21650,22152,22662,23180,23706,24241,24784,25335,25895,26464,27041,27627,28222,28826,29439,30060,30691,31332,31981,32640 - -#define DEFAULT_LEVEL 75 -#define MAX_1x7135 75 -#define HALFSPEED_LEVEL 44 -#define QUARTERSPEED_LEVEL 34 -#undef USE_DYNAMIC_UNDERCLOCKING // makes huge bumps in the ramp - -#define USE_SMOOTH_STEPS -//#define USE_SET_LEVEL_GRADUALLY - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 40 - -// override default ramp style -#undef RAMP_STYLE -#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped -// set floor and ceiling as far apart as possible -// because this lantern isn't overpowered -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL 150 -#define RAMP_DISCRETE_STEPS 7 - -// LT1 can handle heat well, so don't limit simple mode -#define SIMPLE_UI_FLOOR 10 -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 5 - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE -#define USE_EXTENDED_SIMPLE_UI - -// also at Sofirn's request, enable 2 click turbo (Anduril 1 style) -#define DEFAULT_2C_STYLE 1 - - -// the sensor (attiny85) is nowhere near the emitters -// so thermal regulation can't work -#ifdef USE_THERMAL_REGULATION -#undef USE_THERMAL_REGULATION -#endif - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_FLOOR -#undef BLINK_AT_RAMP_FLOOR -#endif -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -#ifdef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#endif - -// too big, turn off extra features -//#undef USE_STEPPED_TINT_RAMPING -#undef USE_MOMENTARY_MODE -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE -//#undef USE_SIMPLE_UI -//#undef USE_BEACON_MODE -//#undef USE_RAMP_SPEED_CONFIG -#undef USE_RAMP_AFTER_MOON_CONFIG -#undef USE_2C_STYLE_CONFIG -#undef USE_VOLTAGE_CORRECTION -//#undef USE_CHANNEL_PER_STROBE -// party strobe, tac strobe, lightning, candle, bike -#define DEFAULT_STROBE_CHANNELS CM_BOTH,CM_BOTH,CM_AUTO,CM_AUTO,CM_AUTO - -// for consistency with other models -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-blf-q8-t1616.h b/spaghetti-monster/anduril/cfg-blf-q8-t1616.h deleted file mode 100644 index 9f0402c..0000000 --- a/spaghetti-monster/anduril/cfg-blf-q8-t1616.h +++ /dev/null @@ -1,82 +0,0 @@ -// BLF Q8 config options for Anduril using the Attiny1616 -// Copyright (C) 2021-2023 gchart, Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0613" -#include "hwdef-blf-q8-t1616.h" -#include "wurkkos-cfg.h" // Sofirn lights are closely related to Wurkkos -// ATTINY: 1616 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// copied from Wurkkos TS25 ramp -#define RAMP_SIZE 150 -// 7135 at 75/150 -// level_calc.py 5.7895 2 150 7135 1 0.1 130 FET 1 10 3000 --pwm dyn:74:4096:255:3 -// (with some manual tweaks) -#define PWM1_LEVELS 1,1,2,3,3,4,5,6,7,8,9,11,12,13,15,16,18,19,21,23,26,27,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,71,74,76,78,80,82,85,87,90,93,96,100,103,107,112,116,122,127,133,140,147,154,163,171,182,192,203,215,228,241,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -// non-zero part of FET channel calculated with: -// level_calc.py 3 1 75 7135 1 200 3000 -// (FIXME? there's a visible bump when the FET kicks in, even with just 1/255) -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,7,8,10,11,13,14,16,17,19,21,22,24,26,28,30,32,34,37,39,41,44,46,48,51,54,56,59,62,65,68,71,74,77,81,84,87,91,94,98,102,106,110,114,118,122,126,130,135,139,144,148,153,158,163,168,173,178,184,189,195,200,206,212,218,224,230,236,242,248,255 -#define PWM_TOPS 4095,2701,3200,3586,2518,2778,2834,2795,2705,2587,2455,2582,2412,2247,2256,2091,2062,1907,1860,1802,1737,1605,1542,1477,1412,1347,1284,1222,1162,1105,1050,997,946,898,853,810,768,730,693,658,625,594,564,536,503,485,462,439,418,398,384,366,353,340,327,319,307,298,292,284,280,273,269,266,263,260,258,256,256,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define MAX_1x7135 75 -#define DEFAULT_LEVEL 50 -#define MIN_THERM_STEPDOWN 60 -#define HALFSPEED_LEVEL 20 -#define QUARTERSPEED_LEVEL 5 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -// 20 38 56 [75] 93 111 130 -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// at Sofirn's request, use max (150) for the Simple UI ceiling -#define SIMPLE_UI_FLOOR 1 -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 5 - -// also at Sofirn's request, enable 2 click turbo (Anduril 1 style) -#define DEFAULT_2C_STYLE 1 - -// enable SOS in the blinkies group -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// stop panicking at ~75% power or ~3000 lm, this light has high thermal mass -#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the aux LEDs by default -#define DEFAULT_BLINK_CHANNEL CM_AUX - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink during the ramp; the button LED brightness is sufficient -// to indicate which power channel(s) are being used -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// enable factory reset on 13H without loosening tailcap (required) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-blf-q8.h b/spaghetti-monster/anduril/cfg-blf-q8.h deleted file mode 100644 index 29dbcb7..0000000 --- a/spaghetti-monster/anduril/cfg-blf-q8.h +++ /dev/null @@ -1,71 +0,0 @@ -// BLF Q8 config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0611" -#include "hwdef-blf-q8.h" - -#define RAMP_SIZE 150 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: high (2) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2) - -// copied from Emisar D4 ramp -// ../../bin/level_calc.py 1 65 7135 1 0.8 150 -// ... mixed with this: -// ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 - -#define MAX_1x7135 65 -#define DEFAULT_LEVEL 65 -#define HALFSPEED_LEVEL 14 -#define QUARTERSPEED_LEVEL 5 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 -// 10 28 46 [65] 83 101 120 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// at Sofirn's request, use max (150) for the Simple UI ceiling -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 5 - -// also at Sofirn's request, enable 2 click turbo (Anduril 1 style) -#define DEFAULT_2C_STYLE 1 - -// enable SOS in the blinkies group -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE -#define USE_EXTENDED_SIMPLE_UI - -// stop panicking at ~75% power or ~3000 lm, this light has high thermal mass -#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -#define USE_SMOOTH_STEPS - -// too big, remove stuff to make room -#undef USE_SOS_MODE -//#undef USE_RAMP_AFTER_MOON_CONFIG -//#undef USE_RAMP_SPEED_CONFIG -//#undef USE_VOLTAGE_CORRECTION -//#undef USE_2C_STYLE_CONFIG -//#undef USE_TACTICAL_STROBE_MODE -#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-emisar-2ch-fet.h b/spaghetti-monster/anduril/cfg-emisar-2ch-fet.h deleted file mode 100644 index 4686483..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-2ch-fet.h +++ /dev/null @@ -1,113 +0,0 @@ -// Emisar 2-channel generic (plus FET) config options for Anduril (based on Noctigon K9.3) -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0136" -#include "hwdef-emisar-2ch-fet.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// the aux LEDs are front-facing, so turn them off while main LEDs are on -// it also has an independent LED in the button -#define USE_BUTTON_LED -// TODO: the whole "indicator LED" thing needs to be refactored into -// "aux LED(s)" and "button LED(s)" since they work a bit differently -// enabling this option breaks the button LED on D4v2.5 -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -// enable max brightness out of the box -#define DEFAULT_CHANNEL_MODE CM_BOTH - -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_BOTH - -#define POLICE_COLOR_STROBE_CH1 CM_CH1 -#define POLICE_COLOR_STROBE_CH2 CM_CH2 - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it - - -// channel 1 / main LEDs (w/ DD FET) -// output: unknown, 1750 lm? -// FET: unknown, 3000 lm? -// channel 2 -// output: unknown, 1750 lm? -// combined: 4000 to 5000 lm? -#define RAMP_SIZE 150 - -// linear+FET ramp: maxreg at 140/150 -// level_calc.py 5.01 2 150 7135 1 0.1 1924 FET 1 10 2600 --pwm dyn:68:4096:255:3 --clock 8:16:0 -// linear segment -#define PWM1_LEVELS 1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,8,8,8,9,9,9,10,10,11,12,13,13,14,15,16,17,17,18,19,20,21,22,23,25,26,27,28,30,31,33,34,36,37,39,41,43,44,46,48,50,53,55,57,60,62,65,67,70,73,76,79,82,85,88,92,95,99,103,106,110,114,119,123,127,132,137,142,147,152,157,162,168,174,179,185,192,198,204,211,218,225,232,240,247,255,255,255,255,255,255,255,255,255,255,255 -// DD FET segment -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,44,68,93,118,144,171,198,226,255 -// PWM TOPS values -#define PWM3_LEVELS 4096,3831,3570,3314,3063,2817,2577,2342,2115,1894,1682,1477,1281,2237,2005,1784,1576,1380,1196,1111,1026,1442,1348,1215,1091,976,871,774,1031,942,860,784,714,650,591,538,652,602,555,513,473,437,403,372,343,398,370,345,322,299,278,311,292,273,255,278,261,245,263,247,232,246,231,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -// linear-only ramp -// level_calc.py 3.11 1 150 7135 1 0.1 1750 --pwm dyn:64:4096:255:3 --clock 8:16:0 -#define PWM4_LEVELS 1,1,1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,13,13,13,14,14,14,15,15,16,17,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35,37,38,39,41,42,44,45,47,48,50,52,53,55,57,59,61,63,65,67,69,71,73,75,77,79,82,84,86,89,91,94,97,99,102,105,107,110,113,116,119,122,125,128,132,135,138,141,145,148,152,156,159,163,167,170,174,178,182,186,190,195,199,203,208,212,217,221,226,230,235,240,245,250,255 -// PWM_TOPS values for linear-only ramp -#define PWM5_LEVELS 4096,3681,3247,2794,2328,1856,2937,2393,1860,2690,2273,1875,2281,1959,1658,1893,1646,1774,1569,1381,1466,1309,1166,1224,1104,996,1033,942,858,882,810,746,687,634,586,604,561,522,487,454,425,397,409,385,362,341,321,302,311,295,279,286,271,257,263,250,255,258,246,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define DEFAULT_LEVEL 75 -#define MAX_1x7135 140 -#define MAX_Nx7135 MAX_1x7135 -#define HALFSPEED_LEVEL 16 -#define QUARTERSPEED_LEVEL 8 - -#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?) -#define RAMP_SMOOTH_CEIL 140 -// 10, 31, 53, [75], 96, 118, [140] -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit highest regulated power (no FET or turbo) -// 10, 42, [75], 107, 140 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~1500 lm -#define THERM_FASTER_LEVEL 130 -#define MIN_THERM_STEPDOWN 65 // should be above highest dyn_pwm level - -#define USE_POLICE_COLOR_STROBE_MODE -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 140,30,(RAMP_SIZE+3) // high, low, police strobe - -// use the brightest setting for strobe -#define STROBE_BRIGHTNESS MAX_LEVEL -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 2 -// TODO: change speed per channel mode -// (the FET is really fast, but the regulator is not) -//#undef PARTY_STROBE_ONTIME - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 33 - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 40 -#define BLINK_BRIGHTNESS 45 -#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow - -#define THERM_CAL_OFFSET 5 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-emisar-2ch.h b/spaghetti-monster/anduril/cfg-emisar-2ch.h deleted file mode 100644 index 4c3a329..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-2ch.h +++ /dev/null @@ -1,103 +0,0 @@ -// Emisar 2-channel generic config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0135" -#include "hwdef-emisar-2ch.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// the aux LEDs are front-facing, so turn them off while main LEDs are on -// it also has an independent LED in the button -#define USE_BUTTON_LED -// TODO: the whole "indicator LED" thing needs to be refactored into -// "aux LED(s)" and "button LED(s)" since they work a bit differently -// enabling this option breaks the button LED on D4v2.5 -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -// enable max brightness out of the box -#define DEFAULT_CHANNEL_MODE CM_BLEND - -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_BLEND - -#define POLICE_COLOR_STROBE_CH1 CM_CH1 -#define POLICE_COLOR_STROBE_CH2 CM_CH2 - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it - - -// channel 1 -// output: unknown, 2000 lm? -// FET: absent / unused -// channel 2 -// output: unknown, 2000 lm? -#define RAMP_SIZE 150 - -// abstract ramp (power is split between both sets of LEDs) -// 1-130: 0 to 100% power -// level_calc.py 5.01 1 130 7135 2 0.2 2000 --pwm dyn:64:16383:511 -// 131 to 150: 101% to 200% power -// level_calc.py 6.44 1 150 7135 1 0.2 2000 --pwm dyn:74:16383:1022 -#define PWM1_LEVELS 1,1,1,2,2,2,3,3,4,5,5,6,7,8,9,10,11,12,13,15,16,18,19,21,22,24,26,28,29,31,33,35,37,40,42,44,46,48,50,52,54,56,58,59,61,62,63,64,65,66,66,66,66,65,64,62,60,58,54,50,46,41,35,28,20,21,22,24,25,26,27,29,30,32,33,35,37,38,40,42,44,46,48,50,53,55,57,60,63,65,68,71,74,77,80,83,87,90,94,98,102,106,110,114,118,123,128,132,137,142,148,153,159,164,170,176,183,189,196,202,209,216,224,231,239,247,255,263,272,281,290,299,309,318,328,339,349,360,371,382,394,406,418,430,443,456,469,483,497,511 -#define PWM_TOPS 16383,13650,10715,15388,11902,8195,12771,9834,12258,13423,11192,11947,12284,12363,12271,12064,11775,11428,11039,11469,10973,11132,10595,10601,10054,9971,9833,9655,9122,8923,8704,8473,8232,8196,7932,7668,7408,7152,6901,6656,6417,6186,5961,5647,5444,5163,4899,4653,4422,4206,3941,3697,3470,3210,2971,2707,2466,2245,1968,1717,1489,1251,1005,756,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511 -// max "200% power" ramp and tops -//#define PWM2_LEVELS 2,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,28,30,33,35,38,41,44,47,50,54,57,60,64,67,71,74,78,81,84,88,91,94,97,99,101,103,105,106,107,107,107,106,105,102,99,95,90,84,77,68,58,47,34,36,38,40,42,44,47,49,52,54,57,60,63,66,69,73,76,80,83,87,91,96,100,104,109,114,119,124,130,135,141,147,153,160,166,173,180,187,195,203,211,219,228,236,245,255,264,274,285,295,306,317,329,340,353,365,378,391,405,419,433,448,463,479,495,511,530,550,570,591,612,634,657,680,705,730,755,782,809,837,865,895,925,957,989,1022 -//#define PWM3_LEVELS 16383,13234,9781,13826,9593,13434,9973,12021,12900,13193,13150,12899,12508,12023,12666,11982,12181,11422,11393,11247,11018,10731,10826,10434,10365,9927,9767,9565,9332,9076,8806,8693,8395,8096,7928,7626,7439,7143,6948,6665,6393,6203,5946,5700,5465,5187,4926,4681,4451,4195,3957,3700,3463,3213,2983,2718,2476,2231,1986,1742,1501,1245,997,756,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511 -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 150 -#define HALFSPEED_LEVEL 10 -#define QUARTERSPEED_LEVEL 2 - -#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?) -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, [130] -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit highest regulated power (no FET or turbo) -// 10, 40, [70], 100, 130 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~1500 lm -#define THERM_FASTER_LEVEL 130 -#define MIN_THERM_STEPDOWN 65 // should be above highest dyn_pwm level - -#define USE_POLICE_COLOR_STROBE_MODE -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 130,30,(RAMP_SIZE+3) // high, low, police strobe - -// use the brightest setting for strobe -#define STROBE_BRIGHTNESS MAX_LEVEL -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 2 - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 33 - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 21 -#define BLINK_BRIGHTNESS 40 -#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow - -#define THERM_CAL_OFFSET 5 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-emisar-d1.h b/spaghetti-monster/anduril/cfg-emisar-d1.h deleted file mode 100644 index c81171c..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d1.h +++ /dev/null @@ -1,20 +0,0 @@ -// Emisar D1 config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as Emisar D4, mostly -#include "hwdef-emisar-d4.h" -#include "cfg-emisar-d4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0121" - -// safe limit ~50% power -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL 120 - -// stop panicking at ~75% power or ~1000 lm (D1 has a decent power-to-thermal-mass ratio) -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high diff --git a/spaghetti-monster/anduril/cfg-emisar-d18-219.h b/spaghetti-monster/anduril/cfg-emisar-d18-219.h deleted file mode 100644 index 126e9f4..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d18-219.h +++ /dev/null @@ -1,18 +0,0 @@ -// Emisar D18 (FET+13+1) reduced-FET config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-emisar-d18.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0142" - -// don't turn off first channels at turbo level -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,4,4,5,6,7,8,9,10,11,15,16,18,20,22,24,26,28,30,33,36,39,43,47,51,56,61,66,72,78,85,92,99,107,116,125,135,145,156,168,180,194,208,222,238,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,10,11,13,14,16,18,19,21,23,26,28,30,33,35,38,41,44,47,51,54,58,62,66,70,75,79,84,90,95,101,106,112,119,126,133,140,147,155,164,172,181,190,200,210,221,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 85% FET power -#undef PWM3_LEVELS -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,6,8,10,12,13,16,17,20,22,24,27,29,32,34,38,40,44,46,50,53,57,60,64,68,72,76,80,85,89,94,98,103,108,114,119,125,131,137,143,150,156,163,170,177,185,193,200,209,217 - diff --git a/spaghetti-monster/anduril/cfg-emisar-d18.h b/spaghetti-monster/anduril/cfg-emisar-d18.h deleted file mode 100644 index 3e5d3ae..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d18.h +++ /dev/null @@ -1,61 +0,0 @@ -// Emisar D18 (FET+13+1) config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0141" -#include "hwdef-emisar-d18.h" -#include "hank-cfg.h" - -#define RAMP_SIZE 150 - -// level_calc.py seventh 3 150 7135 1 1.4 117.99 7135 6 1 1706.86 FET 3 10 13000 -// (designed to make 1x hit at level 50, and Nx hit at level 100) -#define PWM1_LEVELS 1,1,2,2,3,4,4,5,6,7,8,9,10,11,15,16,18,20,22,24,26,28,30,33,36,39,43,47,51,56,61,66,72,78,85,92,99,107,116,125,135,145,156,168,180,194,208,222,238,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,10,11,13,14,16,18,19,21,23,26,28,30,33,35,38,41,44,47,51,54,58,62,66,70,75,79,84,90,95,101,106,112,119,126,133,140,147,155,164,172,181,190,200,210,221,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,7,9,11,13,15,18,20,23,25,28,31,34,37,40,44,47,51,54,58,62,66,70,75,79,84,89,94,99,104,110,115,121,127,134,140,147,154,161,168,176,183,191,200,208,217,226,235,245,255 - -#define DEFAULT_LEVEL 50 -#define MAX_1x7135 50 -#define MAX_Nx7135 100 -#define HALFSPEED_LEVEL 15 -#define QUARTERSPEED_LEVEL 6 - -// start at ~2000 lm after battery change, not ~150 lm (at Emisar's request) -//#define DEFAULT_LEVEL MAX_Nx7135 - -// go up to ~4000 lm -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 117 -// 20 36 52 68 84 [100] 117 -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~20% power / max regulated -// 20 40 60 80 100 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL MAX_Nx7135 -#define SIMPLE_UI_STEPS 5 - -// only blink at max regulated level and ceiling -//#define BLINK_AT_RAMP_MIDDLE -//#define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135 -#define BLINK_AT_RAMP_CEIL -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// stop panicking at about ~40% power or ~5000 lm -#define THERM_FASTER_LEVEL 125 - -// enable extra features -#define USE_SMOOTH_STEPS - -// for compatibility with other models -#define USE_SOFT_FACTORY_RESET - -// too big, turn off extra features -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE - diff --git a/spaghetti-monster/anduril/cfg-emisar-d1s.h b/spaghetti-monster/anduril/cfg-emisar-d1s.h deleted file mode 100644 index 8b70a5d..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d1s.h +++ /dev/null @@ -1,23 +0,0 @@ -// Emisar D1S config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as Emisar D4, mostly -#include "hwdef-emisar-d4.h" -#include "cfg-emisar-d4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0122" - -// safe limit ~50% power -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL 120 - -// stop panicking at ~90% power or ~1200 lm (D1S has a good power-to-thermal-mass ratio) -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL 144 // throttle back faster when high - -// too big, turn off extra features -//#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-emisar-d1v2-7135-fet.h b/spaghetti-monster/anduril/cfg-emisar-d1v2-7135-fet.h deleted file mode 100644 index 4022ba6..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d1v2-7135-fet.h +++ /dev/null @@ -1,32 +0,0 @@ -// Emisar D1v2 (7135+FET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// ATTINY: 1634 -// same as Emisar D4v2, mostly -// (was only made for a short time, not many people have one) -#include "cfg-emisar-d4v2.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0123" - -// some models use a simple button LED, others use RGB... -// ... so include support for both -#define USE_BUTTON_LED -// the aux LEDs are in the button, so use them while main LEDs are on -// (early short run had no button LEDs at all, later run uses linear+FET instead, -// so it's unlikely that anyone needs this, but it doesn't hurt anything) -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 25 -#define USE_INDICATOR_LED_WHILE_RAMPING - -// safe limit ~50% power -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL 120 - -// stop panicking at ~75% power or ~1000 lm (D1 has a decent power-to-thermal-mass ratio) -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high - diff --git a/spaghetti-monster/anduril/cfg-emisar-d1v2-linear-fet.h b/spaghetti-monster/anduril/cfg-emisar-d1v2-linear-fet.h deleted file mode 100644 index 28c57f8..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d1v2-linear-fet.h +++ /dev/null @@ -1,30 +0,0 @@ -// Emisar D1v2 (linear+FET) config options for Anduril -// (2022 re-issue / update of old D1) -// Copyright (C) 2022-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// ATTINY: 1634 -// similar to a Noctigon KR4, sort of -#include "cfg-noctigon-kr4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0124" - -// some models use a simple button LED, others use RGB... -// ... so include support for both -#define USE_BUTTON_LED -// the aux LEDs are in the button, so use them while main LEDs are on -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 25 -#define USE_INDICATOR_LED_WHILE_RAMPING - -// safe limit: max regulated power -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL MAX_1x7135 - -// stop panicking at ~75% power or ~1000 lm (D1 has a decent power-to-thermal-mass ratio) -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL (RAMP_SIZE*9/10) // throttle back faster when high - diff --git a/spaghetti-monster/anduril/cfg-emisar-d1v2-nofet.h b/spaghetti-monster/anduril/cfg-emisar-d1v2-nofet.h deleted file mode 100644 index 7f5bcc4..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d1v2-nofet.h +++ /dev/null @@ -1,24 +0,0 @@ -// Emisar D1v2 (linear only, no DDFET) config options for Anduril -// (2022 re-issue / update of old D1) -// Copyright (C) 2022-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// ATTINY: 1634 -// similar to a Noctigon KR4, sort of -#include "cfg-noctigon-kr4-nofet.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0125" - -// some models use a simple button LED, others use RGB... -// ... so include support for both -#define USE_BUTTON_LED -// the aux LEDs are in the button, so use them while main LEDs are on -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 25 -#define USE_INDICATOR_LED_WHILE_RAMPING - -// safe limit: same as regular ramp -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL RAMP_SMOOTH_CEIL - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4-219c.h b/spaghetti-monster/anduril/cfg-emisar-d4-219c.h deleted file mode 100644 index 65649e3..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4-219c.h +++ /dev/null @@ -1,17 +0,0 @@ -// Emisar D4-219C config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as D4 but with FET modes limited to 80% power -// to avoid destroying the LEDs -#include "cfg-emisar-d4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0112" - -// don't turn off first channel at turbo level -#undef PWM1_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 65% FET power -#undef PWM2_LEVELS -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,21,22,23,25,26,27,28,30,32,33,34,36,38,39,41,42,44,46,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,78,80,82,84,87,90,92,94,97,99,102,104,108,110,113,116,119,121,125,127,130,134,136,140,143,146,149,153,156,159,163,166 diff --git a/spaghetti-monster/anduril/cfg-emisar-d4.h b/spaghetti-monster/anduril/cfg-emisar-d4.h deleted file mode 100644 index 4b3ae5a..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4.h +++ /dev/null @@ -1,48 +0,0 @@ -// Emisar D4 config options for Anduril -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0111" -#include "hwdef-emisar-d4.h" -#include "hank-cfg.h" -// ATTINY: 85 - -#define RAMP_SIZE 150 - -// ../../bin/level_calc.py 1 65 7135 1 0.8 150 -// ... mixed with this: -// ../../bin/level_calc.py 2 150 7135 4 0.33 150 FET 1 10 1500 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 - -#define MAX_1x7135 65 -#define DEFAULT_LEVEL 65 -#define HALFSPEED_LEVEL 15 -#define QUARTERSPEED_LEVEL 6 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 -// 10, 28, 46, [65], 83, 101, 120 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~20% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 100 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~30% power or ~1200 lm -#define THERM_FASTER_LEVEL 105 - -// don't blink during ramp -#undef BLINK_AT_RAMP_MIDDLE - -// enable extra features -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -//#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h b/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h deleted file mode 100644 index c39ac01..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4k-3ch.h +++ /dev/null @@ -1,106 +0,0 @@ -// Emisar D4K 3-channel config options for Anduril -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0151" -#include "hwdef-emisar-d4k-3ch.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// turn on the aux LEDs while main LEDs are on -// (in case there's a RGB button) -#define USE_AUX_RGB_LEDS_WHILE_ON 40 -#define USE_INDICATOR_LED_WHILE_RAMPING - -// channel modes... -// CM_MAIN2, CM_LED3, CM_LED4, CM_ALL, -// CM_BLEND34A, CM_BLEND34B, CM_HSV, CM_AUTO3 -#define DEFAULT_CHANNEL_MODE CM_ALL - -#define FACTORY_RESET_WARN_CHANNEL CM_LED4 -#define FACTORY_RESET_SUCCESS_CHANNEL CM_MAIN2 - -#define CONFIG_WAITING_CHANNEL CM_LED3 -#define CONFIG_BLINK_CHANNEL CM_ALL - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN2 - -// LEDs 3 and 4 make a nice police strobe -#define POLICE_COLOR_STROBE_CH1 CM_LED3 -#define POLICE_COLOR_STROBE_CH2 CM_LED4 -// aux red + aux blue are the correct colors, but are dim -//#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -//#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it - -// main 2 LEDs -// output: unknown, 2000 lm? -// LED 3 / 4 -// output: unknown, 1000 lm each? -#define RAMP_SIZE 150 -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// level_calc.py 5.01 1 150 7135 0 0.2 2000 --pwm 32640 -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,28,32,36,41,45,50,56,62,69,76,84,92,101,110,121,132,143,156,169,184,199,215,232,251,270,291,313,336,360,386,414,442,473,505,539,574,612,651,693,736,782,829,880,932,987,1045,1105,1168,1233,1302,1374,1449,1527,1608,1693,1781,1873,1969,2068,2172,2279,2391,2507,2628,2753,2883,3018,3158,3303,3454,3609,3771,3938,4111,4289,4475,4666,4864,5068,5280,5498,5724,5957,6197,6445,6701,6965,7237,7518,7808,8106,8413,8730,9056,9392,9737,10093,10459,10835,11223,11621,12031,12452,12884,13329,13786,14255,14737,15232,15741,16262,16798,17347,17911,18489,19082,19691,20314,20954,21609,22281,22969,23674,24397,25137,25895,26671,27465,28279,29111,29963,30835,31727,32640 - -#define MIN_THERM_STEPDOWN 50 -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 70 -// always run at 1/4th speed, because 4 kHz PWM is enough for this circuit -// and speed changes make a big visible bump -#define HALFSPEED_LEVEL 255 -#define QUARTERSPEED_LEVEL 255 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// 10 40 [70] 100 130 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~1500 lm -#define THERM_FASTER_LEVEL 130 - -#define USE_POLICE_COLOR_STROBE_MODE -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) // high, low, police strobe - -// use the brightest setting for strobe -#define STROBE_BRIGHTNESS MAX_LEVEL -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 2 -// #define STROBE_OFF_LEVEL 1 // nope, this makes strobe blurry -// bike strobe needs a longer pulse too? -//#define BIKE_STROBE_ONTIME 8 - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 33 - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 21 -#define BLINK_BRIGHTNESS 50 -#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow - -#define THERM_CAL_OFFSET 5 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// for consistency with KR4 (not otherwise necessary though) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h b/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h deleted file mode 100644 index f86c1b1..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4s-219c.h +++ /dev/null @@ -1,17 +0,0 @@ -// Emisar D4S-219C config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as D4S but with FET modes limited to 80% power -// to avoid destroying the LEDs -#include "cfg-emisar-d4s.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0132" - -// don't turn off first channel at turbo level -#undef PWM1_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 65% FET power -#undef PWM2_LEVELS -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,19,21,23,24,25,27,28,30,32,34,36,38,39,41,43,45,47,50,52,54,57,60,62,65,67,70,73,76,79,82,86,89,92,95,99,103,106,110,114,119,123,127,132,136,141,145,151,156,161,166 diff --git a/spaghetti-monster/anduril/cfg-emisar-d4s.h b/spaghetti-monster/anduril/cfg-emisar-d4s.h deleted file mode 100644 index e966132..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4s.h +++ /dev/null @@ -1,49 +0,0 @@ -// Emisar D4S config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0131" -#include "hwdef-emisar-d4s.h" -#include "hank-cfg.h" -// ATTINY: 85 - -// the button lights up (on some models) -#define USE_INDICATOR_LED -// the aux LEDs are behind the main LEDs -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -#define RAMP_SIZE 150 - -// 3x7135 + FET -// level_calc.py ninth 2 150 7135 1 11.2 450 FET 1 10 4000 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,10,11,13,14,16,18,19,21,23,25,27,29,31,34,36,38,41,43,46,48,51,54,57,60,63,66,69,72,76,79,83,87,91,95,99,103,107,112,116,121,126,131,136,141,146,152,158,163,169,175,182,188,195,202,209,216,223,231,239,247,255 -#define MAX_1x7135 83 -#define HALFSPEED_LEVEL 13 -#define QUARTERSPEED_LEVEL 6 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 -// 10, 28, 46, 65, [83], 101, 120 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~30% power -// 10 34 59 [83] 108 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 108 -#define SIMPLE_UI_STEPS 5 - -// thermal regulation parameters -#ifdef MIN_THERM_STEPDOWN -#undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135 -#endif -#define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to -#define THERM_FASTER_LEVEL (RAMP_SIZE-20) // don't throttle back faster when high - -// too big, turn off extra features -#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2-219.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2-219.h deleted file mode 100644 index 22775cc..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4sv2-219.h +++ /dev/null @@ -1,18 +0,0 @@ -// Emisar D4Sv2-219 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-emisar-d4sv2.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0134" -// ATTINY: 1634 - -// don't turn off first channel at turbo level -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,12,13,17,18,19,20,21,22,24,26,28,30,33,35,38,41,44,47,50,54,57,61,65,69,74,79,84,89,94,100,106,113,119,126,134,142,150,158,167,176,186,196,207,218,230,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,16,21,25,30,35,41,46,52,58,64,71,77,84,92,99,107,115,124,133,142,151,161,172,182,193,205,217,229,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 65% FET power -#undef PWM3_LEVELS -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,6,7,8,10,11,12,13,15,17,18,20,21,23,25,27,29,31,33,35,38,39,42,44,47,49,52,54,57,60,63,66,69,73,76,79,83,86,90,94,98,102,106,110,115,119,124,129,134,139,144,149,155,160,166 diff --git a/spaghetti-monster/anduril/cfg-emisar-d4sv2.h b/spaghetti-monster/anduril/cfg-emisar-d4sv2.h deleted file mode 100644 index 666b394..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4sv2.h +++ /dev/null @@ -1,81 +0,0 @@ -// Emisar D4S V2 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0133" -#include "hwdef-emisar-d4sv2.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -#define RAMP_SIZE 150 - -// 1x7135 + 3x7135 + FET - -// level_calc.py 5.7895 3 150 7135 1 0.1 130 7135 1 1 321.43 FET 2 10 3000 --pwm dyn:74:4096:255:3 -#define PWM1_LEVELS 1,1,2,3,3,4,5,6,7,8,9,11,12,13,15,16,18,19,21,23,26,27,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,71,74,76,78,80,82,85,87,90,93,96,100,103,107,112,116,122,127,133,140,147,154,163,171,182,192,203,215,228,241,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,12,19,25,32,40,47,55,64,72,81,91,101,111,122,133,144,156,169,182,195,209,224,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,7,10,12,15,17,20,22,25,28,31,34,38,41,44,48,52,56,60,64,68,72,77,81,86,91,96,101,107,112,118,124,130,136,143,149,156,163,170,178,186,193,201,210,218,227,236,245,255 -#define PWM_TOPS 4095,2701,3200,3586,2518,2778,2834,2795,2705,2587,2455,2582,2412,2247,2256,2091,2062,1907,1860,1802,1737,1605,1542,1477,1412,1347,1284,1222,1162,1105,1050,997,946,898,853,810,768,730,693,658,625,594,564,536,503,485,462,439,418,398,384,366,353,340,327,319,307,298,292,284,280,273,269,266,263,260,258,256,256,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define MIN_THERM_STEPDOWN 70 // should be above highest dyn_pwm level -#define MAX_1x7135 75 -#define MAX_Nx7135 100 -#define HALFSPEED_LEVEL 20 -#define QUARTERSPEED_LEVEL 5 - -// old -//// ../../../bin/level_calc.py seventh 3 150 7135 1 2.3 130 7135 11 5 400.1 FET 2 10 4000 -//// (and some manual edits to make the clock speed changes smoother) -//#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,12,13,17,18,19,20,21,22,24,26,28,30,33,35,38,41,44,47,50,54,57,61,65,69,74,79,84,89,94,100,106,113,119,126,134,142,150,158,167,176,186,196,207,218,230,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -//#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,16,21,25,30,35,41,46,52,58,64,71,77,84,92,99,107,115,124,133,142,151,161,172,182,193,205,217,229,242,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -//#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,5,6,8,10,12,14,16,18,20,23,25,27,30,32,35,38,41,44,47,50,53,57,60,64,67,71,75,79,83,87,92,96,101,106,111,116,121,127,132,138,144,150,156,163,169,176,183,190,197,205,213,221,229,237,246,255 -//#define PWM_TOPS 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -//#define MAX_1x7135 62 -//#define MAX_Nx7135 93 -//#define HALFSPEED_LEVEL 18 -//#define QUARTERSPEED_LEVEL 8 - - -#define DEFAULT_LEVEL MAX_Nx7135 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 20, 38, 56, [75], 93, 111, 130 -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~35% power, 150% of sustainable thermal power -// 25 50 [75] [100] 125 -#define SIMPLE_UI_FLOOR 25 -#define SIMPLE_UI_CEIL 125 -#define SIMPLE_UI_STEPS 5 - -#define STROBE_BRIGHTNESS MAX_LEVEL - -// stop panicking at ~50% power or ~2000 lm -#define THERM_FASTER_LEVEL 130 - -#define THERM_CAL_OFFSET 5 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h b/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h deleted file mode 100644 index e9775ec..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4v2-219.h +++ /dev/null @@ -1,17 +0,0 @@ -// Emisar D4v2-219 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-emisar-d4v2.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0114" -// ATTINY: 1634 - -// don't turn off the low channel at turbo level -#undef LOW_PWM_LEVELS -#define LOW_PWM_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 65% DDFET power -#undef HIGH_PWM_LEVELS -#define HIGH_PWM_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,13,15,16,17,18,19,21,22,23,25,26,27,28,30,32,33,34,36,38,39,41,42,44,46,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,78,80,82,84,87,90,92,94,97,99,102,104,108,110,113,116,119,121,125,127,130,134,136,140,143,146,149,153,156,159,163,166 - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h b/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h deleted file mode 100644 index 6eddb40..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4v2-nofet.h +++ /dev/null @@ -1,62 +0,0 @@ -// Emisar D4v2-noFET config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// switch to 1-channel support functions -#define HWDEF_C_FILE hwdef-emisar-d4v2-nofet.c - -#include "cfg-emisar-d4v2.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0115" -// ATTINY: 1634 - -// the ramp uses only 1x7135 chip, max ~130 lm -#undef PWM_CHANNELS -#define PWM_CHANNELS 1 - -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#undef PWM_TOPS -//#define PWM1_LEVELS 1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,6,7,8,8,9,9,10,10,11,12,13,13,14,15,16,16,17,18,19,20,21,22,23,23,24,26,27,28,29,30,31,32,33,34,36,37,38,39,41,42,43,45,46,47,49,50,52,53,55,56,58,59,61,62,64,66,67,69,71,72,74,76,78,80,81,83,85,87,89,91,93,95,97,99,101,103,105,107,109,111,113,116,118,120,122,125,127,129,132,134,136,139,141,144,146,148,151,154,156,159,161,164,166,169,172,174,177,180,183,185,188,191,194,197,200,203,205,208,211,214,217,220,223,226,230,233,236,239,242,245,249,252,255 -// level_calc.py 3.01 1 150 7135 -1 0.1 140 --pwm dyn:64:4096:255:3 --clock 11:21:8.0 -// (and some manual tweaks to make half/quarter speed levels less bumpy) -#define PWM1_LEVELS 1,1,2,2,3,4,4,5,6,7,9,10,11,11,12,13,13,14,15,15,18,18,17,18,18,19,19,19,19,19,20,20,20,20,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,20,20,20,21,21,22,23,24,24,26,27,28,29,30,31,32,33,34,35,36,38,39,40,42,43,44,46,47,49,50,52,53,55,56,58,60,62,63,65,67,69,71,73,75,77,79,81,83,85,88,90,92,95,97,100,102,105,107,110,112,115,118,121,124,127,129,132,135,139,142,145,148,151,155,158,162,165,169,172,176,179,183,187,191,195,199,203,207,211,215,219,223,228,232,237,241,246,250,255 -#define PWM_TOPS 4094,2719,3280,1954,2599,3032,2342,2548,2626,2635,2246,2261,2244,1964,1956,1929,1743,1733,1763,1697,1492,1362,1245,1231,1132,1118,1034,958,889,826,821,767,717,671,629,591,556,523,493,465,440,416,394,373,354,336,319,304,299,293,279,282,269,257,260,249,251,252,253,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#undef MAX_1x7135 -#define MAX_1x7135 150 -#undef QUARTERSPEED_LEVEL -#undef HALFSPEED_LEVEL -#define QUARTERSPEED_LEVEL 11 -#define HALFSPEED_LEVEL 21 - -#undef DEFAULT_LEVEL -#define DEFAULT_LEVEL 80 - -#undef RAMP_SMOOTH_CEIL -#define RAMP_SMOOTH_CEIL 150 -// 10, 45, 80, 115, 150 -#undef RAMP_DISCRETE_FLOOR -#undef RAMP_DISCRETE_CEIL -#undef RAMP_DISCRETE_STEPS -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 150 -#define RAMP_DISCRETE_STEPS 5 - -// safe limit ~100% power because no FET -#undef SIMPLE_UI_FLOOR -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL - -#undef CANDLE_AMPLITUDE -#define CANDLE_AMPLITUDE 60 - -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 150 - -// maybe keep this, in case someone uses a higher power channel? -//#undef USE_THERMAL_REGULATION -//#undef USE_SET_LEVEL_GRADUALLY - diff --git a/spaghetti-monster/anduril/cfg-emisar-d4v2.h b/spaghetti-monster/anduril/cfg-emisar-d4v2.h deleted file mode 100644 index 0f0bb17..0000000 --- a/spaghetti-monster/anduril/cfg-emisar-d4v2.h +++ /dev/null @@ -1,64 +0,0 @@ -// Emisar D4v2 config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0113" -#include "hwdef-emisar-d4v2.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -#define RAMP_SIZE 150 - -// 7135 at 75/150 -// level_calc.py 5.7895 2 150 7135 1 0.1 130 FET 1 10 3000 --pwm dyn:74:4096:255:3 -// (with some manual tweaks) -// non-zero part of FET channel calculated with: -// level_calc.py 3 1 75 7135 2 500 3000 -#define PWM1_LEVELS 1,1,2,3,3,4,5,6,7,8,9,11,12,13,15,16,18,19,21,23,26,27,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,71,74,76,78,80,82,85,87,90,93,96,100,103,107,112,116,122,127,133,140,147,154,163,171,182,192,203,215,228,241,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,7,9,11,13,15,17,19,21,23,25,27,29,32,34,36,39,41,43,46,49,51,54,57,59,62,65,68,71,74,77,80,83,86,90,93,96,100,103,107,110,114,117,121,125,129,133,137,141,145,149,153,157,162,166,170,175,179,184,189,193,198,203,208,213,218,223,228,233,239,244,249,255 -#define PWM_TOPS 4095,2701,3200,3586,2518,2778,2834,2795,2705,2587,2455,2582,2412,2247,2256,2091,2062,1907,1860,1802,1737,1605,1542,1477,1412,1347,1284,1222,1162,1105,1050,997,946,898,853,810,768,730,693,658,625,594,564,536,503,485,462,439,418,398,384,366,353,340,327,319,307,298,292,284,280,273,269,266,263,260,258,256,256,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define MAX_1x7135 75 -#define DEFAULT_LEVEL 50 -#define MIN_THERM_STEPDOWN 70 // should be above highest dyn_pwm level -#define HALFSPEED_LEVEL 20 -#define QUARTERSPEED_LEVEL 5 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 20, 38, 56, [75], 93, 111, 130 -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// 20, 40, 60, 80, 100 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL 100 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~25% power or ~1000 lm -#define THERM_FASTER_LEVEL 110 - -#define THERM_CAL_OFFSET 5 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-ff-e01.h b/spaghetti-monster/anduril/cfg-ff-e01.h deleted file mode 100644 index 07bda87..0000000 --- a/spaghetti-monster/anduril/cfg-ff-e01.h +++ /dev/null @@ -1,57 +0,0 @@ -// Fireflies E01 SST-40 thrower config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0441" -#include "hwdef-ff-pl47.h" -// ATTINY: 85 - -// disable indicator LED; it's hardwired -#ifdef USE_INDICATOR_LED -#undef USE_INDICATOR_LED -#endif - - -#define RAMP_SIZE 150 - -// driver is a FET + 3x7135, ~413 lm at highest regulated level -// ../../../bin/level_calc.py seventh 2 150 7135 1 12 414 FET 2 10 1930 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,15,16,17,18,20,21,22,23,24,26,27,28,30,31,33,34,36,38,39,41,43,45,47,49,51,53,56,58,60,63,65,68,71,74,77,80,83,86,89,93,96,100,103,107,111,115,119,124,128,132,137,142,147,152,157,163,168,174,180,186,192,198,204,211,218,225,232,240,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,7,9,12,14,16,19,22,24,27,30,33,36,39,42,45,48,52,55,58,62,66,69,73,77,81,85,90,94,98,103,107,112,117,122,127,132,137,143,148,154,160,166,172,178,184,191,197,204,211,218,225,232,240,247,255 -#define MAX_1x7135 93 -#define HALFSPEED_LEVEL 14 -#define QUARTERSPEED_LEVEL 7 - -// ceiling is level 130/150 (50% power) -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 - -// 20, 38, 56, 75, [93], 111, 130 (93 is highest regulated) -// (9 / 45 / 116 / 248 / 467 / 742 / 1280 + 2140 lm) -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~50% power -// 20 56 [93] 130 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL 130 -#define SIMPLE_UI_STEPS 4 - -// thermal regulation parameters -#define MIN_THERM_STEPDOWN 65 // lowest value it'll step down to -#define THERM_FASTER_LEVEL 130 - -#ifndef BLINK_AT_RAMP_CEIL -#define BLINK_AT_RAMP_CEIL -#endif - -// don't do this -#undef BLINK_AT_RAMP_MIDDLE - -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_SOS_MODE -//#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-ff-pl47-219.h b/spaghetti-monster/anduril/cfg-ff-pl47-219.h deleted file mode 100644 index 11bd5b1..0000000 --- a/spaghetti-monster/anduril/cfg-ff-pl47-219.h +++ /dev/null @@ -1,15 +0,0 @@ -// Fireflies PL47-219B config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as PL47 but with FET modes limited to 67% power -// to avoid destroying the LEDs -#include "cfg-ff-pl47.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0422" - -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,19,20,22,23,25,27,28,30,31,33,35,37,39,41,43,45,47,50,52,55,57,60,63,65,68,71,74,77,80,83,87,90,93,97,101,105,108,112,116,121,125,129,134,139,143,148,153,159,164,169 diff --git a/spaghetti-monster/anduril/cfg-ff-pl47.h b/spaghetti-monster/anduril/cfg-ff-pl47.h deleted file mode 100644 index 6436477..0000000 --- a/spaghetti-monster/anduril/cfg-ff-pl47.h +++ /dev/null @@ -1,79 +0,0 @@ -// Fireflies PL47 config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0421" -#include "hwdef-ff-pl47.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the aux LEDs are in the same place as the main LEDs -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif -//#define USE_INDICATOR_LED_WHILE_RAMPING - -// off mode: high (2) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2) - -// the "low" mode doesn't work on this light's aux LEDs -// (but it does work on the switch LEDs) -// Fireflies wants to skip aux LED mode 1 (low) -#define INDICATOR_LED_SKIP_LOW - - -#define RAMP_SIZE 150 - -// driver is a FET + 3x7135, ~400 lm at highest regulated level -// ramp copied from Emisar D4S ramp -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,10,11,13,14,16,18,19,21,23,25,27,29,31,34,36,38,41,43,46,48,51,54,57,60,63,66,69,72,76,79,83,87,91,95,99,103,107,112,116,121,126,131,136,141,146,152,158,163,169,175,182,188,195,202,209,216,223,231,239,247,255 -#define MAX_1x7135 83 -#define HALFSPEED_LEVEL 13 -#define QUARTERSPEED_LEVEL 6 - -// ceiling is level 120/150 -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 - -// 10, 28, 46, 65, 83, 101, 120 (83 is highest regulated) -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 120 -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~25% power / ~1000 lm -// 10 34 59 [83] 108 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 108 -#define SIMPLE_UI_STEPS 5 - -// ~25 lm to ~300 lm -//#define SIMPLE_UI_FLOOR 30 -//#define SIMPLE_UI_CEIL MAX_1x7135 -// ~50 lm to ~500 lm -//#define SIMPLE_UI_FLOOR 40 -//#define SIMPLE_UI_CEIL 90 - -// thermal regulation parameters -#ifdef MIN_THERM_STEPDOWN -#undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135 -#endif -#define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to -// regulate down faster when the FET is active, slower otherwise -#define THERM_FASTER_LEVEL 135 // throttle back faster when high - -#ifndef BLINK_AT_RAMP_CEIL -#define BLINK_AT_RAMP_CEIL -#endif - -// don't do this -#undef BLINK_AT_RAMP_MIDDLE - -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_SOS_MODE -#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-ff-pl47g2.h b/spaghetti-monster/anduril/cfg-ff-pl47g2.h deleted file mode 100644 index 830d7e8..0000000 --- a/spaghetti-monster/anduril/cfg-ff-pl47g2.h +++ /dev/null @@ -1,67 +0,0 @@ -// Fireflies PL47 G2 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0423" -#include "hwdef-ff-pl47.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the aux LEDs are in the same place as the main LEDs -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - - - -#define RAMP_SIZE 150 - -// driver is a FET + 3x7135, ~400 lm at highest regulated level -// ramp copied from Emisar D4S ramp -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,16,17,18,19,21,22,23,25,26,27,29,31,32,34,36,38,40,42,44,46,49,51,54,56,59,62,65,68,71,74,78,81,85,89,93,97,101,106,110,115,120,125,130,136,141,147,153,160,166,173,180,187,195,202,210,219,227,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,10,11,13,14,16,18,19,21,23,25,27,29,31,34,36,38,41,43,46,48,51,54,57,60,63,66,69,72,76,79,83,87,91,95,99,103,107,112,116,121,126,131,136,141,146,152,158,163,169,175,182,188,195,202,209,216,223,231,239,247,255 -#define MAX_1x7135 83 -#define HALFSPEED_LEVEL 13 -#define QUARTERSPEED_LEVEL 6 - -// ceiling is level 120/150 -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 - -// 10, 28, 46, 65, 83, 101, 120 (83 is highest regulated) -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 120 -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~25% power / ~1000 lm -// 10 34 59 [83] 108 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 108 -#define SIMPLE_UI_STEPS 5 - -// thermal regulation parameters -#ifdef MIN_THERM_STEPDOWN -#undef MIN_THERM_STEPDOWN // this should be lower, because 3x7135 instead of 1x7135 -#endif -#define MIN_THERM_STEPDOWN 60 // lowest value it'll step down to -// regulate down faster when the FET is active, slower otherwise -#define THERM_FASTER_LEVEL 135 // throttle back faster when high - -#ifndef BLINK_AT_RAMP_CEIL -#define BLINK_AT_RAMP_CEIL -#endif - -// don't do this -#undef BLINK_AT_RAMP_MIDDLE - -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_SOS_MODE -#undef USE_TACTICAL_MODE diff --git a/spaghetti-monster/anduril/cfg-ff-rot66-219.h b/spaghetti-monster/anduril/cfg-ff-rot66-219.h deleted file mode 100644 index 4dad4e2..0000000 --- a/spaghetti-monster/anduril/cfg-ff-rot66-219.h +++ /dev/null @@ -1,26 +0,0 @@ -// Fireflies ROT66-219 (7x7135) config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as regular ROT66, but calibrated for Nichia 219B with 7x7135 chips -#include "cfg-ff-rot66.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0412" - -// driver is a FET+N+1, -// where N=6 for the 219b version -// calculated to get transition points at level 65 and 115 -// first 65 steps same as regular ROT66 -// remaining steps from this command: -// level_calc.py ninth 3 150 7135 1 1.4 110.1 7135 14 1 1058.5 FET 1 10 4500 -#undef PWM2_LEVELS -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,17,18,20,21,23,25,27,29,31,33,36,38,41,43,46,49,52,55,58,62,65,69,73,77,81,86,90,95,100,105,111,116,122,128,135,141,148,155,163,170,178,187,195,204,214,224,234,244,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#undef PWM3_LEVELS -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,12,16,21,25,30,35,40,45,50,56,62,68,74,81,87,94,101,109,116,124,133,141,150,159,168,178,188,198,209,220,231,243,255 -#undef MAX_Nx7135 -#define MAX_Nx7135 115 - -// regulate down faster when the FET is active, slower otherwise -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 130 // throttle back faster when high diff --git a/spaghetti-monster/anduril/cfg-ff-rot66.h b/spaghetti-monster/anduril/cfg-ff-rot66.h deleted file mode 100644 index 752ddbb..0000000 --- a/spaghetti-monster/anduril/cfg-ff-rot66.h +++ /dev/null @@ -1,65 +0,0 @@ -// Fireflies ROT66 (14x7135) config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0411" -#include "hwdef-ff-rot66.h" - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING - -// off mode: high (2) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 2) - -#define RAMP_SIZE 150 - -// driver is a FET+N+1, -// where N=6 for the 219b version, -// or N=13 for the XP-L HI version (this version) -// calculated to get transition points at level 65 and 125 -// first 65 steps copied from FW3A -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -// remaining steps from this command: -// level_calc.py ninth 3 150 7135 1 1.4 110.1 7135 15 1 1644.16 FET 1 10 4500 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,17,18,19,20,21,22,23,25,26,27,29,30,32,34,35,37,39,41,43,46,48,50,53,55,58,61,64,67,70,73,77,81,84,88,92,97,101,106,110,115,120,126,131,137,143,149,156,162,169,177,184,192,200,208,217,226,235,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,13,21,28,35,43,51,60,68,77,87,96,106,117,127,138,150,161,173,186,199,212,226,240,255 -#define MAX_1x7135 65 -#define MAX_Nx7135 125 -#define HALFSPEED_LEVEL 14 -#define QUARTERSPEED_LEVEL 8 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL MAX_Nx7135 -// safe limit max regulated power -// 20 46 72 98 [125] -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL MAX_Nx7135 -#define SIMPLE_UI_STEPS 5 - -// regulate down faster when the FET is active, slower otherwise -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// don't do this -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_CEIL - -// enable extra features -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_MOMENTARY_MODE -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE -//#undef USE_RAMP_AFTER_MOON_CONFIG -//#undef USE_RAMP_SPEED_CONFIG -//#undef USE_VOLTAGE_CORRECTION -//#undef USE_2C_STYLE_CONFIG -//#undef USE_TACTICAL_STROBE_MODE -//#ifdef USE_LOWPASS_WHILE_ASLEEP -//#undef USE_LOWPASS_WHILE_ASLEEP -//#endif - diff --git a/spaghetti-monster/anduril/cfg-ff-rot66g2.h b/spaghetti-monster/anduril/cfg-ff-rot66g2.h deleted file mode 100644 index 04aac53..0000000 --- a/spaghetti-monster/anduril/cfg-ff-rot66g2.h +++ /dev/null @@ -1,59 +0,0 @@ -// Fireflies ROT66 G2 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-ff-rot66.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0413" - -// if the "low" mode was disabled, turn it back on -#ifdef INDICATOR_LED_SKIP_LOW -#undef INDICATOR_LED_SKIP_LOW -#endif - -// lockout: blinking (3), off: low (1) -#ifdef INDICATOR_LED_DEFAULT_MODE -#undef INDICATOR_LED_DEFAULT_MODE -#endif -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// the button is *not* visible while main LEDs are on -#undef USE_INDICATOR_LED_WHILE_RAMPING - -// ramp shape is different than original ROT66 -// 1x7135: 150 lm -// Nx7135: 1200 lm -// FET: 4500 lm -// ../../../bin/level_calc.py 7.0 3 150 7135 1 4 180.16 7135 8 1 1374.48 FET 1 10 4000 -// (plus some manual tweaks) -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#undef PWM3_LEVELS -#define PWM1_LEVELS 1,1,2,3,3,4,4,5,6,7,7,8,9,10,11,12,16,17,18,19,20,21,22,24,26,28,30,32,35,37,40,42,45,48,51,55,58,62,65,69,74,78,83,87,92,98,103,109,115,121,128,134,142,149,157,165,173,182,191,201,211,221,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,11,13,14,16,18,20,22,24,26,28,30,33,35,38,41,43,46,49,52,55,59,62,66,69,73,77,81,85,89,94,98,103,108,113,118,124,129,135,141,147,153,160,166,173,180,188,195,203,211,219,228,237,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,11,17,23,29,36,42,49,56,63,71,78,86,94,102,111,119,128,137,147,156,166,176,187,197,208,219,231,243,255 - -#undef MAX_1x7135 -#undef MAX_Nx7135 -#define MAX_1x7135 65 // ~150 lm -#define MAX_Nx7135 120 // ~1200 m -#undef HALFSPEED_LEVEL -#undef QUARTERSPEED_LEVEL -#define HALFSPEED_LEVEL 17 -#define QUARTERSPEED_LEVEL 6 - -// higher floor than default, and stop at highest regulated level -#define RAMP_SMOOTH_FLOOR 1 // ~0.3 lm -#define RAMP_SMOOTH_CEIL MAX_Nx7135 // ~1200 lm -// 10, 28, 46, [65], 83, 101, [120] -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL MAX_Nx7135 -#define RAMP_DISCRETE_STEPS 7 - -// safe limit max regulated power -// 10 37 65 92 [120] -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL MAX_Nx7135 -#define SIMPLE_UI_STEPS 5 - diff --git a/spaghetti-monster/anduril/cfg-fw3a-219.h b/spaghetti-monster/anduril/cfg-fw3a-219.h deleted file mode 100644 index 0bd5250..0000000 --- a/spaghetti-monster/anduril/cfg-fw3a-219.h +++ /dev/null @@ -1,16 +0,0 @@ -// FW3A-219 config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-fw3a.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0312" - -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#undef PWM3_LEVELS -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,13,19,25,30,36,42,48,54,61,67,73,80,86,93,100,107,114,120,128 - diff --git a/spaghetti-monster/anduril/cfg-fw3a-nofet.h b/spaghetti-monster/anduril/cfg-fw3a-nofet.h deleted file mode 100644 index b5d4166..0000000 --- a/spaghetti-monster/anduril/cfg-fw3a-nofet.h +++ /dev/null @@ -1,54 +0,0 @@ -// FW3A with the FET disabled -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-fw3a.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0313" - -// don't use channel 3 (FET) -#undef PWM_CHANNELS -#undef CH3_PIN -#undef CH3_PWM -#define PWM_CHANNELS 2 - -// reconfigure the ramp -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#undef PWM3_LEVELS -// copied from Emisar D4, mostly -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255 -#undef MAX_1x7135 -#define MAX_1x7135 65 -#undef MAX_Nx7135 -#undef HALFSPEED_LEVEL -#define HALFSPEED_LEVEL 15 -#undef QUARTERSPEED_LEVEL -#define QUARTERSPEED_LEVEL 6 - -#undef RAMP_SMOOTH_FLOOR -#undef RAMP_SMOOTH_CEIL -#undef RAMP_DISCRETE_FLOOR -#undef RAMP_DISCRETE_CEIL -#undef RAMP_DISCRETE_STEPS - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -// 10, 33, 56, 80, 103, 126, 150 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~25% power -// 10 37 65 92 120 -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL 120 - -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 130 - -// without the 3rd channel, extra features can fit -#define USE_TACTICAL_MODE - diff --git a/spaghetti-monster/anduril/cfg-fw3a.h b/spaghetti-monster/anduril/cfg-fw3a.h deleted file mode 100644 index 53c4135..0000000 --- a/spaghetti-monster/anduril/cfg-fw3a.h +++ /dev/null @@ -1,54 +0,0 @@ -// FW3A config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0311" -#include "hwdef-fw3a.h" - -#define RAMP_SIZE 150 - -// ../../bin/level_calc.py 1 65 7135 1 0.8 150 -// ... mixed with this: -// ../../../bin/level_calc.py 3 150 7135 1 0.33 150 7135 1 1 850 FET 1 10 1500 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,8,10,13,15,17,19,22,24,26,29,31,34,37,39,42,45,48,51,54,57,60,64,67,70,74,77,81,85,88,92,96,100,104,108,112,116,121,125,130,134,139,143,148,153,158,163,168,173,179,184,189,195,201,206,212,218,224,230,236,243,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,19,31,43,55,67,79,91,104,117,130,143,157,170,184,198,212,226,240,255 - -#define DEFAULT_LEVEL 50 -#define MAX_1x7135 65 -#define MAX_Nx7135 130 -#define HALFSPEED_LEVEL 15 -#define QUARTERSPEED_LEVEL 6 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL MAX_Nx7135 -// 10, 30, 50, [70], 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~20% power -// 20 40 60 80 100 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL 100 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at about 3A or ~1100 lm, this light is a hotrod -#define THERM_FASTER_LEVEL MAX_Nx7135 - -// don't blink during ramp -#define BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_FLOOR - -// enable extra features -#define USE_SMOOTH_STEPS - -// can't reset the normal way because power is connected before the button -#define USE_SOFT_FACTORY_RESET - -// too big, turn off extra features -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE - diff --git a/spaghetti-monster/anduril/cfg-fw3x-lume1.h b/spaghetti-monster/anduril/cfg-fw3x-lume1.h deleted file mode 100644 index 184ab8e..0000000 --- a/spaghetti-monster/anduril/cfg-fw3x-lume1.h +++ /dev/null @@ -1,81 +0,0 @@ -// lume1 for FW3x config options for Anduril -// Copyright (C) 2020-2023 LoneOceans, Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -/* - * Constant current Buck-Boost + FET driver - * For more information: www.loneoceans.com/labs/ - * Datasheets: - * - 1634: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8303-8-bit-AVR-Microcontroller-tinyAVR-ATtiny1634_Datasheet.pdf - * - 85: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf - */ - -#define MODEL_NUMBER "0314" -#include "hwdef-fw3x-lume1.h" -// ATTINY: 1634 - -// set this light for 50C thermal ceiling -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 50 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// it has no independent LED in the button unlike emisar d4 -//#define USE_BUTTON_LED - -// the aux LEDs are front-facing, so turn them off while main LEDs are on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// ../../bin/level_calc.py cube 1 149 7135 0 0.5 1000, with 0 appended to the end. -// for FET PWM (PWM2), all values are 0, except for last value of 1023 -// (with max_pwm set to 1023) -#define RAMP_SIZE 150 -//#define PWM1_LEVELS 0,0,0,0,1,1,1,1,2,2,2,3,3,4,4,5,5,6,7,7,8,9,10,11,12,13,14,15,16,17,19,20,22,23,25,26,28,30,32,34,36,38,40,42,45,47,49,52,55,58,60,63,66,70,73,76,80,83,87,91,94,98,102,107,111,115,120,124,129,134,139,144,150,155,160,166,172,178,184,190,196,203,209,216,223,230,237,244,252,259,267,275,283,291,299,308,316,325,334,343,353,362,372,382,392,402,412,423,433,444,455,466,478,489,501,513,525,538,550,563,576,589,602,616,630,644,658,672,687,701,716,731,747,762,778,794,810,827,844,861,878,895,913,930,948,967,985,1004,1023,0 -#define PWM1_LEVELS 1,1,1,1,2,2,2,2,3,3,3,4,4,5,5,6,6,7,8,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24,26,27,29,31,33,35,37,39,41,43,45,48,50,53,56,58,61,64,67,70,74,77,80,84,88,91,95,99,103,108,112,116,121,125,130,135,140,145,150,156,161,167,173,178,184,191,197,203,210,217,223,230,238,245,252,260,268,275,283,292,300,308,317,326,335,344,353,363,372,382,392,402,413,423,434,445,456,467,478,490,502,514,526,538,551,563,576,589,603,616,630,644,658,672,687,702,717,732,747,763,778,794,811,827,844,861,878,895,913,931,949,967,985,1004,1023,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1023 -#define DEFAULT_LEVEL 56 -#define MAX_1x7135 149 -// TODO: test if underclocking works on lume1 -//#define HALFSPEED_LEVEL 14 -//#define QUARTERSPEED_LEVEL 5 -// don't slow down at low levels; this isn't that sort of light -// (it needs to stay at full speed for the 10-bit PWM to work) -#ifdef USE_DYNAMIC_UNDERCLOCKING -#undef USE_DYNAMIC_UNDERCLOCKING -#endif - -// the entire ramp is regulated except turbo; don't blink halfway up -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 149 -// turn on BuckBoost from level 1 to 149, but not 150 -// Level 150 is when BuckBoost is off and FET is ON 100% -#define LED_ENABLE_PIN_LEVEL_MIN 1 -#define LED_ENABLE_PIN_LEVEL_MAX 149 -// 10 33 56 79 102 125 [149] -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 120 -#define SIMPLE_UI_STEPS 5 - -// slow down party strobe; this driver can't pulse for too short a time -#define PARTY_STROBE_ONTIME 4 - -// stop panicking at ~85% regulated power or ~750 lm -#define THERM_FASTER_LEVEL 140 - -#define THERM_CAL_OFFSET 0 // not needed due to external sensor - -// can't reset the normal way because power is connected before the button -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-gchart-fet1-t1616.h b/spaghetti-monster/anduril/cfg-gchart-fet1-t1616.h deleted file mode 100644 index 4082fca..0000000 --- a/spaghetti-monster/anduril/cfg-gchart-fet1-t1616.h +++ /dev/null @@ -1,63 +0,0 @@ -// gChart's custom FET+1 driver config options for Anduril -// Copyright (C) 2020-2023 gchart, Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "1618" // Golden Ratio... because I can -#include "hwdef-gchart-fet1-t1616.h" -// ATTINY: 1616 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -#define RAMP_SIZE 150 - -// 7135 at 90/150 -// level_calc.py 5.7895 2 150 7135 0 0.1 125.25 FET 1 10 1200 --pwm dyn:61:4096:255:2.5 --clock 5:11:2.0 -// (with heavy manual tweaks up to ~15/150) -#define PWM1_LEVELS 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 35, 36, 37, 38, 40, 41, 43, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 79, 84, 89, 94, 99,104,110,116,122,129,136,143,150,158,166,174,183,192,202,211,222,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 37, 39, 42, 45, 48, 51, 54, 58, 61, 65, 68, 72, 76, 80, 84, 88, 93, 97,102,107,112,117,122,127,133,139,145,151,157,163,170,177,183,191,198,205,213,221,229,238,246,255 -#define PWM_TOPS 4095,2893,3917,2806,3252,2703,2684,2660,2640,2370,3000,2900,2630,2549,2246,2193,2030,1961,1889,1716,1642,1569,1497,1428,1290,1232,1176,1122,1070,976,932,890,849,779,745,685,656,605,579,536,514,476,457,424,407,379,364,340,327,314,302,291,280,276,266,262,257,253,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 90 -#define MIN_THERM_STEPDOWN 60 -#define HALFSPEED_LEVEL 11 -#define QUARTERSPEED_LEVEL 5 -#define DEFAULT_LEVEL 50 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10 30 50 70 [90] 110 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// 10 30 50 70 [90] 110 130 -#define SIMPLE_UI_FLOOR 10 -#define SIMPLE_UI_CEIL 130 -#define SIMPLE_UI_STEPS 7 - -// stop panicking at ~50% power -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the aux LEDs by default -//#define DEFAULT_BLINK_CHANNEL CM_AUX - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 40 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// enable factory reset on 13H without loosening tailcap (required) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h b/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h deleted file mode 100644 index fb62ac6..0000000 --- a/spaghetti-monster/anduril/cfg-mateminco-mf01-mini.h +++ /dev/null @@ -1,74 +0,0 @@ -// Mateminco/Astrolux MF01-Mini options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0521" -#include "hwdef-mateminco-mf01-mini.h" - -// the button lights up -#define USE_INDICATOR_LED -//#define INDICATOR_LED_SKIP_LOW // low mode doesn't work on this driver -// the button is visible while main LEDs are on -//#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - - -#define RAMP_SIZE 150 - -// measured brightness with Sofirn 5500mAh cell at 3.97V: -// moon: 0.3 lm -// channel 1: 113 lm -// channel 2: 718 lm -// channel 3: 3500 lm -// ../../../bin/level_calc.py ninth 3 150 7135 1 2.5 115.65 7135 11 5 708.65 FET 1 10 3500 -// (plus some manual tweaks for a smoother ramp) -#define PWM1_LEVELS 1,1,2,2,3,3,4,5,5,6,7,8,9,9,10,14,15,16,17,18,19,20,21,22,24,26,28,30,32,34,37,39,42,45,48,51,54,58,62,65,69,74,78,83,88,93,98,104,110,116,123,130,137,145,153,161,170,179,188,198,208,219,231,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,13,16,18,20,23,25,28,31,34,37,40,43,47,50,54,58,62,66,70,75,80,85,90,95,100,106,112,118,125,131,138,145,153,161,169,177,185,194,204,213,223,233,244,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM3_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,6,10,13,17,21,24,28,33,37,41,46,50,55,60,66,71,76,82,88,94,101,107,114,121,128,135,143,151,159,167,176,185,194,203,213,223,233,244,255 - -#define MAX_1x7135 65 // ~113 lm -#define MAX_Nx7135 110 -#define HALFSPEED_LEVEL 16 -#define QUARTERSPEED_LEVEL 8 - -#define RAMP_SMOOTH_FLOOR 1 // ~0.3 lm -#define RAMP_SMOOTH_CEIL 130 // ~??? lm -// 14/135/6 = 14, 38, 62, 86, [110], 135 -// 20/110/7 = 20, 35, 50, [65], 80, 95, [110] -// 15/130/7 = 15, 34, 53, 72, 91, [110], 130 <-- -#define RAMP_DISCRETE_FLOOR 15 // ~?? lm -#define RAMP_DISCRETE_CEIL 130 // ~??? lm -#define RAMP_DISCRETE_STEPS 7 // ??, ??, ... lm - -// safe limit max regulated power -// 15 38 62 86 [110] -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 110 -#define SIMPLE_UI_STEPS 5 - - -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// don't blink during ramp -//#define BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_FLOOR - -// enable extra features -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#define USE_SOFT_FACTORY_RESET -//#undef USE_SIMPLE_UI -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE -#undef USE_BEACON_MODE -#undef USE_RAMP_AFTER_MOON_CONFIG -//#undef USE_RAMP_SPEED_CONFIG -#undef USE_VOLTAGE_CORRECTION -//#undef USE_2C_STYLE_CONFIG - diff --git a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h b/spaghetti-monster/anduril/cfg-mateminco-mf01s.h deleted file mode 100644 index de92693..0000000 --- a/spaghetti-monster/anduril/cfg-mateminco-mf01s.h +++ /dev/null @@ -1,61 +0,0 @@ -// Mateminco MT18S / Astrolux MF01S options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0511" -#include "hwdef-mateminco-mf01s.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -//#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - - -#define RAMP_SIZE 150 - -// measured brightness with 4x30Q cells at 4.11V: -// moon: 2.5 lm -// channel 1: 617 lm -// channel 2: 13500 lm -// ../../../bin/level_calc.py seventh 2 150 7135 1 12 717 FET 1 10 13000 -// (with some manual tweaks afterward) -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,7,7,8,9,10,11,12,13,14,15,17,18,19,21,22,24,26,28,30,32,34,36,38,41,44,46,49,52,55,59,62,66,70,74,78,83,87,92,97,102,108,114,120,126,133,139,147,154,162,170,178,187,196,206,215,226,236,248,255,235,255,240,255,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,3,3,4,4,5,6,7,8,9,10,11,12,13,14,16,17,19,20,22,23,25,26,28,30,31,33,35,37,39,41,43,45,47,49,52,54,57,59,62,65,67,70,73,76,80,83,86,90,93,97,101,105,109,113,117,122,126,131,135,140,145,151,156,161,167,173,179,185,191,197,204,211,218,225,232,239,247,255 - -#define MAX_1x7135 70 // ~626 lm -#define HALFSPEED_LEVEL 23 -#define QUARTERSPEED_LEVEL 6 - -#define RAMP_SMOOTH_FLOOR 1 // ~2.5 lm -#define RAMP_SMOOTH_CEIL 120 // ~5400 lm -// 20, 36, 53, [70], 86, 103, 120 -#define RAMP_DISCRETE_FLOOR 20 // 35 lm -#define RAMP_DISCRETE_CEIL 120 // ~5400 lm -#define RAMP_DISCRETE_STEPS 7 // 35, 108, 280, 626, 1500, 2930, 5400 lm - -// safe limit ~25% power -// 18 35 52 [70] 87 105 -#define SIMPLE_UI_FLOOR 18 -#define SIMPLE_UI_CEIL 105 -#define SIMPLE_UI_STEPS 6 - -#define THERM_FASTER_LEVEL 125 // throttle back faster when high (>6000 lm) -#define THERM_HARD_TURBO_DROP // this light is massively overpowered - -// don't blink during ramp, it's irrelevant and annoying on this light -#define BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_FLOOR - -// enable extra features -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE - diff --git a/spaghetti-monster/anduril/cfg-mateminco-mt35-mini.h b/spaghetti-monster/anduril/cfg-mateminco-mt35-mini.h deleted file mode 100644 index 1ca5008..0000000 --- a/spaghetti-monster/anduril/cfg-mateminco-mt35-mini.h +++ /dev/null @@ -1,65 +0,0 @@ -// Mateminco MT35 Mini / Astrolux FT03 -// Copyright (C) 2022-2023 (original author TBD), Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0531" -#include "hwdef-mateminco-mt35-mini.h" -// ATTINY: 85 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING - -#define RAMP_SIZE 150 - -// level_calc.py fifth 2 150 7135 1 1 120 FET 1 10 2000 -#define PWM1_LEVELS 1,2,2,3,4,5,6,7,8,9,11,13,14,16,18,21,23,26,28,31,35,38,41,45,49,53,58,63,67,73,78,84,90,96,102,109,116,124,131,139,147,156,165,174,184,194,204,215,226,237,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,3,4,5,6,7,8,9,10,11,12,14,15,16,17,18,20,21,22,24,25,27,28,30,31,33,35,36,38,40,42,43,45,47,49,51,53,55,57,59,62,64,66,68,71,73,75,78,80,83,86,88,91,94,96,99,102,105,108,111,114,117,120,124,127,130,134,137,140,144,148,151,155,159,162,166,170,174,178,182,186,190,195,199,203,208,212,217,221,226,231,235,240,245,250,255 - -#define DEFAULT_LEVEL 46 -#define MAX_1x7135 52 -#define HALFSPEED_LEVEL 20 -#define QUARTERSPEED_LEVEL 10 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 112 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~33% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// this light should be fine running a bit hotter than most -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 55 - -// stop panicking at ~40% power -#define THERM_FASTER_LEVEL 120 -#define MIN_THERM_STEPDOWN 95 // ~600 lumens -#define THERM_RESPONSE_MAGNITUDE 16 // smaller adjustments, big body. default = 64 - -#define DEFAULT_2C_STYLE 1 // enable 2 click turbo (Anduril 1 style) - -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// enable extra features -#define USE_SMOOTH_STEPS - -// too big, turn off extra features -#undef USE_TACTICAL_MODE -#undef USE_SOS_MODE -//#undef USE_RAMP_AFTER_MOON_CONFIG -//#undef USE_RAMP_SPEED_CONFIG -//#undef USE_VOLTAGE_CORRECTION -//#undef USE_2C_STYLE_CONFIG - diff --git a/spaghetti-monster/anduril/cfg-noctigon-dm11-boost.h b/spaghetti-monster/anduril/cfg-noctigon-dm11-boost.h deleted file mode 100644 index 2174fdb..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-dm11-boost.h +++ /dev/null @@ -1,91 +0,0 @@ -// Noctigon DM11 (boost driver) config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0273" -#include "hwdef-noctigon-dm11-boost.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -#define RAMP_SIZE 150 - -// power channels: -// - boost: 8A? -// - DD FET: none (can't do DD on a boost driver) - -#if 0 // old, dynamic PWM method -// level_calc.py 5.01 1 149 7135 1 0.3 1740 --pwm dyn:78:16384:255 -// (plus a 0 at the beginning for moon) -#define PWM1_LEVELS 0,1,1,1,2,3,3,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,27,29,31,34,36,39,42,44,47,50,53,57,60,63,67,70,74,77,81,85,88,92,96,99,103,107,110,113,117,120,123,126,128,130,133,134,136,137,137,137,137,136,135,133,130,126,122,117,111,104,96,87,76,65,52,38,22,23,25,26,27,28,29,30,32,33,34,36,37,39,40,42,43,45,47,49,51,53,55,57,59,61,63,66,68,70,73,76,78,81,84,87,90,93,96,99,103,106,110,113,117,121,125,129,133,137,142,146,151,155,160,165,170,175,181,186,192,197,203,209,215,222,228,234,241,248,255 -#define PWM_TOPS 16383,16383,12404,8140,11462,14700,11041,12947,13795,14111,14124,13946,13641,13248,12791,13418,12808,13057,12385,12428,12358,12209,12000,11746,11459,11147,11158,10793,10708,10576,10173,9998,9800,9585,9527,9278,9023,8901,8634,8486,8216,8053,7881,7615,7440,7261,7009,6832,6656,6422,6196,6031,5819,5615,5419,5190,4973,4803,4571,4386,4179,3955,3745,3549,3340,3145,2940,2729,2513,2312,2109,1903,1697,1491,1286,1070,871,662,459,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 150 -#define DEFAULT_LEVEL 70 -#define MIN_THERM_STEPDOWN 80 // must be > end of dynamic PWM range -#define HALFSPEED_LEVEL 12 -#define QUARTERSPEED_LEVEL 4 -#endif - -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// level_calc.py 5.01 1 150 7135 0 0.2 2000 --pwm 32640 -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,28,32,36,41,45,50,56,62,69,76,84,92,101,110,121,132,143,156,169,184,199,215,232,251,270,291,313,336,360,386,414,442,473,505,539,574,612,651,693,736,782,829,880,932,987,1045,1105,1168,1233,1302,1374,1449,1527,1608,1693,1781,1873,1969,2068,2172,2279,2391,2507,2628,2753,2883,3018,3158,3303,3454,3609,3771,3938,4111,4289,4475,4666,4864,5068,5280,5498,5724,5957,6197,6445,6701,6965,7237,7518,7808,8106,8413,8730,9056,9392,9737,10093,10459,10835,11223,11621,12031,12452,12884,13329,13786,14255,14737,15232,15741,16262,16798,17347,17911,18489,19082,19691,20314,20954,21609,22281,22969,23674,24397,25137,25895,26671,27465,28279,29111,29963,30835,31727,32640 -#define MIN_THERM_STEPDOWN 50 -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 150 -// always run at 1/4th speed, because 4 kHz PWM is enough for this circuit -// and speed changes make a big visible bump -#define HALFSPEED_LEVEL 255 -#define QUARTERSPEED_LEVEL 255 - -#define RAMP_SMOOTH_FLOOR 1 // low levels may be unreliable -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, 130 -// Nichia B35 model: (0.56), 1.4, 8.4, 34.5, [102], 250, 500, 860, (1300) lm -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~75% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~70% power or ~600 lm -#define THERM_FASTER_LEVEL 130 - -#define THERM_CAL_OFFSET 5 - -// the power regulator seems to "jump start" the LEDs all on its own, -// so the firmware doesn't have to -// (and unfortunately the power regulator jumps it a bit too hard) -#define DEFAULT_JUMP_START_LEVEL 1 -#define BLINK_BRIGHTNESS 50 -#define BLINK_ONCE_TIME 12 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// slow down party strobe; this driver can't pulse for 2ms or less -#define PARTY_STROBE_ONTIME 3 - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// added for convenience -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-noctigon-dm11-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-dm11-nofet.h deleted file mode 100644 index b2fdfdb..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-dm11-nofet.h +++ /dev/null @@ -1,49 +0,0 @@ -// Noctigon DM11 (no DD FET) config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same support functions as a KR4 -#define HWDEF_C_FILE hwdef-noctigon-kr4-nofet.c -#include "cfg-noctigon-dm11.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0272" -// ATTINY: 1634 - -// turn off the DD FET -#undef PWM_CHANNELS -#define PWM_CHANNELS 1 -#define RAMP_SIZE 150 - -// level_calc.py 5.01 1 149 7135 1 0.3 1740 --pwm dyn:78:16384:255 -#undef PWM1_LEVELS -#define PWM1_LEVELS 0,1,1,1,2,3,3,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,27,29,31,34,36,39,42,44,47,50,53,57,60,63,67,70,74,77,81,85,88,92,96,99,103,107,110,113,117,120,123,126,128,130,133,134,136,137,137,137,137,136,135,133,130,126,122,117,111,104,96,87,76,65,52,38,22,23,25,26,27,28,29,30,32,33,34,36,37,39,40,42,43,45,47,49,51,53,55,57,59,61,63,66,68,70,73,76,78,81,84,87,90,93,96,99,103,106,110,113,117,121,125,129,133,137,142,146,151,155,160,165,170,175,181,186,192,197,203,209,215,222,228,234,241,248,255 -#undef PWM2_LEVELS -#undef PWM_TOPS -#define PWM_TOPS 16383,16383,12404,8140,11462,14700,11041,12947,13795,14111,14124,13946,13641,13248,12791,13418,12808,13057,12385,12428,12358,12209,12000,11746,11459,11147,11158,10793,10708,10576,10173,9998,9800,9585,9527,9278,9023,8901,8634,8486,8216,8053,7881,7615,7440,7261,7009,6832,6656,6422,6196,6031,5819,5615,5419,5190,4973,4803,4571,4386,4179,3955,3745,3549,3340,3145,2940,2729,2513,2312,2109,1903,1697,1491,1286,1070,871,662,459,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#undef DEFAULT_LEVEL -#define DEFAULT_LEVEL 70 -#undef MAX_1x7135 -#define MAX_1x7135 150 - -// make candle mode wobble more -#ifdef CANDLE_AMPLITUDE -#undef CANDLE_AMPLITUDE -#endif -#define CANDLE_AMPLITUDE 33 - - -// slow down party strobe; this driver can't pulse for 1ms or less -// (only needed on no-FET build) -#define PARTY_STROBE_ONTIME 2 - -// jump start a bit higher than base driver -#undef DEFAULT_JUMP_START_LEVEL -#define DEFAULT_JUMP_START_LEVEL 25 - -// stop panicking at ~70% power or ~600 lm -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 130 -#undef MIN_THERM_STEPDOWN -#define MIN_THERM_STEPDOWN 80 // must be > end of dynamic PWM range - diff --git a/spaghetti-monster/anduril/cfg-noctigon-dm11-sbt90.h b/spaghetti-monster/anduril/cfg-noctigon-dm11-sbt90.h deleted file mode 100644 index 9fac446..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-dm11-sbt90.h +++ /dev/null @@ -1,46 +0,0 @@ -// Noctigon DM11-SBT90.2 config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-noctigon-kr4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0274" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// ... and a single LED in the button -#define USE_BUTTON_LED -// don't use aux LEDs while main LED is on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// power channels: -// - linear: 5A? -// - FET: DD - -#undef DEFAULT_LEVEL -#define DEFAULT_LEVEL 70 - -#undef RAMP_SMOOTH_FLOOR -#define RAMP_SMOOTH_FLOOR 10 // low levels may be unreliable -// 10, 30, 50, [70], 90, 110, 130 -#undef RAMP_DISCRETE_FLOOR -#define RAMP_DISCRETE_FLOOR 10 - -// safe limit ~75% power -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL - -// stop panicking at ~70% power or ~600 lm -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 130 - -#undef BLINK_BRIGHTNESS -#define BLINK_BRIGHTNESS 50 - -#undef CANDLE_AMPLITUDE -#define CANDLE_AMPLITUDE 30 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-dm11.h b/spaghetti-monster/anduril/cfg-noctigon-dm11.h deleted file mode 100644 index cd6bc9d..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-dm11.h +++ /dev/null @@ -1,88 +0,0 @@ -// Noctigon DM11 config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0271" -#include "hwdef-noctigon-dm11.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// ... and a single LED in the button -#define USE_BUTTON_LED -// don't use aux LEDs while main LED is on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -#define RAMP_SIZE 150 - -// power channels: -// - linear: 5A? -// - FET: DD - -// maxreg at 130, dynamic PWM: level_calc.py 5.01 2 149 7135 1 0.3 1740 FET 1 10 3190 --pwm dyn:64:16384:255 -// (plus one extra level at the beginning for moon) -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,7,8,9,11,12,14,16,17,19,22,24,26,29,31,34,37,40,43,46,49,53,56,60,63,67,71,74,78,82,86,89,93,96,99,103,105,108,110,112,114,115,116,116,115,114,112,109,106,101,95,89,81,71,60,48,34,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,20,30,41,52,63,75,87,99,112,125,138,151,165,179,194,208,224,239,255 -#define PWM_TOPS 16383,16383,11750,14690,9183,12439,13615,13955,13877,13560,13093,12529,13291,12513,12756,12769,11893,11747,12085,11725,11329,11316,10851,10713,10518,10282,10016,9729,9428,9298,8971,8794,8459,8257,8043,7715,7497,7275,7052,6753,6538,6260,5994,5798,5501,5271,5006,4758,4525,4268,4030,3775,3508,3263,3010,2752,2517,2256,1998,1763,1512,1249,994,749,497,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MIN_THERM_STEPDOWN 66 // should be above highest dyn_pwm level - -#define MAX_1x7135 130 -#define DEFAULT_LEVEL 70 -#define HALFSPEED_LEVEL 12 -#define QUARTERSPEED_LEVEL 4 - -#define RAMP_SMOOTH_FLOOR 10 // low levels may be unreliable -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~75% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~70% power or ~600 lm -#define THERM_FASTER_LEVEL 130 - -#define THERM_CAL_OFFSET 5 - - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 21 -#define BLINK_BRIGHTNESS 50 -#define BLINK_ONCE_TIME 12 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// there is usually no lighted button, so -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// slow down party strobe; this driver can't pulse for 1ms or less -// (only needed on no-FET build) -//#define PARTY_STROBE_ONTIME 2 - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// make candle mode wobble more -#define CANDLE_AMPLITUDE 30 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// added for convenience -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1-boost.h b/spaghetti-monster/anduril/cfg-noctigon-k1-boost.h deleted file mode 100644 index 0684ce7..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k1-boost.h +++ /dev/null @@ -1,96 +0,0 @@ -// Noctigon K1 boost config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0253" -#include "hwdef-noctigon-k1-boost.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// Most K1 lights can run hotter than default, but the 12V model -// is known to have issues with the driver itself getting too hot. -// This then causes the main LEDs to turn off during use, because the -// boost chip's built-in protection activates. So try to keep the -// temperature relatively low. -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 45 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 25 -#define USE_INDICATOR_LED_WHILE_RAMPING - -#if 0 // old, 10-bit PWM method -// level_calc.py cube 1 150 7135 0 4 1300 -// (with max_pwm set to 1023) -// (level 0 is usable on this light) -#define RAMP_LENGTH 150 -#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,5,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,22,23,25,26,28,30,31,33,35,37,39,42,44,46,48,51,53,56,59,61,64,67,70,73,76,80,83,86,90,94,97,101,105,109,113,117,122,126,130,135,140,144,149,154,159,165,170,175,181,187,193,198,204,211,217,223,230,236,243,250,257,264,271,279,286,294,302,310,318,326,334,343,351,360,369,378,387,397,406,416,426,436,446,456,466,477,488,499,510,521,532,544,555,567,579,591,604,616,629,642,655,668,682,695,709,723,737,751,766,780,795,810,825,841,856,872,888,904,921,937,954,971,988,1005,1023 -#define MAX_1x7135 50 -// don't slow down at low levels; this isn't that sort of light -// (it needs to stay at full speed for the 10-bit PWM to work) -#ifdef USE_DYNAMIC_UNDERCLOCKING -#undef USE_DYNAMIC_UNDERCLOCKING -#endif -#endif - -#define RAMP_SIZE 150 -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// level_calc.py 5.01 1 150 7135 0 0.2 2000 --pwm 32640 -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,28,32,36,41,45,50,56,62,69,76,84,92,101,110,121,132,143,156,169,184,199,215,232,251,270,291,313,336,360,386,414,442,473,505,539,574,612,651,693,736,782,829,880,932,987,1045,1105,1168,1233,1302,1374,1449,1527,1608,1693,1781,1873,1969,2068,2172,2279,2391,2507,2628,2753,2883,3018,3158,3303,3454,3609,3771,3938,4111,4289,4475,4666,4864,5068,5280,5498,5724,5957,6197,6445,6701,6965,7237,7518,7808,8106,8413,8730,9056,9392,9737,10093,10459,10835,11223,11621,12031,12452,12884,13329,13786,14255,14737,15232,15741,16262,16798,17347,17911,18489,19082,19691,20314,20954,21609,22281,22969,23674,24397,25137,25895,26671,27465,28279,29111,29963,30835,31727,32640 -#define MIN_THERM_STEPDOWN 50 -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 150 -// always run at 1/4th speed, because 4 kHz PWM is enough for this circuit -// and speed changes make a big visible bump -#define HALFSPEED_LEVEL 255 -#define QUARTERSPEED_LEVEL 255 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~50% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 120 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~70% power or ~600 lm -#define THERM_FASTER_LEVEL 130 - -#define THERM_CAL_OFFSET 5 - -#define THERM_RESPONSE_MAGNITUDE 32 // smaller adjustments, this host changes temperature slowly -#define THERM_NEXT_WARNING_THRESHOLD 32 // more error tolerance before adjusting - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 4 - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// make candle mode wobble more -#define CANDLE_AMPLITUDE 33 - -// the entire ramp is regulated; don't blink halfway up -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// added for convenience -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h b/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h deleted file mode 100644 index 568ff95..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k1-sbt90.h +++ /dev/null @@ -1,96 +0,0 @@ -// Noctigon K1-SBT90.2 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// (is a K1 host with a KR4-like driver and a really high-powered LED) -#define MODEL_NUMBER "0252" -#include "hwdef-noctigon-k1-sbt90.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light can safely run a bit hotter than most -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 55 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 10 -#define USE_INDICATOR_LED_WHILE_RAMPING - - -// brightness: -// 0/1023: 0.35 lm -// 1/1023: 2.56 lm -// max regulated: 1740 lm -// FET: ~3700 lm -#define RAMP_SIZE 150 -// FIXME: it should probably have max_regulated at 120, not 130 -// ramp copied from noctigon-kr4 -// nice low lows, but might have visible ripple on some lights: -// maxreg at 130, dynamic PWM: level_calc.py 5.01 2 149 7135 1 0.3 1740 FET 1 10 3190 --pwm dyn:64:16384:255 -// (plus one extra level at the beginning for moon) -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,7,8,9,11,12,14,16,17,19,22,24,26,29,31,34,37,40,43,46,49,53,56,60,63,67,71,74,78,82,86,89,93,96,99,103,105,108,110,112,114,115,116,116,115,114,112,109,106,101,95,89,81,71,60,48,34,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,20,30,41,52,63,75,87,99,112,125,138,151,165,179,194,208,224,239,255 -#define PWM_TOPS 16383,16383,11750,14690,9183,12439,13615,13955,13877,13560,13093,12529,13291,12513,12756,12769,11893,11747,12085,11725,11329,11316,10851,10713,10518,10282,10016,9729,9428,9298,8971,8794,8459,8257,8043,7715,7497,7275,7052,6753,6538,6260,5994,5798,5501,5271,5006,4758,4525,4268,4030,3775,3508,3263,3010,2752,2517,2256,1998,1763,1512,1249,994,749,497,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MIN_THERM_STEPDOWN 66 // should be above highest dyn_pwm level - -#define MAX_1x7135 130 -#define DEFAULT_LEVEL 50 -#define HALFSPEED_LEVEL 12 -#define QUARTERSPEED_LEVEL 4 - -#if 0 // original 10-bit ramp -// maxreg at 130: level_calc.py cube 2 150 7135 0 2.5 1740 FET 1 10 2565 -// maxreg at 120: level_calc.py cube 2 150 7135 0 2.5 1740 FET 1 10 3190 -#define PWM1_LEVELS 0,0,1,1,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,15,17,19,20,22,24,26,28,30,33,35,38,40,43,46,49,52,55,59,62,66,70,74,78,82,86,91,96,100,105,111,116,121,127,133,139,145,151,158,165,172,179,186,193,201,209,217,225,234,243,251,261,270,280,289,299,310,320,331,342,353,364,376,388,400,412,425,438,451,464,478,492,506,521,536,551,566,582,597,614,630,647,664,681,699,717,735,754,772,792,811,831,851,871,892,913,935,956,978,1001,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,51,79,109,138,168,198,229,260,292,324,357,390,423,457,492,527,562,598,634,671,708,746,784,822,861,901,941,982,1023 -#define DEFAULT_LEVEL 46 -#define MAX_1x7135 120 -#define HALFSPEED_LEVEL 10 -#define QUARTERSPEED_LEVEL 2 -#endif - -#define RAMP_SMOOTH_FLOOR 11 // low levels may be unreliable -#define RAMP_SMOOTH_CEIL 130 -// 11 30 [50] 70 90 110 [130] -#define RAMP_DISCRETE_FLOOR 11 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~33% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 120 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~40% power or ~1700 lm -#define THERM_FASTER_LEVEL 130 -//#define THERM_NEXT_WARNING_THRESHOLD 16 // accumulate less error before adjusting -//#define THERM_RESPONSE_MAGNITUDE 128 // bigger adjustments - -#define THERM_CAL_OFFSET 5 - -// the power regulator is a bit slow, so push it harder for a quick response from off -// (unsure if necessary, copied from noctigon-kr4) -//#define DEFAULT_JUMP_START_LEVEL 21 -//#define BLINK_BRIGHTNESS DEFAULT_LEVEL -//#define BLINK_ONCE_TIME 12 - -// there is usually no lighted button, so -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// normal party strobe speed; this driver can pulse very quickly due to its DD FET -//#define PARTY_STROBE_ONTIME 2 - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// for compatibility with other models -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k1.h b/spaghetti-monster/anduril/cfg-noctigon-k1.h deleted file mode 100644 index b2d4697..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k1.h +++ /dev/null @@ -1,83 +0,0 @@ -// Noctigon K1 config options for Anduril -// Copyright (C) 2019-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0251" -// (originally known as Emisar D1S v2) -#include "hwdef-noctigon-k1.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light can safely run a bit hotter than most -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 55 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -#define USE_AUX_RGB_LEDS_WHILE_ON 5 -#define USE_INDICATOR_LED_WHILE_RAMPING - - -#define RAMP_SIZE 150 - -// ../../bin/level_calc.py cube 1 150 7135 1 4 1300 -// (with max_pwm set to 1023) -// (level 0 flickers and isn't relevant on a thrower, so it's omitted) -#define RAMP_LENGTH 150 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21,23,24,26,27,29,31,32,34,36,38,40,43,45,47,49,52,54,57,60,62,65,68,71,74,77,81,84,87,91,95,98,102,106,110,114,118,122,127,131,136,141,145,150,155,160,166,171,176,182,188,193,199,205,211,218,224,231,237,244,251,258,265,272,280,287,295,303,310,319,327,335,344,352,361,370,379,388,397,407,416,426,436,446,457,467,477,488,499,510,521,533,544,556,568,580,592,604,617,629,642,655,668,682,695,709,723,737,751,766,781,795,810,826,841,857,872,888,904,921,937,954,971,988,1005,1023 - -#define MAX_1x7135 50 -#define DEFAULT_LEVEL 50 -#define MIN_THERM_STEPDOWN 50 // should be above highest dyn_pwm level -//#define HALFSPEED_LEVEL 12 -//#define QUARTERSPEED_LEVEL 4 -// don't slow down at low levels; this isn't that sort of light -// (it needs to stay at full speed for the 10-bit PWM to work) -#ifdef USE_DYNAMIC_UNDERCLOCKING -#undef USE_DYNAMIC_UNDERCLOCKING -#endif - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, [50], 70, 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~75% power -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~70% power or ~600 lm -#define THERM_FASTER_LEVEL 130 - -#define THERM_CAL_OFFSET 5 - -#define THERM_RESPONSE_MAGNITUDE 32 // smaller adjustments, this host changes temperature slowly -#define THERM_NEXT_WARNING_THRESHOLD 32 // more error tolerance before adjusting - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 10 -#define BLINK_BRIGHTNESS DEFAULT_LEVEL -#define BLINK_ONCE_TIME 12 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// there is usually no lighted button, -// so blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 2 - -// make candle mode wobble more -#define CANDLE_AMPLITUDE 32 - -// don't blink while ramping; the entire ramp is regulated -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-219.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-219.h deleted file mode 100644 index 88abf05..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3-219.h +++ /dev/null @@ -1,15 +0,0 @@ -// Noctigon K9.3 (reduced FET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-noctigon-k9.3.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0263" -// ATTINY: 1634 - -// main LEDs -#undef PWM2_LEVELS -// 65% FET power -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,7,11,15,19,23,27,32,37,41,46,51,56,61,66,72,78,83,89,95,102,108,115,121,128,135,143,150,157,165 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h deleted file mode 100644 index 16504fd..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3-nofet.h +++ /dev/null @@ -1,12 +0,0 @@ -// Noctigon K9.3 (noFET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// no functional differences from generic emisar-2ch build -// (just use that one instead, this is only here for legacy reasons) -#include "cfg-emisar-2ch.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0262" -// ATTINY: 1634 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c b/spaghetti-monster/anduril/cfg-noctigon-k9.3.c deleted file mode 100644 index d30d397..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.c +++ /dev/null @@ -1,108 +0,0 @@ -#error This build is broken. -// Noctigon K9.3 code overrides for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -/* - * K9.3 has unusual power channels, so it must override some of FSM's code. - * There are two sets of LEDs: - * 1. Main LEDs: (9 x white LEDs) - * PWM1 (10-bit, linear) - * PWM2 (8-bit, FET, only used on some K9.3 models) - * 2. 2nd LEDs: (3 x white or color LEDs) - * PWM3 (10-bit, linear) - * - * The two sets are not used at the same time... just one or the other, - * depending on the "tint" variable. (0 = main LEDs, other value = 2nd LEDs) - */ -// if the gradual adjustment mechanism doesn't work, disable it here: -//#ifdef USE_SET_LEVEL_GRADUALLY -//#undef USE_SET_LEVEL_GRADUALLY -//#endif - -// this is inserted into fsm-ramping.c :: set_level() -// (it overrides part of the function, but not all of it) -inline void set_level_override(uint8_t level) { - if (level == 0) { // off - PWM1_LVL = 0; - PWM2_LVL = 0; - PWM3_LVL = 0; - // disable both power channels - LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); - LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); - } else { - level --; - - if (! tint) { // main LEDs - // enable this power channel - LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); - // disable other power channel - LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); - // set levels - PWM1_LVL = PWM_GET(pwm1_levels, level); - #ifndef K93_NO_FET - PWM2_LVL = (uint8_t)(PWM_GET(pwm2_levels, level) >> 2); // 8 bits - #endif - PWM3_LVL = 0; - } else { // 2nd LEDs - // disable other power channel - LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); - // enable this power channel - LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); - // set levels - PWM1_LVL = 0; - PWM2_LVL = 0; - PWM3_LVL = PWM_GET(pwm3_levels, level); - } - } -} - -// override fsm-ramping.c :: gradual_tick() -// (because the power handling on this light is weird) -// call this every frame or every few frames to change brightness very smoothly -void gradual_tick() { - // go by only one ramp level at a time instead of directly to the target - uint8_t gt = gradual_target; - if (gt < actual_level) gt = actual_level - 1; - else if (gt > actual_level) gt = actual_level + 1; - - gt --; // convert 1-based number to 0-based - - PWM_DATATYPE target; - - if (! tint) { // main LED channel - target = PWM_GET(pwm1_levels, gt); - if ((gt < actual_level) // special case for FET-only turbo - && (PWM1_LVL == 0) // (bypass adjustment period for first step) - && (target == PWM_TOP)) PWM1_LVL = PWM_TOP; - else if (PWM1_LVL < target) PWM1_LVL ++; - else if (PWM1_LVL > target) PWM1_LVL --; - - #ifndef K93_NO_FET // skip this on E21A model - target = PWM_GET(pwm2_levels, gt) >> 2; // 8 bits, not 10 - if (PWM2_LVL < target) PWM2_LVL ++; - else if (PWM2_LVL > target) PWM2_LVL --; - #endif - - // did we go far enough to hit the next defined ramp level? - // if so, update the main ramp level tracking var - if ((PWM1_LVL == PWM_GET(pwm1_levels, gt)) - #ifndef K93_NO_FET - && (PWM2_LVL == (PWM_GET(pwm2_levels, gt) >> 2)) - #endif - ) - { actual_level = gt + 1; } - } else { // 2nd LED channel - target = PWM_GET(pwm3_levels, gt); - if (PWM3_LVL < target) PWM3_LVL ++; - else if (PWM3_LVL > target) PWM3_LVL --; - - // did we go far enough to hit the next defined ramp level? - // if so, update the main ramp level tracking var - if ( PWM3_LVL == PWM_GET(pwm3_levels, gt) ) - { actual_level = gt + 1; } - } - -} - diff --git a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h b/spaghetti-monster/anduril/cfg-noctigon-k9.3.h deleted file mode 100644 index ba24504..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-k9.3.h +++ /dev/null @@ -1,111 +0,0 @@ -// Noctigon K9.3 config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0261" -#include "hwdef-emisar-2ch-fet.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// the aux LEDs are front-facing, so turn them off while main LEDs are on -// it also has an independent LED in the button -#define USE_BUTTON_LED -// TODO: the whole "indicator LED" thing needs to be refactored into -// "aux LED(s)" and "button LED(s)" since they work a bit differently -// enabling this option breaks the button LED on D4v2.5 -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -// enable max brightness out of the box -#define DEFAULT_CHANNEL_MODE CM_BOTH - -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_BOTH - -#define POLICE_COLOR_STROBE_CH1 CM_CH1 -#define POLICE_COLOR_STROBE_CH2 CM_CH2 - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it - - -// main LEDs -// max regulated: 1500 to 2000 lm? -// FET: 5000 to 8000 lm? -// 2nd LEDs -// max regulated: ~1500 lm -#define RAMP_SIZE 150 - -// linear+FET ramp: maxreg at 120/150 -// level_calc.py 5.01 2 150 7135 1 0.1 1872 FET 1 10 5000 --pwm dyn:63:4096:255:3 --clock 8:16:0 -// linear segment -#define PWM1_LEVELS 1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,9,9,10,10,10,11,12,12,13,14,14,16,17,18,19,20,21,22,24,25,26,28,29,31,33,35,36,38,40,42,45,47,49,52,54,57,60,63,66,69,72,76,79,83,87,91,95,99,103,108,112,117,122,127,133,138,144,150,156,162,169,175,182,189,197,204,212,220,229,237,246,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// DD FET segment -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,11,17,24,30,36,43,50,57,64,71,79,87,95,103,111,120,129,138,147,157,167,177,187,198,209,220,231,243,255 -// PWM TOPS values -#define PWM3_LEVELS 4096,3798,3504,3214,2926,2645,2368,2098,1834,1579,1333,2304,2017,1744,1486,1242,1174,1700,1505,1323,1155,1037,1299,1163,1038,923,819,967,874,789,712,641,577,655,598,545,497,453,413,456,419,386,355,326,352,326,301,278,296,275,287,267,249,258,265,248,253,256,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -// linear-only ramp -// level_calc.py 3.11 1 150 7135 1 0.1 1750 --pwm dyn:64:4096:255:3 --clock 8:16:0 -#define PWM4_LEVELS 1,1,1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,10,10,10,11,11,11,11,11,11,11,12,12,12,12,12,12,13,13,13,14,14,14,15,15,16,17,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,33,34,35,37,38,39,41,42,44,45,47,48,50,52,53,55,57,59,61,63,65,67,69,71,73,75,77,79,82,84,86,89,91,94,97,99,102,105,107,110,113,116,119,122,125,128,132,135,138,141,145,148,152,156,159,163,167,170,174,178,182,186,190,195,199,203,208,212,217,221,226,230,235,240,245,250,255 -// PWM_TOPS values for linear-only ramp -#define PWM5_LEVELS 4096,3681,3247,2794,2328,1856,2937,2393,1860,2690,2273,1875,2281,1959,1658,1893,1646,1774,1569,1381,1466,1309,1166,1224,1104,996,1033,942,858,882,810,746,687,634,586,604,561,522,487,454,425,397,409,385,362,341,321,302,311,295,279,286,271,257,263,250,255,258,246,249,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define DEFAULT_LEVEL 65 -#define MAX_1x7135 120 -#define MAX_Nx7135 MAX_1x7135 -#define HALFSPEED_LEVEL 16 -#define QUARTERSPEED_LEVEL 8 - -#define RAMP_SMOOTH_FLOOR 10 // level 1 is unreliable (?) -#define RAMP_SMOOTH_CEIL 120 -// 10, 28, 46, [65], 83, 101, 120 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// 10, 37, [65], 92, 120 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~25% power or ~1000 lm -#define THERM_FASTER_LEVEL 100 -#define MIN_THERM_STEPDOWN 60 // should be above highest dyn_pwm level - -#define USE_POLICE_COLOR_STROBE_MODE -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) // high, low, police strobe - -// use the brightest setting for strobe -#define STROBE_BRIGHTNESS MAX_LEVEL -// slow down party strobe; this driver can't pulse for 1ms or less -#define PARTY_STROBE_ONTIME 2 -// TODO: change speed per channel mode -// (the FET is really fast, but the regulator is not) -//#undef PARTY_STROBE_ONTIME - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 33 - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 35 -#define BLINK_BRIGHTNESS 30 -#define BLINK_ONCE_TIME 12 // longer blink, since main LEDs are slow - -#define THERM_CAL_OFFSET 5 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-219.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-219.h deleted file mode 100644 index 5d106ef..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4-219.h +++ /dev/null @@ -1,17 +0,0 @@ -// Noctigon KR4 (reduced FET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-noctigon-kr4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0213" -// ATTINY: 1634 - -// don't turn off first channel at turbo level -#undef PWM1_LEVELS -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,7,8,9,11,12,14,16,17,19,22,24,26,29,31,34,37,40,43,46,49,53,56,60,63,67,71,74,78,82,86,89,93,96,99,103,105,108,110,112,114,115,116,116,115,114,112,109,106,101,95,89,81,71,60,48,34,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 60% FET power -#undef PWM2_LEVELS -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,12,18,25,32,38,45,53,60,68,75,83,91,99,108,117,125,135,144,153 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-219b.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-219b.h deleted file mode 100644 index b242048..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4-219b.h +++ /dev/null @@ -1,17 +0,0 @@ -// Noctigon KR4 (reduced FET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-noctigon-kr4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0214" -// ATTINY: 1634 - -// don't turn off first channel at turbo level -#undef PWM1_LEVELS -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,7,8,9,11,12,14,16,17,19,22,24,26,29,31,34,37,40,43,46,49,53,56,60,63,67,71,74,78,82,86,89,93,96,99,103,105,108,110,112,114,115,116,116,115,114,112,109,106,101,95,89,81,71,60,48,34,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -// 50% FET power -#undef PWM2_LEVELS -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,10,15,21,26,32,38,44,50,56,63,69,76,83,90,97,104,112,120,128 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-2ch.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-2ch.h deleted file mode 100644 index 09dd604..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4-2ch.h +++ /dev/null @@ -1,16 +0,0 @@ -// Noctigon KR4 2-channel config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// (basically the same as Emisar generic 2-channel build, -// but switch on a different pin, and no lighted button) -// ATTINY: 1634 -#include "hwdef-noctigon-kr4-2ch.h" -#include "cfg-emisar-2ch.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0215" - -// the button doesn't light up -#undef USE_BUTTON_LED - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-boost.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-boost.h deleted file mode 100644 index 1603acf..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4-boost.h +++ /dev/null @@ -1,16 +0,0 @@ -// Noctigon KR4 (12V) config options for Anduril -// (and Noctigon KR1) -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// the only things different from dm11-boost are: -// - e-switch is on a different pin (defined in hwdef) -// - different model number -#include "cfg-noctigon-dm11-boost.h" -#include "hwdef-noctigon-kr4-boost.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0216" -#include "hank-cfg.h" -// ATTINY: 1634 - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h b/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h deleted file mode 100644 index 6d49a8b..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4-nofet.h +++ /dev/null @@ -1,66 +0,0 @@ -// Noctigon KR4 (no DD FET) config options for Anduril -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// (and Noctigon KR1) -// (and Emisar D4v2 E21A, a.k.a. "D4v2.5") -#define HWDEF_C_FILE hwdef-noctigon-kr4-nofet.c -#include "cfg-noctigon-kr4.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0212" -// ATTINY: 1634 - -// brightness w/ SST-20 4000K LEDs: -// 0/1023: 0.35 lm -// 1/1023: 2.56 lm -// max regulated: 1740 lm -#undef PWM_CHANNELS -#define PWM_CHANNELS 1 -#define RAMP_SIZE 150 -// prioritize low lows, at risk of visible ripple -// level_calc.py 5.01 1 149 7135 1 0.3 1740 --pwm dyn:78:16384:255 -#undef PWM1_LEVELS -#define PWM1_LEVELS 0,1,1,1,2,3,3,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,27,29,31,34,36,39,42,44,47,50,53,57,60,63,67,70,74,77,81,85,88,92,96,99,103,107,110,113,117,120,123,126,128,130,133,134,136,137,137,137,137,136,135,133,130,126,122,117,111,104,96,87,76,65,52,38,22,23,25,26,27,28,29,30,32,33,34,36,37,39,40,42,43,45,47,49,51,53,55,57,59,61,63,66,68,70,73,76,78,81,84,87,90,93,96,99,103,106,110,113,117,121,125,129,133,137,142,146,151,155,160,165,170,175,181,186,192,197,203,209,215,222,228,234,241,248,255 -#undef PWM2_LEVELS -#undef PWM_TOPS -#define PWM_TOPS 16383,16383,12404,8140,11462,14700,11041,12947,13795,14111,14124,13946,13641,13248,12791,13418,12808,13057,12385,12428,12358,12209,12000,11746,11459,11147,11158,10793,10708,10576,10173,9998,9800,9585,9527,9278,9023,8901,8634,8486,8216,8053,7881,7615,7440,7261,7009,6832,6656,6422,6196,6031,5819,5615,5419,5190,4973,4803,4571,4386,4179,3955,3745,3549,3340,3145,2940,2729,2513,2312,2109,1903,1697,1491,1286,1070,871,662,459,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#undef DEFAULT_LEVEL -#define DEFAULT_LEVEL 50 -#undef MAX_1x7135 -#define MAX_1x7135 150 - -#undef RAMP_SMOOTH_FLOOR -#undef RAMP_SMOOTH_CEIL -#undef RAMP_DISCRETE_FLOOR -#undef RAMP_DISCRETE_CEIL -#undef RAMP_DISCRETE_STEPS - -#define RAMP_SMOOTH_FLOOR 11 // low levels may be unreliable -#define RAMP_SMOOTH_CEIL 130 -// 11, 30, [50], 70, 90, 110, 130 (plus [150] on turbo) -#define RAMP_DISCRETE_FLOOR 11 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~1000 lm (can sustain 900 lm) -#undef SIMPLE_UI_FLOOR -#undef SIMPLE_UI_CEIL -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL - - -// slow down party strobe; this driver can't pulse for 1ms or less -// (only needed on no-FET build) -#define PARTY_STROBE_ONTIME 2 - -// jump start a bit higher than base driver -#undef DEFAULT_JUMP_START_LEVEL -#define DEFAULT_JUMP_START_LEVEL 25 - -// stop panicking at ~1300 lm -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 140 -#undef MIN_THERM_STEPDOWN -#define MIN_THERM_STEPDOWN 80 // must be > end of dynamic PWM range - diff --git a/spaghetti-monster/anduril/cfg-noctigon-kr4.h b/spaghetti-monster/anduril/cfg-noctigon-kr4.h deleted file mode 100644 index 5b24ef5..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-kr4.h +++ /dev/null @@ -1,89 +0,0 @@ -// Noctigon KR4 config options for Anduril -// (and Emisar D4v2.5, which uses KR4 driver plus a button LED) -// Copyright (C) 2020-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0211" -#include "hwdef-noctigon-kr4.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// brightness w/ SST-20 4000K LEDs: -// 0/1023: 0.35 lm -// 1/1023: 2.56 lm -// max regulated: 1740 lm -// FET: ~3700 lm -#define RAMP_SIZE 150 - -// nice low lows, but might have visible ripple on some lights: -// maxreg at 130, dynamic PWM: level_calc.py 5.01 2 149 7135 1 0.3 1740 FET 1 10 3190 --pwm dyn:64:16384:255 -// (plus one extra level at the beginning for moon) -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,7,8,9,11,12,14,16,17,19,22,24,26,29,31,34,37,40,43,46,49,53,56,60,63,67,71,74,78,82,86,89,93,96,99,103,105,108,110,112,114,115,116,116,115,114,112,109,106,101,95,89,81,71,60,48,34,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,20,30,41,52,63,75,87,99,112,125,138,151,165,179,194,208,224,239,255 -#define PWM_TOPS 16383,16383,11750,14690,9183,12439,13615,13955,13877,13560,13093,12529,13291,12513,12756,12769,11893,11747,12085,11725,11329,11316,10851,10713,10518,10282,10016,9729,9428,9298,8971,8794,8459,8257,8043,7715,7497,7275,7052,6753,6538,6260,5994,5798,5501,5271,5006,4758,4525,4268,4030,3775,3508,3263,3010,2752,2517,2256,1998,1763,1512,1249,994,749,497,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MIN_THERM_STEPDOWN 66 // should be above highest dyn_pwm level - -// less ripple, but lows are a bit higher than ideal: -// maxreg at 130, dynamic PWM: level_calc.py 5.01 2 149 7135 1 0.3 1740 FET 1 10 3190 --pwm dyn:64:4096:255 -// (plus one extra level at the beginning for moon) -//#define PWM1_LEVELS 0,1,1,1,1,1,1,2,2,2,2,3,3,3,4,4,5,5,6,6,7,8,8,9,10,11,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,32,33,33,34,34,34,34,34,34,33,32,31,30,28,26,24,21,19,20,21,22,23,24,26,27,28,30,31,32,34,36,37,39,41,43,45,47,49,51,53,56,58,61,63,66,69,72,75,78,81,84,88,91,95,99,103,107,111,115,119,124,129,133,138,143,149,154,159,165,171,177,183,189,196,203,210,217,224,231,239,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -//#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,20,30,41,52,63,75,87,99,112,125,138,151,165,179,194,208,224,239,255 -//#define PWM_TOPS 4095,4095,3760,3403,3020,2611,2176,3582,3062,2515,1940,3221,2761,2283,2998,2584,3004,2631,2899,2555,2735,2836,2538,2606,2636,2638,2387,2382,2361,2328,2286,2238,2185,2129,2070,2010,1949,1887,1826,1766,1706,1648,1591,1536,1482,1429,1379,1329,1242,1199,1122,1084,1016,953,895,842,791,723,659,602,549,482,422,367,302,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define MAX_1x7135 130 -#define DEFAULT_LEVEL 50 -#define HALFSPEED_LEVEL 12 -#define QUARTERSPEED_LEVEL 4 - -#define RAMP_SMOOTH_FLOOR 11 // low levels may be unreliable -#define RAMP_SMOOTH_CEIL 130 -// 11 30 [50] 70 90 110 [130] -#define RAMP_DISCRETE_FLOOR 11 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// safe limit ~30% power / ~1300 lm (can sustain 900 lm) -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL 120 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~1300 lm -#define THERM_FASTER_LEVEL 120 - -#define THERM_CAL_OFFSET 5 - - -// the power regulator is a bit slow, so push it harder for a quick response from off -#define DEFAULT_JUMP_START_LEVEL 21 -#define BLINK_BRIGHTNESS DEFAULT_LEVEL -#define BLINK_ONCE_TIME 12 - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// there is usually no lighted button, so -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// slow down party strobe; this driver can't pulse for 1ms or less -// (only needed on no-FET build) -//#define PARTY_STROBE_ONTIME 2 - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// can't reset the normal way because power is connected before the button -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-noctigon-m44.h b/spaghetti-monster/anduril/cfg-noctigon-m44.h deleted file mode 100644 index 88bf628..0000000 --- a/spaghetti-monster/anduril/cfg-noctigon-m44.h +++ /dev/null @@ -1,134 +0,0 @@ -// Noctigon M44 config options for Anduril -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0143" -#include "hwdef-noctigon-m44.h" -#include "hank-cfg.h" -// ATTINY: 1634 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS -// the aux LEDs are front-facing, so turn them off while main LEDs are on -// it also has an independent LED in the button -#define USE_BUTTON_LED -// TODO: the whole "indicator LED" thing needs to be refactored into -// "aux LED(s)" and "button LED(s)" since they work a bit differently -// enabling this option breaks the button LED on D4v2.5 -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// channel modes... -// CM_CH1, CM_CH2, CM_BOTH, CM_BLEND, CM_AUTO -// enable max brightness out of the box -#define DEFAULT_CHANNEL_MODE CM_BOTH - -//#define FACTORY_RESET_WARN_CHANNEL CM_CH2 -//#define FACTORY_RESET_SUCCESS_CHANNEL CM_BOTH - -#define USE_CONFIG_COLORS -//#define CONFIG_WAITING_CHANNEL CM_CH2 -//#define CONFIG_BLINK_CHANNEL CM_BOTH - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_BOTH - -#define POLICE_COLOR_STROBE_CH1 CM_CH1 -#define POLICE_COLOR_STROBE_CH2 CM_CH2 -// aux red + aux blue are the correct colors, but are dim -//#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -//#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -#define TINT_RAMPING_CORRECTION 0 // none, linear regulator doesn't need it - -// channel 1 -// output: unknown, 6000 lm? -// channel 2 -// output: unknown, 6000 lm? -#define RAMP_SIZE 150 -#if 0 // optimized hand-tweaked ramp from before PWM+DSM update -// "100% power" ramp -// level_calc.py 5.01 1 150 7135 0 2.0 5000 --pwm dyn:64:16384:511:5 -// (with manual tweaks) -#define PWM1_LEVELS 0,1,1,2,2,3,4,5,6,6,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,10,10,11,11,12,12,13,14,15,16,17,18,19,20,21,22,23,24,26,27,28,29,31,32,34,35,37,39,40,42,44,46,48,50,52,54,57,59,62,64,67,69,72,75,78,81,84,87,91,94,98,101,105,109,113,117,121,126,130,135,140,145,150,155,160,165,171,177,183,189,195,201,208,214,221,228,236,243,251,258,266,274,283,291,300,309,318,328,337,347,357,368,378,389,400,411,423,435,447,459,472,484,498,511 -#define PWM_TOPS 16383,16383,10002,11695,8083,9374,9793,7993,8291,7017,7180,6235,5431,5556,4927,4385,3916,3511,3159,2852,2585,2349,2142,1958,1795,1648,1517,1398,1290,1193,1104,1023,950,883,822,765,714,667,623,582,632,610,588,566,544,512,535,505,523,494,509,480,492,502,509,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511 -// max "200% power" ramp and tops -// 1-130: 0 to 100% power -// level_calc.py 5.01 1 130 7135 2 0.2 2000 --pwm dyn:64:16383:511 -// 131 to 150: 101% to 200% power -// level_calc.py 6.44 1 150 7135 1 0.2 2000 --pwm dyn:74:16383:1022 -//#define PWM2_LEVELS 2,2,2,3,3,4,4,5,6,7,8,9,10,11,13,14,16,17,19,21,23,25,28,30,33,35,38,41,44,47,50,54,57,60,64,67,71,74,78,81,84,88,91,94,97,99,101,103,105,106,107,107,107,106,105,102,99,95,90,84,77,68,58,47,34,36,38,40,42,44,47,49,52,54,57,60,63,66,69,73,76,80,83,87,91,96,100,104,109,114,119,124,130,135,141,147,153,160,166,173,180,187,195,203,211,219,228,236,245,255,264,274,285,295,306,317,329,340,353,365,378,391,405,419,433,448,463,479,495,511,530,550,570,591,612,634,657,680,705,730,755,782,809,837,865,895,925,957,989,1022 -//#define PWM3_LEVELS 16383,13234,9781,13826,9593,13434,9973,12021,12900,13193,13150,12899,12508,12023,12666,11982,12181,11422,11393,11247,11018,10731,10826,10434,10365,9927,9767,9565,9332,9076,8806,8693,8395,8096,7928,7626,7439,7143,6948,6665,6393,6203,5946,5700,5465,5187,4926,4681,4451,4195,3957,3700,3463,3213,2983,2718,2476,2231,1986,1742,1501,1245,997,756,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511 -#define MIN_THERM_STEPDOWN 65 // should be above highest dyn_pwm level -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 150 -#define HALFSPEED_LEVEL 10 -#define QUARTERSPEED_LEVEL 2 -#endif // end old ramp config - -// delta-sigma modulated PWM (0b0HHHHHHHHLLLLLLL = 0, 8xHigh, 7xLow bits) -// level_calc.py 5.01 1 150 7135 0 0.2 2000 --pwm 32640 -// (max is (255 << 7), because it's 8-bit PWM plus 7 bits of DSM) -#define PWM1_LEVELS 0,1,2,3,4,5,6,7,9,10,12,14,17,19,22,25,28,32,36,41,45,50,56,62,69,76,84,92,101,110,121,132,143,156,169,184,199,215,232,251,270,291,313,336,360,386,414,442,473,505,539,574,612,651,693,736,782,829,880,932,987,1045,1105,1168,1233,1302,1374,1449,1527,1608,1693,1781,1873,1969,2068,2172,2279,2391,2507,2628,2753,2883,3018,3158,3303,3454,3609,3771,3938,4111,4289,4475,4666,4864,5068,5280,5498,5724,5957,6197,6445,6701,6965,7237,7518,7808,8106,8413,8730,9056,9392,9737,10093,10459,10835,11223,11621,12031,12452,12884,13329,13786,14255,14737,15232,15741,16262,16798,17347,17911,18489,19082,19691,20314,20954,21609,22281,22969,23674,24397,25137,25895,26671,27465,28279,29111,29963,30835,31727,32640 - -#define MIN_THERM_STEPDOWN 50 -#define DEFAULT_LEVEL 70 -#define MAX_1x7135 150 -// always run at 1/4th speed, because 4 kHz PWM is enough for this circuit -// and speed changes make a big visible bump -#define HALFSPEED_LEVEL 255 -#define QUARTERSPEED_LEVEL 255 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10, 30, 50, [70], 90, 110, 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// 10 40 [70] 100 130 -#define SIMPLE_UI_FLOOR RAMP_DISCRETE_FLOOR -#define SIMPLE_UI_CEIL RAMP_DISCRETE_CEIL -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~???? lm -#define THERM_FASTER_LEVEL 130 - -#define USE_POLICE_COLOR_STROBE_MODE -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) // high, low, police strobe - -// use the brightest setting for strobe -#define STROBE_BRIGHTNESS MAX_LEVEL -// slow down party strobe; this driver takes a while to start making any light -#define PARTY_STROBE_ONTIME 12 -//#define STROBE_OFF_LEVEL 1 // nope, this makes strobe blurry -// bike strobe needs a longer pulse too? nope -#define BIKE_STROBE_ONTIME 8 - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 33 - -// party strobe, tac strobe, police, lightning, candle, bike -#define DEFAULT_STROBE_CHANNELS CM_BOTH,CM_BOTH,CM_BOTH,CM_AUTO,CM_AUTO,CM_AUTO - -// the power regulator is a bit slow, so push it harder for a quick response from off -//#define DEFAULT_JUMP_START_LEVEL 50 -//#define JUMP_START_TIME 50 -#define BLINK_BRIGHTNESS 30 -#define BLINK_ONCE_TIME 16 // longer blink, since the boost driver is slow - -#define THERM_CAL_OFFSET 5 - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// for consistency with KR4 (not otherwise necessary though) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-sofirn-lt1s-pro.h b/spaghetti-monster/anduril/cfg-sofirn-lt1s-pro.h deleted file mode 100644 index 440a03d..0000000 --- a/spaghetti-monster/anduril/cfg-sofirn-lt1s-pro.h +++ /dev/null @@ -1,125 +0,0 @@ -// Sofirn LT1S Pro config file for Anduril -// Copyright (C) 2022-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0623" -#include "hwdef-sofirn-lt1s-pro.h" -// ATTINY: 1616 - -// off mode: low (1) -// lockout: blinking (3) -// Standby power usage: -// - aux high: 6.9 mA (30 days) -// - aux low: 0.16 mA (3.5 years) -// - red moon: 2.17 mA (96 days) -// - white moon: 1.47 mA (141 days) -// Low mode isn't bright enough to be useful on this light, -// but at least it doesn't drain the battery 3X faster than moon mode. -// (it seriously would be more practical to just use moon instead) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// channel modes... -// CM_WHITE, CM_AUTO2, CM_AUTO3, CM_RED, CM_WHITE_RED -#define DEFAULT_CHANNEL_MODE CM_AUTO3 - -#define FACTORY_RESET_WARN_CHANNEL CM_RED -#define FACTORY_RESET_SUCCESS_CHANNEL CM_WHITE - -#define CONFIG_WAITING_CHANNEL CM_RED -#define CONFIG_BLINK_CHANNEL CM_WHITE - -// blink numbers on the main LEDs by default (but allow user to change it) -#define DEFAULT_BLINK_CHANNEL CM_RED - -// how much to increase total brightness at middle tint -// (0 = 100% brightness, 64 = 200% brightness) -// seems unnecessary on this light -#define TINT_RAMPING_CORRECTION 0 - -#define RAMP_SIZE 150 -// use dynamic PWM instead of plain 8-bit -// (so we can get lower lows and a smoother ramp) -// (also, red LEDs use a QX7138 chip which has max PWM speed of 10 kHz, -// and it behaves erratically at full speed, -// so PWM here is 576 clock cycles long to keep the speed low enough) -// -// This first ramp seems a bit too low: 0.2 / 1.9 / 10 / 37 / 109 / 272 / 600 lm -// level_calc.py 5.99 1 150 7135 1 0.2 600 --pwm dyn:77:16383:575:3 -//#define PWM_LEVELS 1,1,2,2,3,4,4,5,6,6,7,8,9,9,10,11,11,12,13,13,14,15,15,16,16,17,18,18,19,19,19,20,20,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,24,24,24,25,26,26,27,28,29,30,32,33,34,36,38,40,42,44,46,48,50,52,55,57,59,62,65,68,70,73,77,80,83,86,90,94,97,101,105,110,114,118,123,128,133,138,143,148,154,160,166,172,178,185,191,198,205,213,220,228,236,244,252,261,270,279,289,298,308,319,329,340,351,363,374,386,399,411,424,438,452,466,480,495,510,526,542,558,575 -//#define PWM_TOPS 16383,10869,13246,8043,11458,12772,10093,11043,11450,9664,9991,10091,10048,8868,8838,8730,7814,7724,7589,6864,6748,6604,6024,5899,5398,5287,5159,4754,4638,4287,3963,3876,3594,3511,3265,3038,2829,2770,2586,2417,2260,2115,1981,1857,1742,1636,1537,1445,1360,1281,1207,1138,1073,1013,957,904,855,848,803,760,720,714,677,643,637,630,599,592,585,577,569,579,570,560,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575 -// -// This ramp is a bit higher: 0.2 / 3 / 19 / 61 / 152 / 320 / 600 lm -// level_calc.py 4.001 1 150 7135 1 0.2 600 --pwm dyn:78:16383:575:3.333 -#define PWM1_LEVELS 1,1,2,4,5,6,7,8,9,10,12,13,14,15,17,18,19,21,22,23,24,25,26,27,28,29,30,31,32,33,33,34,34,35,35,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,37,37,38,38,39,40,40,41,43,44,45,47,48,50,52,54,56,59,62,64,67,69,72,75,78,81,84,87,90,94,97,101,104,108,112,116,120,124,128,133,137,142,147,151,156,161,167,172,177,183,189,194,200,206,213,219,226,232,239,246,253,260,268,275,283,291,299,307,316,324,333,342,351,361,370,380,390,400,410,420,431,442,453,464,476,487,499,511,523,536,549,562,575 -#define PWM_TOPS 16383,8174,7823,14429,13603,12806,12046,11328,10652,10017,10402,9742,9134,8575,8615,8089,7605,7536,7093,6684,6307,5959,5636,5337,5060,4802,4562,4337,4127,3929,3633,3468,3216,3077,2862,2744,2559,2390,2234,2091,1960,1838,1727,1623,1528,1439,1357,1280,1209,1143,1081,1024,970,919,872,828,787,770,732,716,682,668,654,624,611,613,600,587,587,574,573,571,569,566,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575,575 -// TODO? 200% power at top of ramp on white blend mode -// 2nd table handles "200% power" turbo -//#define PWM2_LEVELS ... -// tops for PWM2 -//#define PWM3_LEVELS ... -#define MAX_1x7135 75 -#define MIN_THERM_STEPDOWN 75 // should be above highest dyn_pwm level -#define HALFSPEED_LEVEL 12 -#define QUARTERSPEED_LEVEL 5 - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 40 - -// override default ramp style -#undef RAMP_STYLE -#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped -// set floor and ceiling as far apart as possible -// because this lantern isn't overpowered -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -//#define RAMP_DISCRETE_FLOOR 17 // 17 50 83 116 150 -#define RAMP_DISCRETE_FLOOR 1 // 1 25 50 75 100 125 150 -#define RAMP_DISCRETE_CEIL 150 -#define RAMP_DISCRETE_STEPS 7 - -// LT1S can handle heat well, so don't limit simple mode -//#define SIMPLE_UI_FLOOR 10 // 10 45 80 115 150 -#define SIMPLE_UI_FLOOR 1 -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 7 - -// Allow 3C (or 6C) in Simple UI (toggle smooth or stepped ramping) -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// turn on at med-low brightness by default (level 50/150, or ramp step 3/7) -// (also sets lockout mode 2H to a useful level) -#define DEFAULT_MANUAL_MEMORY 50 -// reset to default after being off for 10 minutes -#define DEFAULT_MANUAL_MEMORY_TIMER 10 - -// enable 2 click turbo (Anduril 1 style) -#define DEFAULT_2C_STYLE 1 - -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_COLOR_STROBE_CH1 CM_RED -#define POLICE_COLOR_STROBE_CH2 CM_WHITE - -#undef TACTICAL_LEVELS -#define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) // high, low, police strobe - -// don't blink while ramping -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -#ifdef BLINK_AT_RAMP_FLOOR -#undef BLINK_AT_RAMP_FLOOR -#endif -#ifdef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#endif -// without this, it's really hard to tell when ramping up stops -#define BLINK_AT_RAMP_CEIL - -#define USE_SOFT_FACTORY_RESET diff --git a/spaghetti-monster/anduril/cfg-sofirn-sc21-pro.h b/spaghetti-monster/anduril/cfg-sofirn-sc21-pro.h deleted file mode 100644 index 8fd2dee..0000000 --- a/spaghetti-monster/anduril/cfg-sofirn-sc21-pro.h +++ /dev/null @@ -1,14 +0,0 @@ -// Sofirn SC21 Pro - same setup as a Wurkkos TS10, but with the aux indicator on while ramping -// Copyright (C) 2022-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#include "cfg-wurkkos-ts10.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0632" -// ATTINY: 1616 - -// turn on the aux LED while main LED is on -#ifndef USE_INDICATOR_LED_WHILE_RAMPING -#define USE_INDICATOR_LED_WHILE_RAMPING -#endif diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h b/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h deleted file mode 100644 index 0e2f28d..0000000 --- a/spaghetti-monster/anduril/cfg-sofirn-sp10-pro.h +++ /dev/null @@ -1,81 +0,0 @@ -// Sofirn SP10 Pro config options for Anduril -// Copyright (C) 2022-2023 (original author TBD), Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0631" -#include "hwdef-sofirn-sp10-pro.h" -// ATTINY: 1616 - -// 1....15: level_calc.py 3.01 1 15 7135 1 0.1 2 --pwm dyn:15:64:64 -// 16..150: level_calc.py 5.01 1 135 7135 1 2 800 --pwm dyn:49:3072:255:3.0 -#define RAMP_SIZE 150 -#define _PWM1_LEVELS_ 1, 2, 4, 6, 9,12,15,19,23,28,34,41,48,55,64 -#define _PWM1_TOPS_ 64,64,64,64,64,64,64,64,64,64,64,64,64,64,64 -#define _PWM2_LEVELS_ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 44, 46, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 70, 72, 74, 77, 79, 82, 85, 88, 90, 93, 96, 99,103,106,109,113,116,120,123,127,131,135,139,143,147,151,156,160,165,170,175,180,185,190,195,201,206,212,218,223,230,236,242,248,255 -#define _PWM2_TOPS_ 3072,1960,2372,1476,2097,1572,1920,1570,1777,1524,1646,1454,1286,1369,1234,1115,1011,918,837,894,823,759,702,650,603,560,522,487,455,425,398,374,351,330,310,292,275,259,280,265,251,266,253,240,252,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define PWM1_LEVELS _PWM1_LEVELS_,_PWM2_TOPS_ -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,_PWM2_LEVELS_ -#define PWM_TOPS _PWM1_TOPS_,_PWM2_TOPS_ - -#define MAX_1x7135 15 -#define HALFSPEED_LEVEL 15 -#define QUARTERSPEED_LEVEL 15 -#define DEFAULT_LEVEL 50 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -// 1 25 50 [75] 100 125 150 -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// at Sofirn's request, use max (150) for the Simple UI ceiling -// 15 48 [82] 116 150 -#define SIMPLE_UI_FLOOR MAX_1x7135 -#define SIMPLE_UI_CEIL 150 -#define SIMPLE_UI_STEPS 5 - -// turn on at ~6 lm by default (level 50/150, or ramp step 2/5 or 3/7) -// (also sets lockout mode 2H to a useful level) -#define DEFAULT_MANUAL_MEMORY 50 -// reset to default after being off for 10 minutes -#define DEFAULT_MANUAL_MEMORY_TIMER 10 - -// enable SOS in the blinkies group -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// and finally, set the default ramp style to Stepped -#undef RAMP_STYLE -#define RAMP_STYLE 1 // 0 = smooth, 1 = stepped - -// stop panicking at ~30% power -#define THERM_FASTER_LEVEL 105 -#define MIN_THERM_STEPDOWN 65 // must be > end of dynamic PWM range - -// slow down party strobe; this driver can't pulse for too short a time -//#define PARTY_STROBE_ONTIME 8 -#define STROBE_OFF_LEVEL 1 // keep the regulator chip on between pulses - -// the default of 26 looks a bit flat, so increase it -#define CANDLE_AMPLITUDE 50 - -// enable 2 click turbo (replaces USE_2C_MAX_TURBO) -#define DEFAULT_2C_STYLE 1 - -// don't blink during the ramp or at the ceiling -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -#ifdef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#endif - - -// enable factory reset on 13H without loosening tailcap -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp36-t1616.h b/spaghetti-monster/anduril/cfg-sofirn-sp36-t1616.h deleted file mode 100644 index cb29e4f..0000000 --- a/spaghetti-monster/anduril/cfg-sofirn-sp36-t1616.h +++ /dev/null @@ -1,37 +0,0 @@ -// Sofirn SP36 (small Q8) config options for Anduril using the Attiny1616 -// Copyright (C) 2021-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as the BLF Q8, mostly -#include "cfg-blf-q8-t1616.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0614" -// ATTINY: 1616 - -// voltage readings were a little high with the Q8 value -#undef VOLTAGE_FUDGE_FACTOR -#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V, not 0.35V - -// the high button LED mode on this light uses too much power -// off mode: low (1) -// lockout: blinking (3) -#ifdef INDICATOR_LED_DEFAULT_MODE -#undef INDICATOR_LED_DEFAULT_MODE -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) -#endif - -// don't blink during the ramp; the button LED brightness is sufficient -// to indicate which power channel(s) are being used -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -#ifdef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#endif - -// stop panicking at ~60% power or ~3000 lm -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL 130 diff --git a/spaghetti-monster/anduril/cfg-sofirn-sp36.h b/spaghetti-monster/anduril/cfg-sofirn-sp36.h deleted file mode 100644 index 3661686..0000000 --- a/spaghetti-monster/anduril/cfg-sofirn-sp36.h +++ /dev/null @@ -1,36 +0,0 @@ -// Sofirn SP36 (small Q8) config options for Anduril -// Copyright (C) 2018-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as the BLF Q8, mostly -#include "cfg-blf-q8.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0612" - -// voltage readings were a little high with the Q8 value -#undef VOLTAGE_FUDGE_FACTOR -#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V, not 0.35V - -// the high button LED mode on this light uses too much power -// off mode: low (1) -// lockout: blinking (3) -#ifdef INDICATOR_LED_DEFAULT_MODE -#undef INDICATOR_LED_DEFAULT_MODE -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) -#endif - -// don't blink during the ramp; the button LED brightness is sufficient -// to indicate which power channel(s) are being used -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif -#ifdef BLINK_AT_RAMP_CEIL -#undef BLINK_AT_RAMP_CEIL -#endif - -// stop panicking at ~60% power or ~3000 lm -#ifdef THERM_FASTER_LEVEL -#undef THERM_FASTER_LEVEL -#endif -#define THERM_FASTER_LEVEL 130 diff --git a/spaghetti-monster/anduril/cfg-thefreeman-boost-fwaa.h b/spaghetti-monster/anduril/cfg-thefreeman-boost-fwaa.h deleted file mode 100755 index 460346e..0000000 --- a/spaghetti-monster/anduril/cfg-thefreeman-boost-fwaa.h +++ /dev/null @@ -1,116 +0,0 @@ -// thefreeman's BCK-FWAA-MP3432 (li-ion / AA) -// Copyright (C) 2023 TBD (thefreeman), Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "1632" -#include "hwdef-thefreeman-boost-fwaa-mp3432-hdr-dac-rgb.h" -// ATTINY: 1616 - -// HPRsense : 4.2+0.3+20 = 24.5mR (DMN1004UFDF+trace resistance+20mR) -// R1=165k Vsense=49.02 Iout=2001mA -// LPRsense : 2R -// transition DAC lvl 14, ramp lvl 51 -// fifth power ramp 0.06mA to 2001mA - -#define RAMP_SIZE 150 - -// 4 ramp segments: -// - low 0.55V -// - low 2.5V -// - high 0.55V -// - high 2.5V -// PWM1: DAC Data -#define PWM1_LEVELS 2, 3, 4, 5, 6, 8, 9, 11, 14, 16, 19, 23, 26, 31, 35, 41, 47, 54, 61, 69, 78, 89,100,112,125,140,155,173,191,212,234, \ - 56, 62, 68, 74, 82, 89, 97,106,115,125,136,147,159,172,186,200,215,232,249, \ - 14, 15, 17, 18, 19, 20, 22, 23, 25, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81, 86, 90, 95, 99,104,109,114,120,126,131,138,144,150,157,164,171,179,187,195,203,212,221,230,239,249, \ - 57, 59, 61, 64, 66, 69, 72, 74, 77, 80, 83, 86, 90, 93, 96,100,103,107,111,115,119,123,127,132,136,141,145,150,155,160,166,171,176,182,188,194,200,206,213,219,226,233,240,247,255 -// PWM Tops: VREF selector (0.55V=16,1.1V=17, 2.5V=18, 4.3V=19, 1.5V=20) -#define PWM_TOPS 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, \ - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 - -#define MAX_1x7135 50 -#define DEFAULT_LEVEL 44 -#define HDR_ENABLE_LEVEL_MIN 51 // when HDR FET turns ON - -// no PWM, so MCU clock speed can be slow -#define HALFSPEED_LEVEL 46 -#define QUARTERSPEED_LEVEL 45 // seems to run fine at 10kHz/4, try reducing more - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 // ~50% power, ~??? mA / ??? lm -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// 20 [45] 70 95 120 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL 120 // ~37% power, ~??? mA / ??? lm -#define SIMPLE_UI_STEPS 5 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// thermal config - -// temperature limit -#define THERM_FASTER_LEVEL 130 -#define MIN_THERM_STEPDOWN MAX_1x7135 - -//#define THERM_LOOKAHEAD 2 // 4 by default -> decrease for longer turbo -//#define THERM_NEXT_WARNING_THRESHOLD 48 // 24 by default -> increase for fewer adjustments (more stable output on large time scale) -//#define THERM_RESPONSE_MAGNITUDE 16 // 64 by default -> decrease for smaller adjustments (removes dip post turbo) -//#define THERM_WINDOW_SIZE 1 // 2 by default -> decrease for tighter temperature regulation - - -// UI - -//#define SIMPLE_UI_ACTIVE 0 // advanced UI by default - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -#define DEFAULT_2C_STYLE 1 // enable 2 click turbo - - -// AUX - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the aux LEDs are front-facing, so turn them off while main LEDs are on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - - -// Misc - -#define PARTY_STROBE_ONTIME 1 // slow down party strobe -#define STROBE_OFF_LEVEL 1 // keep the regulator chip on between pulses - -// smoother candle mode with bigger oscillations -#define CANDLE_AMPLITUDE 40 - -// enable 13H factory reset so it can be used on tail e-switch lights -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-thefreeman-boost21-6a.h b/spaghetti-monster/anduril/cfg-thefreeman-boost21-6a.h deleted file mode 100644 index 66cc2d0..0000000 --- a/spaghetti-monster/anduril/cfg-thefreeman-boost21-6a.h +++ /dev/null @@ -1,119 +0,0 @@ -// thefreeman's BST21 BST20-FWxA (no button LED) -// Copyright (C) 2023 TBD (thefreeman), Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "1631" -#include "hwdef-thefreeman-boost21-mp3431-hdr-dac-argb.h" -// ATTINY: 1616 - -// HPRsense : 1.7+0.3+5 = 7mR (DMN22M5UFG+trace resistance+5mR) -// Vsense=42.46mV, R1= 191k -// LPRsense : 1R -// transition DAC level 8, ramp level 45 -// fifth power ramp 0.1mA to 6066mA - -#define RAMP_SIZE 150 - -// 4 ramp segments: -// - low 0.55V -// - low 2.5V -// - high 0.55V -// - high 2.5V -// PWM1: DAC Data -#define PWM1_LEVELS 2, 3, 4, 5, 7, 9, 11, 13, 16, 19, 23, 28, 33, 39, 45, 53, 61, 71, 81, 93,106,121,137,155,175,196,220,246, \ - 60, 67, 74, 82, 91,100,110,121,133,146,159,174,190,207,224,244, \ - 8, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 23, 24, 26, 27, 29, 31, 33, 35, 37, 40, 42, 45, 47, 50, 53, 56, 59, 62, 66, 69, 73, 77, 81, 85, 90, 94, 99,104,109,114,120,126,132,138,144,151,158,165,173,180,188,196,205,214,223,232,242,252, \ - 57, 60, 62, 65, 67, 70, 73, 76, 78, 82, 85, 88, 91, 95, 98,102,105,109,113,117,121,126,130,135,139,144,149,154,159,164,170,175,181,187,193,199,206,212,219,225,232,240,247,255 -// PWM Tops: VREF selector (0.55V=16,1.1V=17, 2.5V=18, 4.3V=19, 1.5V=20) -#define PWM_TOPS 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, \ - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 - -#define MAX_1x7135 44 -#define DEFAULT_LEVEL 44 -#define HDR_ENABLE_LEVEL_MIN 45 // when HDR FET turns ON - -// no PWM, so MCU clock speed can be slow -#define HALFSPEED_LEVEL 41 -#define QUARTERSPEED_LEVEL 40 // seems to run fine at 10kHz/4, try reducing more - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 // 50% / 3A / 1000 lm -// 1 22 [44] 65 87 108 130 -#define RAMP_DISCRETE_FLOOR 1 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// 20 [45] 70 95 120 -#define SIMPLE_UI_FLOOR 20 -#define SIMPLE_UI_CEIL 120 // ~2.25A / ~750 lm -#define SIMPLE_UI_STEPS 5 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// thermal config - -// temperature limit -#define THERM_FASTER_LEVEL 130 // stop panicking at 50%/3A -#define MIN_THERM_STEPDOWN MAX_1x7135 - -//#define THERM_LOOKAHEAD 4 // 4 by default -> decrease for longer turbo -#define THERM_NEXT_WARNING_THRESHOLD 48 // 24 by default -> increase for fewer adjustments (more stable output on large time scale) -#define THERM_RESPONSE_MAGNITUDE 32 // 64 by default -> decrease for smaller adjustments (removes dip post turbo) -//#define THERM_WINDOW_SIZE 1 // 2 by default -> decrease for tighter temperature regulation - - -// UI - -//#define SIMPLE_UI_ACTIVE 0 // advanced UI by default - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -#define DEFAULT_2C_STYLE 1 // enable 2 click turbo - - -// AUX - -//#define USE_BUTTON_LED - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default -#define DEFAULT_BLINK_CHANNEL CM_MAIN - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// the aux LEDs are front-facing, so turn them off while main LEDs are on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - - -// Misc - -#define PARTY_STROBE_ONTIME 1 // slow down party strobe -#define STROBE_OFF_LEVEL 1 // keep the regulator chip on between pulses - -// smoother candle mode with bigger oscillations -#define CANDLE_AMPLITUDE 40 - -// enable 13H factory reset so it can be used on tail e-switch lights -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h b/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h deleted file mode 100644 index 20d2bf5..0000000 --- a/spaghetti-monster/anduril/cfg-thefreeman-lin16dac.h +++ /dev/null @@ -1,61 +0,0 @@ -// thefreeman's Linear 16 driver using DAC control -// Copyright (C) 2021-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "1630" -#include "hwdef-thefreeman-lin16dac.h" -// ATTINY: 1616 - -// the button lights up -#define USE_INDICATOR_LED -// the button is visible while main LEDs are on -#define USE_INDICATOR_LED_WHILE_RAMPING -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// level_calc.py ninth 2 150 7135 1 0.03 6.4 7135 1 6.3 1600 -#define RAMP_SIZE 150 - -// 4 ramp segments: -// - low 0.55V -// - low 2.5V -// - high 0.55V -// - high 2.5V -// PWM1: DAC Data -// FIXME: ramp stalls with 8 duplicate levels in a row -// (maybe use 1.1V Vref during that part of the ramp?) -#define PWM1_LEVELS 25, 25, 33, 41, 41, 50, 58, 66, 75, 83, 92,108,117,133,150,167,192,209,234, \ - 58, 64, 71, 80, 90, 99,110,121,134,149,163,180,198,218,241, \ - 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 25, 26, 28, 30, 32, 34, 36, 39, 41, 44, 47, 50, 53, 56, 59, 63, 67, 71, 75, 79, 84, 89, 94,100,105,112,118,124,131,139,146,154,163,172,181,191,201,212,223,234,246, \ - 57, 60, 63, 66, 69, 73, 76, 80, 84, 88, 93, 97,102,107,112,117,123,129,135,141,147,154,161,169,176,184,193,201,210,220,229,239,250,255 -// PWM Tops: VREF selector (0.55V=16,1.1V=17, 2.5V=18, 4.3V=19, 1.5V=20) -#define PWM_TOPS 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, \ - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 - -#define MAX_1x7135 34 -#define HDR_ENABLE_LEVEL_MIN 35 // bottom level of top half of the ramp -#define HALFSPEED_LEVEL 255 // always run at 1/4th speed -#define QUARTERSPEED_LEVEL 255 // because DAC doesn't use PWM - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 120 -// 10, 28, 46, [65], 83, 101, 120 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 7 - -// stop panicking at ~30% power -#define THERM_FASTER_LEVEL 123 - -// enable 2 click turbo -#define DEFAULT_2C_STYLE 1 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/cfg-wurkkos-fc13.h b/spaghetti-monster/anduril/cfg-wurkkos-fc13.h deleted file mode 100644 index 56161b4..0000000 --- a/spaghetti-monster/anduril/cfg-wurkkos-fc13.h +++ /dev/null @@ -1,17 +0,0 @@ -// Wurkkos FC13, like a TS25 but with a RGB button and no front aux -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// ATTINY: 1616 -#include "cfg-wurkkos-ts25.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0716" - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// turn on the aux LEDs while main LEDs are on -#define USE_AUX_RGB_LEDS_WHILE_ON 20 -#define USE_INDICATOR_LED_WHILE_RAMPING - diff --git a/spaghetti-monster/anduril/cfg-wurkkos-ts10-rgbaux.h b/spaghetti-monster/anduril/cfg-wurkkos-ts10-rgbaux.h deleted file mode 100644 index 6770c47..0000000 --- a/spaghetti-monster/anduril/cfg-wurkkos-ts10-rgbaux.h +++ /dev/null @@ -1,85 +0,0 @@ -// Wurkkos TS10 (RGB aux version) config options for Anduril -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// most things are the same as TS25 -#include "cfg-wurkkos-ts25.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0713" -// ATTINY: 1616 - -///// apply some config from the TS10 ///// - -// use the TS10 ramp, not the TS25 ramp -#undef PWM1_LEVELS -#undef PWM2_LEVELS -#undef PWM_TOPS -#undef MAX_1x7135 -#undef MIN_THERM_STEPDOWN -#undef HALFSPEED_LEVEL -#undef QUARTERSPEED_LEVEL -#undef DEFAULT_LEVEL -#undef RAMP_SMOOTH_FLOOR -#undef RAMP_SMOOTH_CEIL -#undef RAMP_DISCRETE_FLOOR -#undef RAMP_DISCRETE_CEIL -#undef RAMP_DISCRETE_STEPS -#undef SIMPLE_UI_FLOOR -#undef SIMPLE_UI_CEIL -#undef SIMPLE_UI_STEPS -#undef THERM_FASTER_LEVEL - -// 7135 at 90/150 -// level_calc.py 5.7895 2 150 7135 0 0.1 125.25 FET 1 10 1200 --pwm dyn:61:4096:255:2.5 --clock 5:11:2.0 -// (with heavy manual tweaks up to ~15/150) -#define PWM1_LEVELS 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 35, 36, 37, 38, 40, 41, 43, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 79, 84, 89, 94, 99,104,110,116,122,129,136,143,150,158,166,174,183,192,202,211,222,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 37, 39, 42, 45, 48, 51, 54, 58, 61, 65, 68, 72, 76, 80, 84, 88, 93, 97,102,107,112,117,122,127,133,139,145,151,157,163,170,177,183,191,198,205,213,221,229,238,246,255 -#define PWM_TOPS 4095,2893,3917,2806,3252,2703,2684,2660,2640,2370,3000,2900,2630,2549,2246,2193,2030,1961,1889,1716,1642,1569,1497,1428,1290,1232,1176,1122,1070,976,932,890,849,779,745,685,656,605,579,536,514,476,457,424,407,379,364,340,327,314,302,291,280,276,266,262,257,253,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 90 -#define MIN_THERM_STEPDOWN 60 -#define HALFSPEED_LEVEL 11 -#define QUARTERSPEED_LEVEL 5 -#define DEFAULT_LEVEL 50 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 20 38 56 [75] 93 111 130 -// 10 30 50 70 [90] 110 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// at Wurkkos's request, reduce the Simple UI ceiling a little bit -// (i.e. not 150; original config had it at 144/150, or DD FET 204/255) -// 20 47 [75] 102 130 -// 10 30 50 70 [90] 110 130 -#define SIMPLE_UI_FLOOR 10 -#define SIMPLE_UI_CEIL 130 -#define SIMPLE_UI_STEPS 7 - -// stop panicking at ~50% power -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the aux LEDs by default -#undef DEFAULT_BLINK_CHANNEL -#define DEFAULT_BLINK_CHANNEL CM_AUXWHT - -// the aux LEDs are pretty bright; set the high-mode threshold a bit higher -// (default is 15) -#define POST_OFF_VOLTAGE_BRIGHTNESS 25 - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// enable factory reset on 13H without loosening tailcap (required) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-wurkkos-ts10.h b/spaghetti-monster/anduril/cfg-wurkkos-ts10.h deleted file mode 100644 index 90839e7..0000000 --- a/spaghetti-monster/anduril/cfg-wurkkos-ts10.h +++ /dev/null @@ -1,85 +0,0 @@ -// Wurkkos TS10 (originally used Sofirn SP36-t1616 firmware) config options for Anduril using the Attiny1616 -// Copyright (C) 2022-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// same as the BLF Q8 T1616, mostly (added Dynamic PWM) -#define MODEL_NUMBER "0714" -#include "hwdef-wurkkos-ts10.h" -#include "wurkkos-cfg.h" -// ATTINY: 1616 - -// uses forward-facing aux LEDs -#define USE_INDICATOR_LED -// don't turn on the aux LEDs while main LEDs are on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif -// the high button LED mode on this light uses too much power, default to low -// off mode: low (1) -// lockout: blinking (3) -#define INDICATOR_LED_DEFAULT_MODE ((3<<2) + 1) - -// voltage readings were a little high with the Q8 value -#undef VOLTAGE_FUDGE_FACTOR -#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V, not 0.35V - -#define RAMP_SIZE 150 - -#if 0 // 2022 version by SammysHP, smooth but only level 1/150 is underclocked -// level 1 by hand, for the rest -// level_calc.py 7.01 2 149 7135 3 0.5 125 FET 1 10 1200 --pwm dyn:63:2048:255 -#define PWM1_LEVELS 1,3,3,4,5,6,7,8,9,10,12,13,14,16,17,19,20,22,24,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,64,67,70,72,75,77,80,82,85,87,89,91,93,95,96,98,99,100,100,101,100,100,99,97,95,93,90,86,82,87,91,96,100,106,111,116,122,128,134,141,147,155,162,169,177,186,194,203,213,222,232,243,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,6,7,9,11,12,14,16,18,20,22,24,27,29,31,34,37,39,42,45,48,51,54,57,61,64,68,72,75,79,83,88,92,97,101,106,111,116,121,126,132,138,144,150,156,162,169,176,183,190,197,205,213,221,229,237,246,255 -#define PWM_TOPS 2047,2047,1198,1322,1584,1676,1701,1691,1662,1622,1774,1703,1631,1692,1613,1639,1558,1564,1559,1478,1464,1444,1420,1392,1361,1329,1331,1293,1256,1246,1207,1192,1152,1133,1094,1074,1035,1013,991,954,932,897,875,842,820,790,760,731,704,678,646,622,593,566,534,510,478,452,423,393,364,338,310,280,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 90 -#define HALFSPEED_LEVEL 2 -#define QUARTERSPEED_LEVEL 2 -#endif - -// 7135 at 90/150 -// level_calc.py 5.7895 2 150 7135 0 0.1 125.25 FET 1 10 1200 --pwm dyn:61:4096:255:2.5 --clock 5:11:2.0 -// (with heavy manual tweaks up to ~15/150) -#define PWM1_LEVELS 1, 1, 2, 2, 3, 3, 4, 5, 6, 6, 8, 9, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 35, 36, 37, 38, 40, 41, 43, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 79, 84, 89, 94, 99,104,110,116,122,129,136,143,150,158,166,174,183,192,202,211,222,232,243,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 29, 31, 34, 37, 39, 42, 45, 48, 51, 54, 58, 61, 65, 68, 72, 76, 80, 84, 88, 93, 97,102,107,112,117,122,127,133,139,145,151,157,163,170,177,183,191,198,205,213,221,229,238,246,255 -#define PWM_TOPS 4095,2893,3917,2806,3252,2703,2684,2660,2640,2370,3000,2900,2630,2549,2246,2193,2030,1961,1889,1716,1642,1569,1497,1428,1290,1232,1176,1122,1070,976,932,890,849,779,745,685,656,605,579,536,514,476,457,424,407,379,364,340,327,314,302,291,280,276,266,262,257,253,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 90 -#define MIN_THERM_STEPDOWN 60 -#define HALFSPEED_LEVEL 11 -#define QUARTERSPEED_LEVEL 5 -#define DEFAULT_LEVEL 50 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 -// 10 30 50 70 [90] 110 130 -#define RAMP_DISCRETE_FLOOR 10 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// at Wurkkos's request, reduce the Simple UI ceiling a little bit -// (i.e. not 150; original config had it at 144/150, or DD FET 204/255) -// 10 30 50 70 [90] 110 130 -#define SIMPLE_UI_FLOOR 10 -#define SIMPLE_UI_CEIL 130 -#define SIMPLE_UI_STEPS 7 - -// stop panicking at ~50% power -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the aux LEDs by default -#define DEFAULT_BLINK_CHANNEL CM_AUX - -// the default of 26 looks a bit rough, so increase it to make it smoother -#define CANDLE_AMPLITUDE 33 - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - -// enable factory reset on 13H without loosening tailcap (required) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/cfg-wurkkos-ts11.h b/spaghetti-monster/anduril/cfg-wurkkos-ts11.h deleted file mode 100644 index 8955731..0000000 --- a/spaghetti-monster/anduril/cfg-wurkkos-ts11.h +++ /dev/null @@ -1,19 +0,0 @@ -// Wurkkos TS11, like a TS25 but with a RGB button and RGB front aux -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// ATTINY: 1616 -#include "cfg-wurkkos-ts25.h" -#undef MODEL_NUMBER -#define MODEL_NUMBER "0717" - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// turn on the aux LEDs while main LEDs are on -// (but not until the main LEDs are bright enough to overpower the aux) -// (setting this lower makes an annoying effect on some levels) -#define USE_AUX_RGB_LEDS_WHILE_ON 50 -#define USE_INDICATOR_LED_WHILE_RAMPING - diff --git a/spaghetti-monster/anduril/cfg-wurkkos-ts25.h b/spaghetti-monster/anduril/cfg-wurkkos-ts25.h deleted file mode 100644 index 852e91b..0000000 --- a/spaghetti-monster/anduril/cfg-wurkkos-ts25.h +++ /dev/null @@ -1,87 +0,0 @@ -// Wurkkos TS25, modelled after the TS10 but with RGB Aux -// Copyright (C) 2022-2023 (FIXME) -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define MODEL_NUMBER "0715" -#include "hwdef-wurkkos-ts25.h" -#include "wurkkos-cfg.h" -// ATTINY: 1616 - -// this light has three aux LED channels: R, G, B -#define USE_AUX_RGB_LEDS - -// don't turn on the aux LEDs while main LEDs are on -#ifdef USE_INDICATOR_LED_WHILE_RAMPING -#undef USE_INDICATOR_LED_WHILE_RAMPING -#endif - -// voltage readings were a little high with the Q8 value -#undef VOLTAGE_FUDGE_FACTOR -#define VOLTAGE_FUDGE_FACTOR 5 // add 0.25V, not 0.35V - -#define RAMP_SIZE 150 - -#if 0 // 2022 version -// level 1 by hand, for the rest -// level_calc.py 7.01 2 149 7135 3 0.5 125 FET 1 10 1200 --pwm dyn:63:2048:255 -#define PWM1_LEVELS 1,3,3,4,5,6,7,8,9,10,12,13,14,16,17,19,20,22,24,25,27,29,31,33,35,37,40,42,44,47,49,52,54,57,59,62,64,67,70,72,75,77,80,82,85,87,89,91,93,95,96,98,99,100,100,101,100,100,99,97,95,93,90,86,82,87,91,96,100,106,111,116,122,128,134,141,147,155,162,169,177,186,194,203,213,222,232,243,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,6,7,9,11,12,14,16,18,20,22,24,27,29,31,34,37,39,42,45,48,51,54,57,61,64,68,72,75,79,83,88,92,97,101,106,111,116,121,126,132,138,144,150,156,162,169,176,183,190,197,205,213,221,229,237,246,255 -#define PWM_TOPS 2047,2047,1198,1322,1584,1676,1701,1691,1662,1622,1774,1703,1631,1692,1613,1639,1558,1564,1559,1478,1464,1444,1420,1392,1361,1329,1331,1293,1256,1246,1207,1192,1152,1133,1094,1074,1035,1013,991,954,932,897,875,842,820,790,760,731,704,678,646,622,593,566,534,510,478,452,423,393,364,338,310,280,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 -#define MAX_1x7135 90 -#define HALFSPEED_LEVEL 2 -#define QUARTERSPEED_LEVEL 2 -#endif - -// 7135 at 75/150 -// level_calc.py 5.7895 2 150 7135 1 0.1 130 FET 1 10 3000 --pwm dyn:74:4096:255:3 -// (with some manual tweaks) -#define PWM1_LEVELS 1,1,2,3,3,4,5,6,7,8,9,11,12,13,15,16,18,19,21,23,26,27,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,71,74,76,78,80,82,85,87,90,93,96,100,103,107,112,116,122,127,133,140,147,154,163,171,182,192,203,215,228,241,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -// non-zero part of FET channel calculated with: -// level_calc.py 3 1 75 7135 1 200 3000 -// (FIXME? there's a visible bump when the FET kicks in, even with just 1/255) -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,7,8,10,11,13,14,16,17,19,21,22,24,26,28,30,32,34,37,39,41,44,46,48,51,54,56,59,62,65,68,71,74,77,81,84,87,91,94,98,102,106,110,114,118,122,126,130,135,139,144,148,153,158,163,168,173,178,184,189,195,200,206,212,218,224,230,236,242,248,255 -#define PWM_TOPS 4095,2701,3200,3586,2518,2778,2834,2795,2705,2587,2455,2582,2412,2247,2256,2091,2062,1907,1860,1802,1737,1605,1542,1477,1412,1347,1284,1222,1162,1105,1050,997,946,898,853,810,768,730,693,658,625,594,564,536,503,485,462,439,418,398,384,366,353,340,327,319,307,298,292,284,280,273,269,266,263,260,258,256,256,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - -#define MAX_1x7135 75 -#define DEFAULT_LEVEL 50 -#define MIN_THERM_STEPDOWN 60 -#define HALFSPEED_LEVEL 20 -#define QUARTERSPEED_LEVEL 5 - -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 150 -// 20 38 56 [75] 93 111 130 -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL 130 -#define RAMP_DISCRETE_STEPS 7 - -// at Wurkkos's request, reduce the Simple UI ceiling a little bit -// 25 50 [75] 100 125 -#define SIMPLE_UI_FLOOR 25 -#define SIMPLE_UI_CEIL 125 -#define SIMPLE_UI_STEPS 5 - -// stop panicking at ~50% power -#define THERM_FASTER_LEVEL 120 // throttle back faster when high - -// show each channel while it scroll by in the menu -#define USE_CONFIG_COLORS - -// blink numbers on the main LEDs by default -// (so battcheck will be visible while charging) -#define DEFAULT_BLINK_CHANNEL CM_MAIN -// blink numbers on the aux LEDs by default -//#define DEFAULT_BLINK_CHANNEL CM_AUXWHT - -// use aux red + aux blue for police strobe -#define USE_POLICE_COLOR_STROBE_MODE -#define POLICE_STROBE_USES_AUX -#define POLICE_COLOR_STROBE_CH1 CM_AUXRED -#define POLICE_COLOR_STROBE_CH2 CM_AUXBLU - -// don't blink mid-ramp -#ifdef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_MIDDLE -#endif - diff --git a/spaghetti-monster/anduril/channel-modes.c b/spaghetti-monster/anduril/channel-modes.c deleted file mode 100644 index b2fc8d1..0000000 --- a/spaghetti-monster/anduril/channel-modes.c +++ /dev/null @@ -1,237 +0,0 @@ -// channel-modes.c: Multi-channel functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "channel-modes.h" - -uint8_t channel_mode_state(Event event, uint16_t arg) { - #ifdef USE_CHANNEL_MODE_ARGS - static int8_t tint_ramp_direction = 1; - static uint8_t prev_tint = 0; - // don't activate auto-tint modes unless the user hits the edge - // and keeps pressing for a while - static uint8_t past_edge_counter = 0; - // bugfix: click-click-hold from off to strobes would invoke tint ramping - // in addition to changing state... so ignore any tint-ramp events which - // don't look like they were meant to be here - static uint8_t active = 0; - uint8_t tint = cfg.channel_mode_args[channel_mode]; - #endif - - // it's possible that a light may need 3H but not 3C, - // so try to detect if 3C is needed - #if NUM_CHANNEL_MODES > 1 - // 3 clicks: next channel mode - if (event == EV_3clicks) { - uint8_t next = channel_mode; - // go to next channel mode until we find one which is enabled - // (and don't do any infinite loops if the user disabled them all) - uint8_t count = 0; - do { - count ++; - next = (next + 1) % NUM_CHANNEL_MODES; - } while ((! channel_mode_enabled(next)) && count < NUM_CHANNEL_MODES); - //} while ((! channel_modes_enabled[next]) && count < NUM_CHANNEL_MODES); - - // undo change if infinite loop detected (redundant?) - //if (NUM_CHANNEL_MODES == count) next = channel_mode; - - // if mode hasn't changed, abort - if (channel_mode == next) - return EVENT_NOT_HANDLED; - - set_channel_mode(next); - - // remember after battery changes - cfg.channel_mode = channel_mode; - save_config(); - return EVENT_HANDLED; - } else - #endif // if NUM_CHANNEL_MODES > 1 - - #ifdef USE_CUSTOM_CHANNEL_3H_MODES - // defer to mode-specific function if defined - if (channel_3H_modes[channel_mode]) { - StatePtr tint_func = channel_3H_modes[channel_mode]; - uint8_t err = tint_func(event, arg); - if (EVENT_HANDLED == err) return EVENT_HANDLED; - // else let the default handler run - } - #endif - #ifdef USE_CHANNEL_MODE_ARGS - #ifndef DONT_USE_DEFAULT_CHANNEL_ARG_MODE - // click, click, hold: change the current channel's arg (like tint) - if (event == EV_click3_hold) { - ///// adjust value from 0 to 255 - // reset at beginning of movement - if (! arg) { - active = 1; // first frame means this is for us - past_edge_counter = 0; // doesn't start until user hits the edge - } - // ignore event if we weren't the ones who handled the first frame - if (! active) return EVENT_NOT_HANDLED; - - #ifdef USE_STEPPED_TINT_RAMPING - if ((tint_ramp_direction > 0 && tint < 255) || - (tint_ramp_direction < 0 && tint > 0)) { - // ramp slower in stepped mode - if (cfg.tint_ramp_style && (arg % HOLD_TIMEOUT != 0)) - return EVENT_HANDLED; - - const uint8_t step_size = (cfg.tint_ramp_style < 2) - ? 1 : 254 / (cfg.tint_ramp_style-1); - tint = nearest_tint_value( - tint + ((int16_t)step_size * tint_ramp_direction) - ); - } - #else // smooth tint ramping only - if ((tint_ramp_direction > 0) && (tint < 255)) { tint ++; } - else - if ((tint_ramp_direction < 0) && (tint > 0)) { tint --; } - #endif // ifdef USE_STEPPED_TINT_RAMPING - - // if tint change stalled, let user know we hit the edge - else if (prev_tint == tint) { - if (past_edge_counter == 0) blip(); - past_edge_counter = 1; - } - prev_tint = tint; - cfg.channel_mode_args[channel_mode] = tint; - set_level(actual_level); - return EVENT_HANDLED; - } - - // click, click, hold, release: reverse direction for next ramp - else if (event == EV_click3_hold_release) { - active = 0; // ignore next hold if it wasn't meant for us - // reverse - tint_ramp_direction = -tint_ramp_direction; - if (0 == tint) tint_ramp_direction = 1; - else if (255 == tint) tint_ramp_direction = -1; - // remember tint after battery change - cfg.channel_mode_args[channel_mode] = tint; - save_config(); - // bug?: for some reason, brightness can seemingly change - // from 1/150 to 2/150 without this next line... not sure why - set_level(actual_level); - return EVENT_HANDLED; - } - #endif // ifndef DONT_USE_DEFAULT_CHANNEL_ARG_MODE - #endif // ifdef USE_CHANNEL_MODE_ARGS - - #if defined(USE_SIMPLE_UI) - // remaining mappings aren't "simple", so stop here - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - - #if NUM_CHANNEL_MODES > 1 - // channel toggle menu on ... 9H? - else if (event == EV_click9_hold) { - push_state(channel_mode_config_state, 0); - return EVENT_HANDLED; - } - #endif - - return EVENT_NOT_HANDLED; -} - - -#if NUM_CHANNEL_MODES > 1 -void channel_mode_config_save(uint8_t step, uint8_t value) { - // 1 menu item per channel mode, to enable or disable that mode - step --; // step is 1-based, channel modes are 0-based - if (value) channel_mode_enable(step); - else channel_mode_disable(step); -} - -uint8_t channel_mode_config_state(Event event, uint16_t arg) { - uint8_t ret; - // make config steps match channel modes - config_color_per_step = true; - // 1 menu item per channel mode, to enable or disable that mode - ret = config_state_base( - event, arg, - NUM_CHANNEL_MODES, - channel_mode_config_save - ); - // no other menu needs this - config_color_per_step = false; - return ret; -} -#endif - - -#if defined(USE_CHANNEL_MODE_ARGS) && defined(USE_STEPPED_TINT_RAMPING) -uint8_t nearest_tint_value(const int16_t target) { - // const symbols for more readable code, will be removed by the compiler - const uint8_t tint_min = 0; - const uint8_t tint_max = 255; - const uint8_t tint_range = tint_max - tint_min; - - // only equal mix of both channels - if (1 == cfg.tint_ramp_style) return (tint_min + tint_max) >> 1; - - if (target < tint_min) return tint_min; - if (target > tint_max) return tint_max; - if (0 == cfg.tint_ramp_style) return target; // smooth ramping - - const uint8_t step_size = tint_range / (cfg.tint_ramp_style-1); - - uint8_t tint_result = tint_min; - for (uint8_t i=0; i<cfg.tint_ramp_style; i++) { - tint_result = tint_min - + (i * (uint16_t)tint_range / (cfg.tint_ramp_style-1)); - int16_t diff = target - tint_result; - if (diff <= (step_size>>1)) return tint_result; - } - return tint_result; -} -#endif - -#ifdef USE_CIRCULAR_TINT_3H -uint8_t circular_tint_3h(Event event, uint16_t arg) { - static int8_t tint_ramp_direction = 1; - // bugfix: click-click-hold from off to strobes would invoke tint ramping - // in addition to changing state... so ignore any tint-ramp events which - // don't look like they were meant to be here - static uint8_t active = 0; - uint8_t tint = cfg.channel_mode_args[channel_mode]; - - // click, click, hold: change the current channel's arg (like tint) - if (event == EV_click3_hold) { - ///// adjust value from 0 to 255 in a circle - // reset at beginning of movement - if (! arg) { - active = 1; // first frame means this is for us - } - // ignore event if we weren't the ones who handled the first frame - if (! active) return EVENT_NOT_HANDLED; - - // smooth tint ramping only - tint += tint_ramp_direction; - - cfg.channel_mode_args[channel_mode] = tint; - set_level(actual_level); - return EVENT_HANDLED; - } - - // click, click, hold, release: reverse direction for next ramp - else if (event == EV_click3_hold_release) { - active = 0; // ignore next hold if it wasn't meant for us - // reverse - tint_ramp_direction = -tint_ramp_direction; - // remember tint after battery change - save_config(); - // bug?: for some reason, brightness can seemingly change - // from 1/150 to 2/150 without this next line... not sure why - set_level(actual_level); - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} -#endif diff --git a/spaghetti-monster/anduril/channel-modes.h b/spaghetti-monster/anduril/channel-modes.h deleted file mode 100644 index b51721d..0000000 --- a/spaghetti-monster/anduril/channel-modes.h +++ /dev/null @@ -1,26 +0,0 @@ -// channel-modes.h: Multi-channel functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// not actually a mode, more of a fallback under other modes -uint8_t channel_mode_state(Event event, uint16_t arg); - -#if NUM_CHANNEL_MODES > 1 -uint8_t channel_mode_config_state(Event event, uint16_t arg); -#endif - -#if defined(USE_CHANNEL_MODE_ARGS) && defined(USE_STEPPED_TINT_RAMPING) -// calculate the nearest tint value which would be valid at the moment -uint8_t nearest_tint_value(const int16_t target); -#endif - -#ifdef USE_CUSTOM_CHANNEL_3H_MODES -StatePtr channel_3H_modes[NUM_CHANNEL_MODES]; -#endif - -#ifdef USE_CIRCULAR_TINT_3H -uint8_t circular_tint_3h(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/anduril/config-default.h b/spaghetti-monster/anduril/config-default.h deleted file mode 100644 index 899bc4a..0000000 --- a/spaghetti-monster/anduril/config-default.h +++ /dev/null @@ -1,207 +0,0 @@ -// config-default.h: Default configuration for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -/* - * This file specifies the default settings for Anduril. - * - * These settings can be overridden per build target, in cfg-*.h files... - * ... but most are not. So changing one here will make it change in - * almost every build target. - * - * Some configurable settings are also in other *.h files. - */ - -/********* User-configurable options *********/ -// low voltage protection (also required for battery check mode) -#define USE_LVP - -// overheat protection -#define USE_THERMAL_REGULATION -#if (ATTINY==85) || (ATTINY==1634) -// sloppy temperature sensor needs bigger error margin -#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this (in C) -#else -// more accurate temperature sensor can regulate higher safely -#define DEFAULT_THERM_CEIL 50 // try not to get hotter than this (in C) -#endif -// Comment out to disable automatic calibration on factory reset -// - If so, be sure to set THERM_CAL_OFFSET to the correct calibration offset -// - Calibration can still be overridden in temperature check mode -// Or uncomment to use the default auto-calibrate on factory reset -// -// To determine THERM_CAL_OFFSET, comment out USE_THERM_AUTOCALIBRATE to -// disable auto-calibration, compile and flash, let flashlight rest at a known -// temperature, then enter temp check mode (do NOT enter calibration mode). -// -// THERM_CAL_OFFSET = known_temperature - temp_check_blinks + THERM_CAL_OFFSET -// -// (include THERM_CAL_OFFSET in sum as it might already be a non-zero number) -#define USE_THERM_AUTOCALIBRATE - -// Include a simplified UI for non-enthusiasts? -#define USE_SIMPLE_UI - - -///// Ramp mode options ///// - -// button timing for turning light on/off: -// B_PRESS_T: activate as soon as button is pressed -// B_RELEASE_T: activate when user lets go of button -// B_TIMEOUT_T: activate when we're sure the user won't double-click -// defaults are release on, timeout off -#define B_TIMING_ON B_RELEASE_T -#define B_TIMING_OFF B_TIMEOUT_T - -// default ramp style: 0 = smooth, 1 = stepped -#define RAMP_STYLE 0 - -// smooth ramp speed: 1, 2, 3, 4, ... for 1X speed, 1/2, 1/3rd, 1/4th, ... -#define USE_RAMP_SPEED_CONFIG - -// after ramping, how long until the direction resets to "up"? -#define AUTO_REVERSE_TIME (TICKS_PER_SECOND * 2 / 3) - -// add runtime option for whether hold-from-off should ramp or stay at moon -#define USE_RAMP_AFTER_MOON_CONFIG - -// short blip when crossing from "click" to "hold" from off -// (helps the user hit moon mode exactly, instead of holding too long -// or too short) -#define MOON_TIMING_HINT // only applies if B_TIMING_ON == B_PRESS_T -// short blips while ramping -#define BLINK_AT_RAMP_MIDDLE -//#define BLINK_AT_RAMP_FLOOR -#define BLINK_AT_RAMP_CEIL -//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode - -// Uncomment for Anduril1 "Ramp 2C" behavior: -// - Ramp 2C goes to turbo (advanced UI) or ceiling (simple UI), like in Anduril1 -// Or comment out to use Anduril2 behavior instead: -// - Ramp 2C goes to ceiling, unless already at ceiling or in simple UI. -// (Advanced UI ceiling 2C goes to turbo) -//#define USE_2C_MAX_TURBO -// Or uncomment to let the user decide which style they want: -#define USE_2C_STYLE_CONFIG -// 0 = no turbo -// 1 = A1 style: Off 2C = ceil, On 2C = turbo -// 2 = A2 style: Off 2C = ceil, On 2C = ceil, Ramped ceil 2C = turbo -// All styles allow momentary turbo in advanced UI -//#define DEFAULT_2C_STYLE 2 // default to Anduril 2 style -//#define DEFAULT_2C_STYLE_SIMPLE 0 // no turbo at all - -// make the ramps configurable by the user -#define USE_RAMP_CONFIG - -// adds a runtime option to switch between automatic memory (default) -// and manual memory (only available if compiled in) -// (manual memory makes 1-click-from-off start at the same level each time) -// (the level can be set explicitly with 10 clicks from on, -// or the user can go back to automatic with 10H) -#define USE_MANUAL_MEMORY -// if enabled, user can use "hybrid memory" -// The light will use automatic or manual memory level, depending on how long -// the light was off. Short off = automatic, long off = manual. -// This also remaps 10C/10H: -// - 10C toggles manual mem on/off at current level. -// - 10H configures the timer value. -#define USE_MANUAL_MEMORY_TIMER - -// enable sunset timer (ramp-down and automatic shutoff) -// timer is available in regular ramp mode and candle mode -#define USE_SUNSET_TIMER - - -///// What to do when power is connected ///// -// factory reset function erases user's runtime configuration in eeprom -#define USE_FACTORY_RESET -//#define USE_SOFT_FACTORY_RESET // only needed on models which can't use hold-button-at-boot - -// dual-switch support (second switch is a tail clicky) -// (currently incompatible with factory reset) -//#define START_AT_MEMORIZED_LEVEL - - -///// extra modes (enable / disable / configure each mode) ///// - -// include a function to blink out the firmware version -#define USE_VERSION_CHECK - -// enable the battery check mode (shows remaining charge) (requires USE_LVP) -#define USE_BATTCHECK_MODE -// battery readout style (pick one) -// TODO: allow VpT and 4-bar simultaneously, -// so one can be in "simple mode" and the other in "advanced mode" -#define BATTCHECK_VpT -//#define BATTCHECK_8bars // FIXME: breaks build -//#define BATTCHECK_4bars // FIXME: breaks build -// allow the user to calibrate the voltage readings? -// (adjust in 0.05V increments from -0.30V to +0.30V) -// (1 = -0.30V, 2 = -0.25V, ... 7 = 0V, ... 13 = +0.30V) -#define USE_VOLTAGE_CORRECTION - -// enable beacon mode -#define USE_BEACON_MODE - -// enable/disable various strobe modes -#define USE_BIKE_FLASHER_MODE -#define USE_PARTY_STROBE_MODE -#define USE_TACTICAL_STROBE_MODE -#define USE_LIGHTNING_MODE -#define USE_CANDLE_MODE - -// boring strobes nobody really likes, but sometimes flashlight companies want -// (these replace the fun strobe group, -// so don't enable them at the same time as any of the above strobes) -//#define USE_POLICE_STROBE_MODE -#define USE_SOS_MODE -//#define USE_SOS_MODE_IN_FF_GROUP // put SOS in the "boring strobes" mode -#define USE_SOS_MODE_IN_BLINKY_GROUP // put SOS in the blinkies mode group - -// enable a mode for locking the light for safe carry -#define USE_LOCKOUT_MODE -// should lockout mode function as a momentary moon mode? -#define USE_MOON_DURING_LOCKOUT_MODE -// add an optional setting to lock the light after being off for a while -#define USE_AUTOLOCK - -// enable momentary mode -#define USE_MOMENTARY_MODE - -// enable tactical mode -#define USE_TACTICAL_MODE - - -// enable a shortcut for +10 in number entry mode -// (click for +1, hold for +10) -#define USE_NUMBER_ENTRY_PLUS10 - -// cut clock speed at very low modes for better efficiency -// (defined here so config files can override it) -#define USE_DYNAMIC_UNDERCLOCKING - -// if the aux LEDs oscillate between "full battery" and "empty battery" -// while in "voltage" mode, enable this to reduce the amplitude of -// those oscillations -#if (ATTINY==1616) || (ATTINY==1634) -#define USE_LOWPASS_WHILE_ASLEEP -#endif - -// if there's tint ramping, allow user to set it smooth or stepped -#define USE_STEPPED_TINT_RAMPING -#define DEFAULT_TINT_RAMP_STYLE 0 // smooth - -// Use "smooth steps" to soften on/off and step changes -// on MCUs with enough room for extra stuff like this -#if (ATTINY==1616) || (ATTINY==1634) -#define USE_SMOOTH_STEPS -#endif -// 0 = none, 1 = smooth, 2+ = undefined -#define DEFAULT_SMOOTH_STEPS_STYLE 1 - -// by default, allow user to set the channel for each strobe-group mode -// (but allow disabling this feature per build) -#define USE_CHANNEL_PER_STROBE - diff --git a/spaghetti-monster/anduril/config-mode.c b/spaghetti-monster/anduril/config-mode.c deleted file mode 100644 index 71b0d69..0000000 --- a/spaghetti-monster/anduril/config-mode.c +++ /dev/null @@ -1,196 +0,0 @@ -// config-mode.c: Config mode base functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "config-mode.h" - -// general helper function for config modes -uint8_t number_entry_state(Event event, uint16_t arg); -// return value from number_entry_state() -volatile uint8_t number_entry_value; - - -#if defined(USE_CONFIG_COLORS) && (NUM_CHANNEL_MODES > 1) -// TODO: promote this to fsm-channels.c ? -void set_chan_if(bool cond, uint8_t chan) { - if ((cond) && (chan != channel_mode)) - set_channel_mode(chan); -} -#endif - -// allow the user to set a new value for a config option -// can be called two ways: -// - with a "click" action: Configures first menu item only. -// - with a "hold" action: Sets user select a menu item and then -// choose a new value for it. User should hold button until light -// blinks N times, to choose menu item N. Then let go, and light -// should give a buzzing prompt to enter a number. Click N times -// at the prompt to set the new value to N. -// after completing this process, config state calls the savefunc callback -// and then returns to caller/parent state -uint8_t config_state_base( - Event event, - uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)(uint8_t step, uint8_t value)) { - - static uint8_t config_step; - #ifdef USE_CONFIG_COLORS - static uint8_t orig_channel; - #endif - if (event == EV_enter_state) { - #if defined(USE_CONFIG_COLORS) && (NUM_CHANNEL_MODES > 1) - orig_channel = channel_mode; - #endif - config_step = 0; - set_level(0); - // if button isn't held, configure first menu item - if (! button_last_state) { - config_step ++; - push_state(number_entry_state, 0); - } - } - - // if initial "hold" event still active - // blink while holding to indicate option number - #define B_CLICK_FLAGS (B_CLICK|B_HOLD|B_PRESS|B_RELEASE|B_TIMEOUT) - #define B_ANY_HOLD (B_CLICK|B_HOLD|B_PRESS) - #define B_ANY_HOLD_RELEASE (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT) - else if ((event & B_CLICK_FLAGS) == B_ANY_HOLD) { - if (config_step <= num_config_steps) { - #if defined(USE_CONFIG_COLORS) && (NUM_CHANNEL_MODES > 1) - uint8_t chan = config_step - 1; - if (chan < NUM_CHANNEL_MODES) - set_chan_if(config_color_per_step, chan); - #endif - if ((TICKS_PER_SECOND/10) == (arg % (TICKS_PER_SECOND*3/2))) { - config_step ++; - // blink when config step advances - if (config_step <= num_config_steps) { - #ifdef CONFIG_BLINK_CHANNEL - set_chan_if(!config_color_per_step, CONFIG_BLINK_CHANNEL); - #endif - set_level(RAMP_SIZE * 3 / 8); - } - } - else { - // stay on at a low level to indicate menu is active - #ifdef CONFIG_WAITING_CHANNEL - set_chan_if(!config_color_per_step, CONFIG_WAITING_CHANNEL); - #endif - set_level(RAMP_SIZE * 1 / 8); - } - } else { - // turn off when end of menu is reached - set_level(0); - } - } - - // button release: activate number entry for one menu item - else if ((event & B_CLICK_FLAGS) == B_ANY_HOLD_RELEASE) { - // ask the user for a number, if they selected a menu item - if (config_step && config_step <= num_config_steps) { - #if defined(USE_CONFIG_COLORS) && (NUM_CHANNEL_MODES > 1) - // put the colors back how they were - set_channel_mode(orig_channel); - #endif - push_state(number_entry_state, 0); - } - // exit after falling out of end of menu - else { - pop_state(); - } - } - - // an option was set (return from number_entry_state) - else if (event == EV_reenter_state) { - // process value with parent's callback - savefunc(config_step, number_entry_value); - // make changes persist in eeprom - save_config(); - pop_state(); - } - - #if defined(USE_CONFIG_COLORS) && (NUM_CHANNEL_MODES > 1) - else if (event == EV_leave_state) { - // put the colors back how they were - set_channel_mode(orig_channel); - } - #endif - - // eat all other events; don't pass any through to parent - return EVENT_HANDLED; -} - -uint8_t number_entry_state(Event event, uint16_t arg) { - static uint8_t entry_step; - - if (event == EV_enter_state) { - number_entry_value = 0; - entry_step = 0; - set_level(0); // initial pause should be dark - } - - // advance through the process: - // 0: wait a moment - // 1: "buzz" while counting clicks - // 2: save and exit - else if (event == EV_tick) { - // wait a moment - if (entry_step == 0) { - if (arg > TICKS_PER_SECOND/2) { - entry_step ++; - empty_event_sequence(); // reset tick counter to 0 - } - } - // buzz while waiting for a number to be entered - else if (entry_step == 1) { - // time out and exit after 3 seconds - if (arg > TICKS_PER_SECOND*3) { - entry_step ++; - set_level(0); - } - // buzz for N seconds after last event - // (flicker every other frame, - // except first frame (so we can see flashes after each click)) - else if (arg) { - #ifdef CONFIG_WAITING_CHANNEL - set_chan_if(1, CONFIG_WAITING_CHANNEL); - #endif - set_level( (RAMP_SIZE/8) - + ((arg&2)<<2) ); - } - } - // all done, save result and return to parent state - else { - pop_state(); - } - return EVENT_HANDLED; - } - - // count clicks: click = +1, hold = +10 - else if ((event == EV_click1_release) - #ifdef USE_NUMBER_ENTRY_PLUS10 - || (event == EV_click1_hold_release) - #endif - ) { - entry_step = 1; // in case user clicked during initial delay - #ifdef USE_NUMBER_ENTRY_PLUS10 - if (event == EV_click1_hold_release) number_entry_value += 10; - else - #endif - number_entry_value ++; // update the result - empty_event_sequence(); // reset FSM's click count - #ifdef CONFIG_BLINK_CHANNEL - set_channel_mode(CONFIG_BLINK_CHANNEL); - #endif - set_level(RAMP_SIZE/2); // flash briefly - return EVENT_HANDLED; - } - - // eat all other events; don't pass any through to parent - return EVENT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/config-mode.h b/spaghetti-monster/anduril/config-mode.h deleted file mode 100644 index d4a7652..0000000 --- a/spaghetti-monster/anduril/config-mode.h +++ /dev/null @@ -1,24 +0,0 @@ -// config-mode.h: Config mode base functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// menus can use 2 colors -#if defined (CONFIG_WAITING_CHANNEL) || defined(CONFIG_BLINK_CHANNEL) -#define USE_CONFIG_COLORS -#endif - -#if NUM_CHANNEL_MODES > 1 -// when true, changes the channel mode for each config step -bool config_color_per_step = false; -#endif - -// config menu -uint8_t config_state_base( - Event event, - uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)(uint8_t step, uint8_t value) - ); - diff --git a/spaghetti-monster/anduril/factory-reset-fsm.h b/spaghetti-monster/anduril/factory-reset-fsm.h deleted file mode 100644 index 3cb0875..0000000 --- a/spaghetti-monster/anduril/factory-reset-fsm.h +++ /dev/null @@ -1,10 +0,0 @@ -// factory-reset-fsm.h: FSM config options to enable factory reset in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_SOFT_FACTORY_RESET -#define USE_REBOOT -#endif - diff --git a/spaghetti-monster/anduril/factory-reset.c b/spaghetti-monster/anduril/factory-reset.c deleted file mode 100644 index f9fb472..0000000 --- a/spaghetti-monster/anduril/factory-reset.c +++ /dev/null @@ -1,73 +0,0 @@ -// factory-reset.c: Factory reset functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "factory-reset.h" - -// allows setting channel mode per animation stage, -// so it can ramp up in red then explode in white (as one example) - -void factory_reset() { - // display a warning for a few seconds before doing the actual reset, - // so the user has time to abort if they want - #define SPLODEY_TIME 2500 - #define SPLODEY_STEPS 64 - #define SPLODEY_TIME_PER_STEP (SPLODEY_TIME/SPLODEY_STEPS) - uint8_t bright; - uint8_t reset = 1; - // wind up to an explosion - #ifdef FACTORY_RESET_WARN_CHANNEL - set_channel_mode(FACTORY_RESET_WARN_CHANNEL); - #endif - for (bright=0; bright<SPLODEY_STEPS; bright++) { - set_level(bright); - nice_delay_ms(SPLODEY_TIME_PER_STEP/2); - set_level(bright>>1); - nice_delay_ms(SPLODEY_TIME_PER_STEP/2); - if (! button_is_pressed()) { - reset = 0; - break; - } - } - // explode, if button pressed long enough - if (reset) { - #if defined(FACTORY_RESET_WARN_CHANNEL) && defined(DEFAULT_CHANNEL_MODE) - // return to default channel before saving - set_channel_mode(DEFAULT_CHANNEL_MODE); - #endif - - // auto-calibrate temperature - // AVR 1-Series has factory calibrated thermal sensor, always remove the offset on reset - #if defined(USE_THERMAL_REGULATION) && defined(AVRXMEGA3) - // this will cancel out the offset - thermal_config_save(1, temperature - cfg.therm_cal_offset); - #elif defined(USE_THERMAL_REGULATION) && defined(USE_THERM_AUTOCALIBRATE) - // assume current temperature is 21 C - thermal_config_save(1, 21); - #endif - - // save all settings to eeprom - // (assuming they're all at default because we haven't loaded them yet) - save_config(); - - // explosion animation - #ifdef FACTORY_RESET_SUCCESS_CHANNEL - set_channel_mode(FACTORY_RESET_SUCCESS_CHANNEL); - #endif - bright = MAX_LEVEL; - for (; bright > 0; bright--) { - set_level(bright); - nice_delay_ms(SPLODEY_TIME_PER_STEP/8); - } - } - // explosion cancelled, fade away - else { - for (; bright > 0; bright--) { - set_level(bright); - nice_delay_ms(SPLODEY_TIME_PER_STEP/3); - } - } -} - diff --git a/spaghetti-monster/anduril/factory-reset.h b/spaghetti-monster/anduril/factory-reset.h deleted file mode 100644 index 63c25cd..0000000 --- a/spaghetti-monster/anduril/factory-reset.h +++ /dev/null @@ -1,8 +0,0 @@ -// factory-reset.h: Factory reset functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -void factory_reset(); - diff --git a/spaghetti-monster/anduril/ff-strobe-modes.c b/spaghetti-monster/anduril/ff-strobe-modes.c deleted file mode 100644 index b7a7303..0000000 --- a/spaghetti-monster/anduril/ff-strobe-modes.c +++ /dev/null @@ -1,62 +0,0 @@ -// ff-strobe-modes.c: Fireflies Flashlights strobe modes for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "ff-strobe-modes.h" - -uint8_t boring_strobe_state(Event event, uint16_t arg) { - // police strobe and SOS, meh - // 'st' reduces ROM size slightly - uint8_t st = boring_strobe_type; - - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - // reset to police strobe for next time - boring_strobe_type = 0; - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: rotate through strobe/flasher modes - else if (event == EV_2clicks) { - boring_strobe_type = (st + 1) % NUM_BORING_STROBES; - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -inline void boring_strobe_state_iter() { - switch(boring_strobe_type) { - #ifdef USE_POLICE_STROBE_MODE - case 0: // police strobe - police_strobe_iter(); - break; - #endif - - #ifdef USE_SOS_MODE_IN_FF_GROUP - default: // SOS - sos_mode_iter(); - break; - #endif - } -} - -#ifdef USE_POLICE_STROBE_MODE -inline void police_strobe_iter() { - // one iteration of main loop() - // flash at 16 Hz then 8 Hz, 8 times each - for (uint8_t del=41; del<100; del+=41) { - for (uint8_t f=0; f<8; f++) { - set_level(STROBE_BRIGHTNESS); - nice_delay_ms(del >> 1); - set_level(0); - nice_delay_ms(del); - } - } -} -#endif - diff --git a/spaghetti-monster/anduril/ff-strobe-modes.h b/spaghetti-monster/anduril/ff-strobe-modes.h deleted file mode 100644 index d7adfec..0000000 --- a/spaghetti-monster/anduril/ff-strobe-modes.h +++ /dev/null @@ -1,15 +0,0 @@ -// ff-strobe-modes.h: Fireflies Flashlights strobe modes for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -uint8_t boring_strobe_state(Event event, uint16_t arg); -inline void boring_strobe_state_iter(); -uint8_t boring_strobe_type = 0; -void sos_blink(uint8_t num, uint8_t dah); -#ifdef USE_POLICE_STROBE_MODE -inline void police_strobe_iter(); -#endif -#define NUM_BORING_STROBES 2 - diff --git a/spaghetti-monster/anduril/hank-cfg.h b/spaghetti-monster/anduril/hank-cfg.h deleted file mode 100644 index 86ac605..0000000 --- a/spaghetti-monster/anduril/hank-cfg.h +++ /dev/null @@ -1,30 +0,0 @@ -// Intl-Outdoor (Hank)'s config options for Anduril -// Copyright (C) 2021-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// config preferences for Hank Wang of Intl-Outdoor (Emisar, Noctigon) - -// RGB aux LEDs should use rainbow cycling mode -// to impress new customers -// (people usually change it to voltage mode later though) -#ifdef RGB_LED_OFF_DEFAULT -#undef RGB_LED_OFF_DEFAULT -#endif -#define RGB_LED_OFF_DEFAULT 0x18 // low, rainbow - -// half a second per color in rainbow mode -//#define RGB_RAINBOW_SPEED 0x03 - -// Allow 3C (or 6C) in Simple UI (toggle smooth or stepped ramping) -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// double click while on goes to full-power turbo, not ramp ceiling -#define DEFAULT_2C_STYLE 1 - -// for consistency with KR4 (not otherwise necessary though) -#define USE_SOFT_FACTORY_RESET - diff --git a/spaghetti-monster/anduril/load-save-config-fsm.h b/spaghetti-monster/anduril/load-save-config-fsm.h deleted file mode 100644 index d189d3a..0000000 --- a/spaghetti-monster/anduril/load-save-config-fsm.h +++ /dev/null @@ -1,139 +0,0 @@ -// load-save-config-fsm.h: FSM config for eeprom configuration in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#define USE_EEPROM -// load into a custom RAM location instead of FSM's default byte array -#define EEPROM_OVERRIDE - -#ifdef USE_SIMPLE_UI -#define NUM_RAMPS 3 -#else -#define NUM_RAMPS 2 -#endif - -// let FSM know this config struct exists -#define USE_CFG - -typedef struct Config { - - ///// ramp vars - uint8_t ramp_style; - #ifdef USE_2C_STYLE_CONFIG - uint8_t ramp_2c_style; - #endif - #ifdef USE_RAMP_CONFIG - uint8_t ramp_floors[NUM_RAMPS]; - uint8_t ramp_ceils [NUM_RAMPS]; - uint8_t ramp_stepss[NUM_RAMPS]; - #endif - #ifdef USE_SIMPLE_UI - uint8_t simple_ui_active; - #ifdef USE_2C_STYLE_CONFIG - uint8_t ramp_2c_style_simple; - #endif - #endif - #ifdef USE_RAMP_AFTER_MOON_CONFIG - uint8_t dont_ramp_after_moon; - #endif - #ifdef USE_MANUAL_MEMORY - uint8_t manual_memory; - #ifdef USE_MANUAL_MEMORY_TIMER - uint8_t manual_memory_timer; - #endif - #endif - - ///// channel modes / color modes - #if NUM_CHANNEL_MODES > 1 - uint8_t channel_mode; - uint16_t channel_modes_enabled; - #ifdef USE_MANUAL_MEMORY - uint8_t manual_memory_channel_mode; - #endif - #ifdef DEFAULT_BLINK_CHANNEL - uint8_t blink_channel; - #endif - #endif - #ifdef USE_CHANNEL_MODE_ARGS - // this is an array, needs a few bytes - uint8_t channel_mode_args[NUM_CHANNEL_MODES]; - #ifdef USE_MANUAL_MEMORY - uint8_t manual_memory_channel_args[NUM_CHANNEL_MODES]; - #endif - #ifdef USE_STEPPED_TINT_RAMPING - uint8_t tint_ramp_style; - #endif - #endif - - ///// Smooth animation between steps, and for on/off - #ifdef USE_SMOOTH_STEPS - uint8_t smooth_steps_style; - #endif - - ///// strobe / blinky mode settings - #ifdef USE_STROBE_STATE - uint8_t strobe_type; - #if (NUM_CHANNEL_MODES > 1) && defined(USE_CHANNEL_PER_STROBE) - uint8_t strobe_channels[NUM_STROBES]; - #endif - #endif - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - uint8_t strobe_delays[2]; - #endif - #ifdef USE_BIKE_FLASHER_MODE - uint8_t bike_flasher_brightness; - #endif - #ifdef USE_BEACON_MODE - uint8_t beacon_seconds; - #endif - - ///// voltage and temperature - #ifdef USE_VOLTAGE_CORRECTION - uint8_t voltage_correction; - #endif - #ifdef USE_THERMAL_REGULATION - uint8_t therm_ceil; - int8_t therm_cal_offset; - #endif - - ///// aux LEDs - #ifdef USE_INDICATOR_LED - uint8_t indicator_led_mode; - #endif - #ifdef USE_AUX_RGB_LEDS - uint8_t rgb_led_off_mode; - uint8_t rgb_led_lockout_mode; - #ifdef USE_POST_OFF_VOLTAGE - uint8_t post_off_voltage; - #endif - #endif - - ///// misc other mode settings - #ifdef USE_AUTOLOCK - uint8_t autolock_time; - #endif - #ifdef USE_TACTICAL_MODE - uint8_t tactical_levels[3]; - #endif - - ///// hardware config / globals menu - #ifdef USE_JUMP_START - uint8_t jump_start_level; - #endif - -} Config; - -// auto-detect how many eeprom bytes -#define EEPROM_BYTES sizeof(Config) - -// declare this so FSM can see it, -// but define its values in a file which loads later -Config cfg; - -#ifdef START_AT_MEMORIZED_LEVEL -#define USE_EEPROM_WL -#define EEPROM_WL_BYTES 1 -#endif - diff --git a/spaghetti-monster/anduril/load-save-config.c b/spaghetti-monster/anduril/load-save-config.c deleted file mode 100644 index aa772e1..0000000 --- a/spaghetti-monster/anduril/load-save-config.c +++ /dev/null @@ -1,33 +0,0 @@ -// load-save-config.c: Load/save/eeprom functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "load-save-config-fsm.h" -#include "load-save-config.h" - -void load_config() { - eeprom = (uint8_t *)&cfg; - - if (! load_eeprom()) return; - - #ifdef START_AT_MEMORIZED_LEVEL - if (load_eeprom_wl()) { - memorized_level = eeprom_wl[0]; - } - #endif -} - -void save_config() { - eeprom = (uint8_t *)&cfg; - save_eeprom(); -} - -#ifdef START_AT_MEMORIZED_LEVEL -void save_config_wl() { - eeprom_wl[0] = memorized_level; - save_eeprom_wl(); -} -#endif - diff --git a/spaghetti-monster/anduril/load-save-config.h b/spaghetti-monster/anduril/load-save-config.h deleted file mode 100644 index 514fcbb..0000000 --- a/spaghetti-monster/anduril/load-save-config.h +++ /dev/null @@ -1,173 +0,0 @@ -// load-save-config.h: Load/save/eeprom functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// remember stuff even after battery was changed -void load_config(); -void save_config(); -#ifdef START_AT_MEMORIZED_LEVEL -void save_config_wl(); -#endif - -// a struct to hold config values -Config cfg = { - - ///// ramp vars - - // smooth vs discrete ramping - .ramp_style = RAMP_STYLE, // 0 = smooth, 1 = discrete - #ifdef USE_2C_STYLE_CONFIG - // 1 = A1 style, 2 = A2 style - .ramp_2c_style = DEFAULT_2C_STYLE, - #endif - - // settings for each ramp (smooth, stepped, simple UI) - #ifdef USE_RAMP_CONFIG - .ramp_floors = { - RAMP_SMOOTH_FLOOR, - RAMP_DISCRETE_FLOOR, - #ifdef USE_SIMPLE_UI - SIMPLE_UI_FLOOR, - #endif - }, - .ramp_ceils = { - RAMP_SMOOTH_CEIL, - RAMP_DISCRETE_CEIL, - #ifdef USE_SIMPLE_UI - SIMPLE_UI_CEIL, - #endif - }, - .ramp_stepss = { - DEFAULT_RAMP_SPEED, - RAMP_DISCRETE_STEPS, - #ifdef USE_SIMPLE_UI - SIMPLE_UI_STEPS, - #endif - }, - #endif - - #ifdef USE_SIMPLE_UI - // whether to enable the simplified interface or not - .simple_ui_active = SIMPLE_UI_ACTIVE, - #ifdef USE_2C_STYLE_CONFIG - // 0 = no turbo, 1 = A1 style, 2 = A2 style - .ramp_2c_style_simple = DEFAULT_2C_STYLE_SIMPLE, - #endif - #endif - - #ifdef USE_RAMP_AFTER_MOON_CONFIG - .dont_ramp_after_moon = DEFAULT_DONT_RAMP_AFTER_MOON, - #endif - - #ifdef USE_MANUAL_MEMORY - .manual_memory = DEFAULT_MANUAL_MEMORY, - #ifdef USE_MANUAL_MEMORY_TIMER - .manual_memory_timer = DEFAULT_MANUAL_MEMORY_TIMER, - #endif - #endif - - ///// channel modes / color modes - - #if NUM_CHANNEL_MODES > 1 - // current multi-channel mode - .channel_mode = DEFAULT_CHANNEL_MODE, - // user can take unwanted modes out of the rotation (bitmask) - .channel_modes_enabled = CHANNEL_MODES_ENABLED, - #ifdef USE_MANUAL_MEMORY - // reset w/ manual memory - .manual_memory_channel_mode = DEFAULT_CHANNEL_MODE, - #endif - #ifdef DEFAULT_BLINK_CHANNEL - // blink numbers in a specific channel (user configurable) - .blink_channel = DEFAULT_BLINK_CHANNEL, - #endif - #endif - #ifdef USE_CHANNEL_MODE_ARGS - // one byte of extra data per channel mode, like for tint value - .channel_mode_args = { CHANNEL_MODE_ARGS }, - #ifdef USE_MANUAL_MEMORY - // remember and reset 1 extra parameter per channel mode (like tint) - .manual_memory_channel_args = { CHANNEL_MODE_ARGS }, - #endif - #ifdef USE_STEPPED_TINT_RAMPING - .tint_ramp_style = DEFAULT_TINT_RAMP_STYLE, - #endif - #endif - - ///// Smooth animation between steps, and for on/off - #ifdef USE_SMOOTH_STEPS - .smooth_steps_style = DEFAULT_SMOOTH_STEPS_STYLE, - #endif - - ///// strobe / blinky mode settings - - #ifdef USE_STROBE_STATE - .strobe_type = DEFAULT_STROBE, - #if (NUM_CHANNEL_MODES > 1) && defined(USE_CHANNEL_PER_STROBE) - // channel mode saved per strobe-group mode - #ifdef DEFAULT_STROBE_CHANNELS - .strobe_channels = { DEFAULT_STROBE_CHANNELS }, - #endif - #endif - #endif - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - // party / tactical strobe timing - // party strobe 24 Hz, tactical strobe 10 Hz - .strobe_delays = { 41, 67 }, - #endif - #ifdef USE_BIKE_FLASHER_MODE - .bike_flasher_brightness = MAX_1x7135, - #endif - #ifdef USE_BEACON_MODE - // beacon timing - .beacon_seconds = 2, - #endif - - ///// voltage and temperature - - #ifdef USE_VOLTAGE_CORRECTION - // same 0.05V units as fudge factor, - // but 7 is neutral, and the expected range is from 1 to 13 - .voltage_correction = 7, - #endif - #ifdef USE_THERMAL_REGULATION - .therm_ceil = DEFAULT_THERM_CEIL, - .therm_cal_offset = 0, - #endif - - ///// aux LEDs - - #ifdef USE_INDICATOR_LED - // bits 2-3 control lockout mode - // bits 0-1 control "off" mode - // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled) - .indicator_led_mode = INDICATOR_LED_DEFAULT_MODE, - #endif - #ifdef USE_AUX_RGB_LEDS - .rgb_led_off_mode = RGB_LED_OFF_DEFAULT, - .rgb_led_lockout_mode = RGB_LED_LOCKOUT_DEFAULT, - #ifdef USE_POST_OFF_VOLTAGE - // display voltage readout for a while after turning off? - .post_off_voltage = DEFAULT_POST_OFF_VOLTAGE_SECONDS, - #endif - #endif - - ///// misc other mode settings - - #ifdef USE_AUTOLOCK - .autolock_time = DEFAULT_AUTOLOCK_TIME, - #endif - #ifdef USE_TACTICAL_MODE - .tactical_levels = { TACTICAL_LEVELS }, - #endif - - ///// hardware config / globals menu - - #ifdef USE_JUMP_START - .jump_start_level = DEFAULT_JUMP_START_LEVEL, - #endif - -}; - diff --git a/spaghetti-monster/anduril/lockout-mode-fsm.h b/spaghetti-monster/anduril/lockout-mode-fsm.h deleted file mode 100644 index ede251c..0000000 --- a/spaghetti-monster/anduril/lockout-mode-fsm.h +++ /dev/null @@ -1,11 +0,0 @@ -// lockout-mode-fsm.h: FSM config for lockout mode in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// autolock function requires the ability to measure time while "off" -#ifdef USE_AUTOLOCK -#define TICK_DURING_STANDBY -#endif - diff --git a/spaghetti-monster/anduril/lockout-mode.c b/spaghetti-monster/anduril/lockout-mode.c deleted file mode 100644 index 422d081..0000000 --- a/spaghetti-monster/anduril/lockout-mode.c +++ /dev/null @@ -1,219 +0,0 @@ -// lockout-mode.c: Lockout mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "lockout-mode.h" - -uint8_t lockout_state(Event event, uint16_t arg) { - #ifdef USE_MOON_DURING_LOCKOUT_MODE - // momentary(ish) moon mode during lockout - // button is being held - #ifdef USE_AUX_RGB_LEDS - // don't turn on during RGB aux LED configuration - if (event == EV_click7_hold) { set_level(0); } else - #endif - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - // hold: lowest floor - // click, hold: highest floor (or manual mem level) - uint8_t lvl = cfg.ramp_floors[0]; - if (1 == (event & 0x0f)) { // first click - if (cfg.ramp_floors[1] < lvl) lvl = cfg.ramp_floors[1]; - } else { // 2nd click or later - if (cfg.ramp_floors[1] > lvl) lvl = cfg.ramp_floors[1]; - #ifdef USE_MANUAL_MEMORY - if (cfg.manual_memory) lvl = cfg.manual_memory; - #endif - } - set_level(lvl); - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - set_level(0); - } - #endif // ifdef USE_MOON_DURING_LOCKOUT_MODE - - // regular event handling - // conserve power while locked out - // (allow staying awake long enough to exit, but otherwise - // be persistent about going back to sleep every few seconds - // even if the user keeps pressing the button) - if (event == EV_enter_state) { - ticks_since_on = 0; - #ifdef USE_INDICATOR_LED - // redundant, sleep tick does the same thing - // indicator_led_update(cfg.indicator_led_mode >> 2, 0); - #elif defined(USE_AUX_RGB_LEDS) - rgb_led_update(cfg.rgb_led_lockout_mode, 0); - #endif - } - - else if (event == EV_tick) { - if (arg > HOLD_TIMEOUT) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - // redundant, sleep tick does the same thing - //indicator_led_update(cfg.indicator_led_mode >> 2, arg); - #elif defined(USE_AUX_RGB_LEDS) - rgb_led_update(cfg.rgb_led_lockout_mode, arg); - #endif - } - return EVENT_HANDLED; - } - - #if defined(TICK_DURING_STANDBY) && (defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS)) - else if (event == EV_sleep_tick) { - if (ticks_since_on < 255) ticks_since_on ++; - #ifdef USE_MANUAL_MEMORY_TIMER - // reset to manual memory level when timer expires - if (cfg.manual_memory && - (arg >= (cfg.manual_memory_timer * SLEEP_TICKS_PER_MINUTE))) { - manual_memory_restore(); - } - #endif - #if defined(USE_INDICATOR_LED) - indicator_led_update(cfg.indicator_led_mode >> 2, arg); - #elif defined(USE_AUX_RGB_LEDS) - rgb_led_update(cfg.rgb_led_lockout_mode, arg); - #endif - return EVENT_HANDLED; - } - #endif - - // 3 clicks: exit and turn off - else if (event == EV_3clicks) { - blink_once(); - set_state(off_state, 0); - return EVENT_HANDLED; - } - - // 4 clicks: exit and turn on - else if (event == EV_4clicks) { - #if defined(USE_MANUAL_MEMORY) && !defined(USE_MANUAL_MEMORY_TIMER) - // this clause probably isn't used by any configs any more - // but is included just in case someone configures it this way - if (cfg.manual_memory) - set_state(steady_state, cfg.manual_memory); - else - #endif - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - - // 4 clicks, but hold last: exit and start at floor - else if (event == EV_click4_hold) { - //blink_once(); - blip(); - // reset button sequence to avoid activating anything in ramp mode - current_event = 0; - // ... and back to ramp mode - set_state(steady_state, 1); - return EVENT_HANDLED; - } - - // 5 clicks: exit and turn on at ceiling level - else if (event == EV_5clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - - #if NUM_CHANNEL_MODES > 1 - // 3H: next channel mode - else if (event == EV_click3_hold) { - if (0 == (arg % TICKS_PER_SECOND)) { - // pretend the user clicked 3 times to change channels - return channel_mode_state(EV_3clicks, 0); - } - } - #endif - - ////////// Every action below here is blocked in the (non-Extended) Simple UI ////////// - - #if defined(USE_SIMPLE_UI) && !defined(USE_EXTENDED_SIMPLE_UI) - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif // if simple UI but not extended simple UI - - #if defined(USE_INDICATOR_LED) - // 7 clicks: rotate through indicator LED modes (lockout mode) - else if (event == EV_7clicks) { - #if defined(USE_INDICATOR_LED) - uint8_t mode = cfg.indicator_led_mode >> 2; - #ifdef TICK_DURING_STANDBY - mode = (mode + 1) & 3; - #else - mode = (mode + 1) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - cfg.indicator_led_mode = (mode << 2) + (cfg.indicator_led_mode & 0x03); - // redundant, sleep tick does the same thing - //indicator_led_update(cfg.indicator_led_mode >> 2, arg); - #elif defined(USE_AUX_RGB_LEDS) - #endif - save_config(); - return EVENT_HANDLED; - } - #elif defined(USE_AUX_RGB_LEDS) - // 7 clicks: change RGB aux LED pattern - else if (event == EV_7clicks) { - uint8_t mode = (cfg.rgb_led_lockout_mode >> 4) + 1; - mode = mode % RGB_LED_NUM_PATTERNS; - cfg.rgb_led_lockout_mode = (mode << 4) | (cfg.rgb_led_lockout_mode & 0x0f); - rgb_led_update(cfg.rgb_led_lockout_mode, 0); - save_config(); - blink_once(); - return EVENT_HANDLED; - } - // 7H: change RGB aux LED color - else if (event == EV_click7_hold) { - setting_rgb_mode_now = 1; - if (0 == (arg & 0x3f)) { - uint8_t mode = (cfg.rgb_led_lockout_mode & 0x0f) + 1; - mode = mode % RGB_LED_NUM_COLORS; - cfg.rgb_led_lockout_mode = mode | (cfg.rgb_led_lockout_mode & 0xf0); - //save_config(); - } - rgb_led_update(cfg.rgb_led_lockout_mode, arg); - return EVENT_HANDLED; - } - // 7H, release: save new color - else if (event == EV_click7_hold_release) { - setting_rgb_mode_now = 0; - save_config(); - return EVENT_HANDLED; - } - #endif - - #if defined(USE_EXTENDED_SIMPLE_UI) && defined(USE_SIMPLE_UI) - ////////// Every action below here is blocked in the Extended Simple UI ////////// - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif // if extended simple UI - - #ifdef USE_AUTOLOCK - // 10H: configure the autolock option - else if (event == EV_click10_hold) { - push_state(autolock_config_state, 0); - return EVENT_HANDLED; - } - #endif - - return EVENT_NOT_HANDLED; -} - -#ifdef USE_AUTOLOCK -// set the auto-lock timer to N minutes, where N is the number of clicks -void autolock_config_save(uint8_t step, uint8_t value) { - cfg.autolock_time = value; -} - -uint8_t autolock_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, 1, autolock_config_save); -} -#endif // #ifdef USE_AUTOLOCK - diff --git a/spaghetti-monster/anduril/lockout-mode.h b/spaghetti-monster/anduril/lockout-mode.h deleted file mode 100644 index c2703a0..0000000 --- a/spaghetti-monster/anduril/lockout-mode.h +++ /dev/null @@ -1,16 +0,0 @@ -// lockout-mode.h: Lockout mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// soft lockout -uint8_t lockout_state(Event event, uint16_t arg); - -#ifdef USE_AUTOLOCK -#ifndef DEFAULT_AUTOLOCK_TIME -#define DEFAULT_AUTOLOCK_TIME 0 // autolock time in minutes, 0 = disabled -#endif -uint8_t autolock_config_state(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/anduril/misc.c b/spaghetti-monster/anduril/misc.c deleted file mode 100644 index 1b92d6f..0000000 --- a/spaghetti-monster/anduril/misc.c +++ /dev/null @@ -1,42 +0,0 @@ -// misc.c: Misc extra functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "misc.h" - -/* no longer used -void blink_confirm(uint8_t num) { - uint8_t brightness = actual_level; - uint8_t bump = actual_level + BLINK_BRIGHTNESS; - if (bump > MAX_LEVEL) bump = 0; - for (; num>0; num--) { - set_level(bump); - delay_4ms(10/4); - set_level(brightness); - if (num > 1) { delay_4ms(100/4); } - } -} -*/ - -// make a short, visible pulse -// (either brighter or darker, depending on current brightness) -void blink_once() { - uint8_t brightness = actual_level; - uint8_t bump = brightness + BLINK_BRIGHTNESS; - if (bump > MAX_LEVEL) bump = 0; - - set_level(bump); - delay_4ms(BLINK_ONCE_TIME/4); - set_level(brightness); -} - -// Just go dark for a moment to indicate to user that something happened -void blip() { - uint8_t temp = actual_level; - set_level(0); - delay_4ms(3); - set_level(temp); -} - diff --git a/spaghetti-monster/anduril/misc.h b/spaghetti-monster/anduril/misc.h deleted file mode 100644 index 0f2992a..0000000 --- a/spaghetti-monster/anduril/misc.h +++ /dev/null @@ -1,10 +0,0 @@ -// misc.h: Misc extra functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -//void blink_confirm(uint8_t num); // no longer used -void blink_once(); -void blip(); - diff --git a/spaghetti-monster/anduril/models.py b/spaghetti-monster/anduril/models.py deleted file mode 100755 index 1985352..0000000 --- a/spaghetti-monster/anduril/models.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -import os -import re - -def main(args): - """models.py: scan build targets to generate the MODELS file - """ - - models = [] - - # load all cfg-*.h files - paths = os.listdir('.') - for p in paths: - if p.startswith('cfg-') and p.endswith('.h'): - m = load_cfg(p) - models.append(m) - - # sort by model number - foo = [(m.num, m.name, m) for m in models] - foo.sort() - models = [x[-1] for x in foo] - - fmt = '%s\t%-30s\t%s' - print(fmt % ('Model', 'Name', 'MCU')) - print(fmt % ('-----', '----', '---')) - for m in models: - print(fmt % (m.num, m.name, m.attiny)) - - print('\nDuplicates:') - for i, m in enumerate(models): - for m2 in models[i+1:]: - #if (m.num == m2.num) and (m is not m2): - if m.num == m2.num: - print('%s\t%s, %s' % (m.num, m.name, m2.name)) - - print('\nMissing:') - for m in models: - if not m.num: - print(m.name) - - -class Empty: - pass - - -def load_cfg(path): - m = Empty() - m.name, m.num, m.attiny = '', '', 'attiny85' - - m.name = path.replace('cfg-', '').replace('.h', '') - - num_pat = re.compile(r'#define\s+MODEL_NUMBER\s+"(\d+)"') - mcu_pat = re.compile(r'ATTINY:\s+(\d+)') - # TODO? use C preprocessor to generate more complete file to scan - with open(path) as fp: - for line in fp: - found = num_pat.search(line) - if found: - m.num = found.group(1) - found = mcu_pat.search(line) - if found: - m.attiny = 'attiny' + found.group(1) - - return m - - -if __name__ == "__main__": - import sys - main(sys.argv[1:]) - diff --git a/spaghetti-monster/anduril/momentary-mode.c b/spaghetti-monster/anduril/momentary-mode.c deleted file mode 100644 index a765142..0000000 --- a/spaghetti-monster/anduril/momentary-mode.c +++ /dev/null @@ -1,67 +0,0 @@ -// momentary-mode.c: Momentary mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "momentary-mode.h" - -uint8_t momentary_state(Event event, uint16_t arg) { - // init strobe mode, if relevant - #ifdef USE_STROBE_STATE - if ((event == EV_enter_state) && (momentary_mode != 0)) { - strobe_state(event, arg); - } - #endif - - // light up when the button is pressed; go dark otherwise - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - momentary_active = 1; - // 0 = ramping, 1 = strobes - if (momentary_mode == 0) { - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - momentary_active = 0; - set_level(0); - //go_to_standby = 1; // sleep while light is off - return EVENT_HANDLED; - } - - // Sleep, dammit! (but wait a few seconds first) - // (because standby mode uses such little power that it can interfere - // with exiting via tailcap loosen+tighten unless you leave power - // disconnected for several seconds, so we want to be awake when that - // happens to speed up the process) - else if (event == EV_tick) { - #ifdef USE_STROBE_STATE - if (momentary_active) { - // 0 = ramping, non-zero = strobes - if (momentary_mode != 0) { - return strobe_state(event, arg); - } - } - else { - #endif - if (arg > TICKS_PER_SECOND*5) { // sleep after 5 seconds - go_to_standby = 1; // sleep while light is off - // turn off lighted button - #ifdef USE_INDICATOR_LED - indicator_led(0); - #elif defined(USE_AUX_RGB_LEDS) - rgb_led_update(0, 0); - #endif - } - #ifdef USE_STROBE_STATE - } - #endif - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/momentary-mode.h b/spaghetti-monster/anduril/momentary-mode.h deleted file mode 100644 index d774801..0000000 --- a/spaghetti-monster/anduril/momentary-mode.h +++ /dev/null @@ -1,11 +0,0 @@ -// momentary-mode.h: Momentary mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// momentary / signalling mode -uint8_t momentary_state(Event event, uint16_t arg); -uint8_t momentary_mode = 0; // 0 = ramping, 1 = strobe -uint8_t momentary_active = 0; // boolean, true if active *right now* - diff --git a/spaghetti-monster/anduril/off-mode.c b/spaghetti-monster/anduril/off-mode.c deleted file mode 100644 index 0a381b7..0000000 --- a/spaghetti-monster/anduril/off-mode.c +++ /dev/null @@ -1,384 +0,0 @@ -// off-mode.c: "Off" mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "off-mode.h" - -#ifdef USE_SUNSET_TIMER -#include "sunset-timer.h" -#endif - -// set level smooth maybe -void off_state_set_level(uint8_t level); - - -uint8_t off_state(Event event, uint16_t arg) { - - // turn emitter off when entering state - if (event == EV_enter_state) { - // turn off - off_state_set_level(0); - #ifdef USE_SMOOTH_STEPS - // don't go to sleep while animating - arg |= smooth_steps_in_progress; - #endif - ticks_since_on = 0; - #if NUM_CHANNEL_MODES > 1 - // reset to ramp mode's channel when light turns off - channel_mode = cfg.channel_mode; - #endif - #ifdef USE_INDICATOR_LED - // redundant, sleep tick does the same thing - //indicator_led_update(cfg.indicator_led_mode & 0x03, 0); - #elif defined(USE_AUX_RGB_LEDS) - // redundant, sleep tick does the same thing - //rgb_led_update(cfg.rgb_led_off_mode, 0); - #endif - #ifdef USE_SUNSET_TIMER - sunset_timer = 0; // needs a reset in case previous timer was aborted - #endif - // sleep while off (lower power use) - // (unless delay requested; give the ADC some time to catch up) - if (! arg) { go_to_standby = 1; } - return EVENT_HANDLED; - } - - // go back to sleep eventually if we got bumped but didn't leave "off" state - else if (event == EV_tick) { - if (arg > HOLD_TIMEOUT - #ifdef USE_SMOOTH_STEPS - && (! smooth_steps_in_progress) - #endif - ) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - // redundant, sleep tick does the same thing - //indicator_led_update(cfg.indicator_led_mode & 0x03, arg); - #elif defined(USE_AUX_RGB_LEDS) - // redundant, sleep tick does the same thing - //rgb_led_update(cfg.rgb_led_off_mode, arg); - #endif - } - return EVENT_HANDLED; - } - - #if defined(TICK_DURING_STANDBY) - // blink the indicator LED, maybe - else if (event == EV_sleep_tick) { - if (ticks_since_on < 255) ticks_since_on ++; - #ifdef USE_MANUAL_MEMORY_TIMER - // reset to manual memory level when timer expires - if (cfg.manual_memory && - (arg >= (cfg.manual_memory_timer * SLEEP_TICKS_PER_MINUTE))) { - manual_memory_restore(); - } - #endif - #ifdef USE_INDICATOR_LED - indicator_led_update(cfg.indicator_led_mode & 0x03, arg); - #elif defined(USE_AUX_RGB_LEDS) - rgb_led_update(cfg.rgb_led_off_mode, arg); - #endif - - #ifdef USE_AUTOLOCK - // lock the light after being off for N minutes - uint16_t ticks = cfg.autolock_time * SLEEP_TICKS_PER_MINUTE; - if ((cfg.autolock_time > 0) && (arg > ticks)) { - set_state(lockout_state, 0); - } - #endif // ifdef USE_AUTOLOCK - return EVENT_HANDLED; - } - #endif - - #if (B_TIMING_ON == B_PRESS_T) - // hold (initially): go to lowest level (floor), but allow abort for regular click - else if (event == EV_click1_press) { - off_state_set_level(nearest_level(1)); - return EVENT_HANDLED; - } - #endif // B_TIMING_ON == B_PRESS_T - - // hold: go to lowest level - else if (event == EV_click1_hold) { - #if (B_TIMING_ON == B_PRESS_T) - #ifdef MOON_TIMING_HINT - if (arg == 0) { - // let the user know they can let go now to stay at moon - blip(); - } else - #endif - #else // B_RELEASE_T or B_TIMEOUT_T - off_state_set_level(nearest_level(1)); - #endif - #ifdef USE_RAMP_AFTER_MOON_CONFIG - if (cfg.dont_ramp_after_moon) { - return EVENT_HANDLED; - } - #endif - // don't start ramping immediately; - // give the user time to release at moon level - //if (arg >= HOLD_TIMEOUT) { // smaller - if (arg >= (!cfg.ramp_style) * HOLD_TIMEOUT) { // more consistent - set_state(steady_state, 1); - } - return EVENT_HANDLED; - } - - // hold, release quickly: go to lowest level (floor) - else if (event == EV_click1_hold_release) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - - #if (B_TIMING_ON != B_TIMEOUT_T) - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - #if defined(USE_MANUAL_MEMORY) && !defined(USE_MANUAL_MEMORY_TIMER) - // this clause probably isn't used by any configs any more - // but is included just in case someone configures it this way - if (cfg.manual_memory) { - manual_memory_restore(); - } - #endif - off_state_set_level(nearest_level(memorized_level)); - return EVENT_HANDLED; - } - #endif // if (B_TIMING_ON != B_TIMEOUT_T) - - // 1 click: regular mode - else if (event == EV_1click) { - #if (B_TIMING_ON != B_TIMEOUT_T) - set_state(steady_state, memorized_level); - #else - // FIXME: B_TIMEOUT_T breaks manual_memory and manual_memory_timer - // (need to duplicate manual mem logic here, probably) - set_state(steady_state, memorized_level); - #endif - return EVENT_HANDLED; - } - - // click, hold: momentary at ceiling or turbo - else if (event == EV_click2_hold) { - ticks_since_on = 0; // momentary turbo is definitely "on" - uint8_t turbo_level; // how bright is "turbo"? - - #if defined(USE_2C_STYLE_CONFIG) // user can choose 2C behavior - uint8_t style_2c = cfg.ramp_2c_style; - #ifdef USE_SIMPLE_UI - // simple UI has its own turbo config - if (cfg.simple_ui_active) style_2c = cfg.ramp_2c_style_simple; - #endif - // 0 = ceiling - // 1+ = full power - if (0 == style_2c) turbo_level = nearest_level(MAX_LEVEL); - else turbo_level = MAX_LEVEL; - #else - // simple UI: ceiling - // full UI: full power - #ifdef USE_SIMPLE_UI - if (cfg.simple_ui_active) turbo_level = nearest_level(MAX_LEVEL); - else - #endif - turbo_level = MAX_LEVEL; - #endif - - off_state_set_level(turbo_level); - return EVENT_HANDLED; - } - else if (event == EV_click2_hold_release) { - off_state_set_level(0); - return EVENT_HANDLED; - } - - // 2 clicks: highest mode (ceiling) - else if (event == EV_2clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - - // 3 clicks (initial press): off, to prep for later events - else if (event == EV_click3_press) { - #ifdef USE_SMOOTH_STEPS - // immediately cancel any animations in progress - smooth_steps_in_progress = 0; - #endif - off_state_set_level(0); - return EVENT_HANDLED; - } - - #ifdef USE_BATTCHECK - // 3 clicks: battcheck mode / blinky mode group 1 - else if (event == EV_3clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_LOCKOUT_MODE - // 4 clicks: soft lockout - else if (event == EV_4clicks) { - blink_once(); - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - #endif - - #if defined(USE_FACTORY_RESET) && defined(USE_SOFT_FACTORY_RESET) - // 13 clicks and hold the last click: invoke factory reset (reboot) - else if (event == EV_click13_hold) { - reboot(); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_VERSION_CHECK - // 15+ clicks: show the version number - else if (event == EV_15clicks) { - set_state(version_check_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_SIMPLE_UI - // 10 clicks, but hold last click: turn simple UI off (or configure it) - else if ((event == EV_click10_hold) && (!arg)) { - if (cfg.simple_ui_active) { // turn off simple UI - blink_once(); - cfg.simple_ui_active = 0; - save_config(); - } - else { // configure simple UI ramp - push_state(simple_ui_config_state, 0); - } - return EVENT_HANDLED; - } - - ////////// Every action below here is blocked in the (non-Extended) Simple UI ////////// - - #ifndef USE_EXTENDED_SIMPLE_UI - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif // ifndef USE_EXTENDED_SIMPLE_UI - #endif // ifdef USE_SIMPLE_UI - - // click, click, long-click: strobe mode - #ifdef USE_STROBE_STATE - else if (event == EV_click3_hold) { - set_state(strobe_state, 0); - return EVENT_HANDLED; - } - #elif defined(USE_BORING_STROBE_STATE) - else if (event == EV_click3_hold) { - set_state(boring_strobe_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_INDICATOR_LED - // 7 clicks: change indicator LED mode - else if (event == EV_7clicks) { - uint8_t mode = (cfg.indicator_led_mode & 3) + 1; - #ifdef TICK_DURING_STANDBY - mode = mode & 3; - #else - mode = mode % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - cfg.indicator_led_mode = (cfg.indicator_led_mode & 0b11111100) | mode; - // redundant, sleep tick does the same thing - //indicator_led_update(cfg.indicator_led_mode & 0x03, arg); - save_config(); - return EVENT_HANDLED; - } - #elif defined(USE_AUX_RGB_LEDS) - // 7 clicks: change RGB aux LED pattern - else if (event == EV_7clicks) { - uint8_t mode = (cfg.rgb_led_off_mode >> 4) + 1; - mode = mode % RGB_LED_NUM_PATTERNS; - cfg.rgb_led_off_mode = (mode << 4) | (cfg.rgb_led_off_mode & 0x0f); - rgb_led_update(cfg.rgb_led_off_mode, 0); - save_config(); - blink_once(); - return EVENT_HANDLED; - } - // 7 clicks (hold last): change RGB aux LED color - else if (event == EV_click7_hold) { - setting_rgb_mode_now = 1; - if (0 == (arg & 0x3f)) { - uint8_t mode = (cfg.rgb_led_off_mode & 0x0f) + 1; - mode = mode % RGB_LED_NUM_COLORS; - cfg.rgb_led_off_mode = mode | (cfg.rgb_led_off_mode & 0xf0); - //save_config(); - } - rgb_led_update(cfg.rgb_led_off_mode, arg); - return EVENT_HANDLED; - } - else if (event == EV_click7_hold_release) { - setting_rgb_mode_now = 0; - save_config(); - return EVENT_HANDLED; - } - #endif // end 7 clicks - - ////////// Every action below here is blocked in the Extended Simple UI ////////// - - #ifdef USE_SIMPLE_UI - #ifdef USE_EXTENDED_SIMPLE_UI - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif // ifdef USE_EXTENDED_SIMPLE_UI - - // 10 clicks: enable simple UI - else if (event == EV_10clicks) { - blink_once(); - cfg.simple_ui_active = 1; - save_config(); - return EVENT_HANDLED; - } - #endif // ifdef USE_SIMPLE_UI - - #ifdef USE_MOMENTARY_MODE - // 5 clicks: momentary mode - else if (event == EV_5clicks) { - blink_once(); - set_state(momentary_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_TACTICAL_MODE - // 6 clicks: tactical mode - else if (event == EV_6clicks) { - blink_once(); - set_state(tactical_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_GLOBALS_CONFIG - // 9 clicks, but hold last click: configure misc global settings - else if ((event == EV_click9_hold) && (!arg)) { - push_state(globals_config_state, 0); - return EVENT_HANDLED; - } - #endif - - return EVENT_NOT_HANDLED; -} - - -void off_state_set_level(uint8_t level) { - // this pattern gets used a few times, so reduce duplication - #ifdef USE_SMOOTH_STEPS - if (cfg.smooth_steps_style) set_level_smooth(level, 8); - else - #endif - set_level(level); -} - diff --git a/spaghetti-monster/anduril/off-mode.h b/spaghetti-monster/anduril/off-mode.h deleted file mode 100644 index d07fff1..0000000 --- a/spaghetti-monster/anduril/off-mode.h +++ /dev/null @@ -1,12 +0,0 @@ -// off-mode.h: "Off" mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// was the light in an "on" mode within the past second or so? -uint8_t ticks_since_on = 0; - -// when the light is "off" or in standby -uint8_t off_state(Event event, uint16_t arg); - diff --git a/spaghetti-monster/anduril/ramp-mode-fsm.h b/spaghetti-monster/anduril/ramp-mode-fsm.h deleted file mode 100644 index edfd6db..0000000 --- a/spaghetti-monster/anduril/ramp-mode-fsm.h +++ /dev/null @@ -1,38 +0,0 @@ -// ramp-mode-fsm.h: FSM config for ramping functions in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// enable FSM's ramping features -#define USE_RAMPING - -// do smooth adjustments when compensating for temperature -#ifdef USE_THERMAL_REGULATION -#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments -#endif - -// brightness to use when no memory is set -// FIXME: this is only here to stop an error in fsm-ramping.c, -// which should be fixed by using a different symbol instead -// (like BUTTON_LED_BRIGHT_LEVEL or RAMP_HALFWAY_LEVEL or something) -#ifndef DEFAULT_LEVEL -#define DEFAULT_LEVEL MAX_1x7135 -#endif - -// requires the ability to measure time while "off" -#ifdef USE_MANUAL_MEMORY_TIMER -#define TICK_DURING_STANDBY -#endif - -// ensure the jump start feature gets compiled in if needed -#ifdef DEFAULT_JUMP_START_LEVEL -#define USE_JUMP_START -#endif - -// include an extra config mode for random stuff which doesn't fit elsewhere -#if defined(USE_JUMP_START) || \ - (defined(USE_CHANNEL_MODE_ARGS) && defined(USE_STEPPED_TINT_RAMPING)) -#define USE_GLOBALS_CONFIG -#endif - diff --git a/spaghetti-monster/anduril/ramp-mode.c b/spaghetti-monster/anduril/ramp-mode.c deleted file mode 100644 index 4611b4f..0000000 --- a/spaghetti-monster/anduril/ramp-mode.c +++ /dev/null @@ -1,741 +0,0 @@ -// ramp-mode.c: Ramping functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "ramp-mode.h" - -#ifdef USE_SUNSET_TIMER -#include "sunset-timer.h" -#endif - -#ifdef USE_SMOOTH_STEPS -#include "smooth-steps.h" -#endif - - -uint8_t steady_state(Event event, uint16_t arg) { - static int8_t ramp_direction = 1; - #if (B_TIMING_OFF == B_RELEASE_T) - // if the user double clicks, we need to abort turning off, - // and this stores the level to return to - static uint8_t level_before_off = 0; - #endif - - #if NUM_CHANNEL_MODES > 1 - channel_mode = cfg.channel_mode; - #endif - - // make sure ramp globals are correct... - // ... but they already are; no need to do it here - //ramp_update_config(); - //nearest_level(1); // same effect, takes less space - - uint8_t mode_min = ramp_floor; - uint8_t mode_max = ramp_ceil; - uint8_t step_size; - if (cfg.ramp_style) { step_size = ramp_discrete_step_size; } - else { step_size = 1; } - - // how bright is "turbo"? - uint8_t turbo_level; - #if defined(USE_2C_STYLE_CONFIG) // user can choose 2C behavior - uint8_t style_2c = cfg.ramp_2c_style; - #ifdef USE_SIMPLE_UI - // simple UI has its own turbo config - if (cfg.simple_ui_active) style_2c = cfg.ramp_2c_style_simple; - #endif - // 0 = no turbo - // 1 = Anduril 1 direct to turbo - // 2 = Anduril 2 direct to ceiling, or turbo if already at ceiling - if (0 == style_2c) turbo_level = mode_max; - else if (1 == style_2c) turbo_level = MAX_LEVEL; - else { - if (memorized_level < mode_max) { turbo_level = mode_max; } - else { turbo_level = MAX_LEVEL; } - } - #elif defined(USE_2C_MAX_TURBO) // Anduril 1 style always - // simple UI: to/from ceiling - // full UI: to/from turbo (Anduril1 behavior) - #ifdef USE_SIMPLE_UI - if (cfg.simple_ui_active) turbo_level = mode_max; - else - #endif - turbo_level = MAX_LEVEL; - #else // Anduril 2 style always - // simple UI: to/from ceiling - // full UI: to/from ceiling if mem < ceiling, - // or to/from turbo if mem >= ceiling - if ((memorized_level < mode_max) - #ifdef USE_SIMPLE_UI - || cfg.simple_ui_active - #endif - ) { turbo_level = mode_max; } - else { turbo_level = MAX_LEVEL; } - #endif - - #ifdef USE_SUNSET_TIMER - // handle the shutoff timer first - uint8_t sunset_active = sunset_timer; // save for comparison - // clock tick - sunset_timer_state(event, arg); - // if the timer was just turned on - if (sunset_timer && (! sunset_active)) { - sunset_timer_orig_level = actual_level; - } - // if the timer just expired, shut off - else if (sunset_active && (! sunset_timer)) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - #endif // ifdef USE_SUNSET_TIMER - - // turn LED on when we first enter the mode - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - #if defined(USE_MOMENTARY_MODE) && defined(USE_STROBE_STATE) - momentary_mode = 0; // 0 = ramping, 1 = strobes - #endif - // if we just got back from config mode, go back to memorized level - if (event == EV_reenter_state) { - arg = memorized_level; - } - // remember this level, unless it's moon or turbo - if ((arg > mode_min) && (arg < mode_max)) - memorized_level = arg; - // use the requested level even if not memorized - arg = nearest_level(arg); - set_level_and_therm_target(arg); - ramp_direction = 1; - return EVENT_HANDLED; - } - #if (B_TIMING_OFF == B_RELEASE_T) - // 1 click (early): off, if configured for early response - else if (event == EV_click1_release) { - level_before_off = actual_level; - set_level_and_therm_target(0); - return EVENT_HANDLED; - } - // 2 clicks (early): abort turning off, if configured for early response - else if (event == EV_click2_press) { - set_level_and_therm_target(level_before_off); - return EVENT_HANDLED; - } - #endif // if (B_TIMING_OFF == B_RELEASE_T) - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: go to/from highest level - else if (event == EV_2clicks) { - if (actual_level < turbo_level) { - set_level_and_therm_target(turbo_level); - } - else { - set_level_and_therm_target(memorized_level); - } - #ifdef USE_SUNSET_TIMER - reset_sunset_timer(); - #endif - return EVENT_HANDLED; - } - - #ifdef USE_LOCKOUT_MODE - // 4 clicks: shortcut to lockout mode - else if (event == EV_4clicks) { - set_level(0); - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - #endif - - // hold: change brightness (brighter, dimmer) - // click, hold: change brightness (dimmer) - else if ((event == EV_click1_hold) || (event == EV_click2_hold)) { - // ramp infrequently in stepped mode - if (cfg.ramp_style && (arg % HOLD_TIMEOUT != 0)) - return EVENT_HANDLED; - #ifdef USE_RAMP_SPEED_CONFIG - // ramp slower if user configured things that way - if ((! cfg.ramp_style) && (arg % ramp_speed)) - return EVENT_HANDLED; - #endif - #ifdef USE_SMOOTH_STEPS - // if a brightness transition is already happening, - // don't interrupt it - // (like 2C for full turbo then 1H to smooth ramp down - // ... without this clause, it flickers because it trips - // the "blink at ramp ceil" clause below, over and over) - if (smooth_steps_in_progress) return EVENT_HANDLED; - #endif - // fix ramp direction on first frame if necessary - if (!arg) { - // click, hold should always go down if possible - if (event == EV_click2_hold) { ramp_direction = -1; } - // make it ramp down instead, if already at max - else if (actual_level >= mode_max) { ramp_direction = -1; } - // make it ramp up if already at min - // (off->hold->stepped_min->release causes this state) - else if (actual_level <= mode_min) { ramp_direction = 1; } - } - // if the button is stuck, err on the side of safety and ramp down - else if ((arg > TICKS_PER_SECOND * 5 - #ifdef USE_RAMP_SPEED_CONFIG - // FIXME: count from time actual_level hits mode_max, - // not from beginning of button hold - * ramp_speed - #endif - ) && (actual_level >= mode_max)) { - ramp_direction = -1; - } - #ifdef USE_LOCKOUT_MODE - // if the button is still stuck, lock the light - else if ((arg > TICKS_PER_SECOND * 10 - #ifdef USE_RAMP_SPEED_CONFIG - // FIXME: count from time actual_level hits mode_min, - // not from beginning of button hold - * ramp_speed - #endif - ) && (actual_level <= mode_min)) { - blink_once(); - set_state(lockout_state, 0); - } - #endif - memorized_level = nearest_level((int16_t)actual_level \ - + (step_size * ramp_direction)); - #if defined(BLINK_AT_RAMP_CEIL) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - // FIXME: blinks at beginning of smooth_steps animation instead - // of the end, so it should blink when actual_level reaches a - // threshold, instead of when memorized_level does - // (one possible fix is to just remove mid-ramp blinks entirely, - // and just blink only when it hits the top while going up) - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #ifdef BLINK_AT_RAMP_MIDDLE_1 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_1) - #endif - #ifdef BLINK_AT_RAMP_MIDDLE_2 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_2) - #endif - #ifdef BLINK_AT_RAMP_CEIL - // FIXME: only blink at top when going up, not down - || (memorized_level == mode_max) - #endif - #ifdef BLINK_AT_RAMP_FLOOR - || (memorized_level == mode_min) - #endif - )) { - blip(); - } - #endif - #if defined(BLINK_AT_STEPS) - uint8_t foo = cfg.ramp_style; - cfg.ramp_style = 1; - uint8_t nearest = nearest_level((int16_t)actual_level); - cfg.ramp_style = foo; - // only blink once for each threshold - if ((memorized_level != actual_level) && - (cfg.ramp_style == 0) && - (memorized_level == nearest) - ) - { - blip(); - } - #endif - set_level_and_therm_target(memorized_level); - #ifdef USE_SUNSET_TIMER - reset_sunset_timer(); - #endif - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - else if ((event == EV_click1_hold_release) - || (event == EV_click2_hold_release)) { - ramp_direction = -ramp_direction; - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); - #endif - return EVENT_HANDLED; - } - - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == AUTO_REVERSE_TIME) ramp_direction = 1; - - #ifdef USE_SUNSET_TIMER - // reduce output if shutoff timer is active - if (sunset_timer) { - uint8_t dimmed_level = sunset_timer_orig_level * sunset_timer / sunset_timer_peak; - uint8_t dimmed_level_next = sunset_timer_orig_level * (sunset_timer-1) / sunset_timer_peak; - uint8_t dimmed_level_delta = dimmed_level - dimmed_level_next; - dimmed_level -= dimmed_level_delta * (sunset_ticks/TICKS_PER_SECOND) / 60; - if (dimmed_level < 1) dimmed_level = 1; - - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(dimmed_level); - target_level = dimmed_level; - #else - set_level_and_therm_target(dimmed_level); - #endif - } - #endif // ifdef USE_SUNSET_TIMER - - #ifdef USE_SET_LEVEL_GRADUALLY - int16_t diff = gradual_target - actual_level; - static uint16_t ticks_since_adjust = 0; - ticks_since_adjust++; - if (diff) { - uint16_t ticks_per_adjust = 256; - if (diff < 0) { - //diff = -diff; - if (actual_level > THERM_FASTER_LEVEL) { - #ifdef THERM_HARD_TURBO_DROP - ticks_per_adjust >>= 2; - #endif - ticks_per_adjust >>= 2; - } - } else { - // rise at half speed - ticks_per_adjust <<= 1; - } - while (diff) { - ticks_per_adjust >>= 1; - //diff >>= 1; - diff /= 2; // because shifting produces weird behavior - } - if (ticks_since_adjust > ticks_per_adjust) - { - gradual_tick(); - ticks_since_adjust = 0; - } - } - #endif // ifdef USE_SET_LEVEL_GRADUALLY - return EVENT_HANDLED; - } - - #ifdef USE_THERMAL_REGULATION - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - #if 0 - blip(); - #endif - #ifdef THERM_HARD_TURBO_DROP - //if (actual_level > THERM_FASTER_LEVEL) { - if (actual_level == MAX_LEVEL) { - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(THERM_FASTER_LEVEL); - target_level = THERM_FASTER_LEVEL; - #else - set_level_and_therm_target(THERM_FASTER_LEVEL); - #endif - } else - #endif - if (actual_level > MIN_THERM_STEPDOWN) { - int16_t stepdown = actual_level - arg; - if (stepdown < MIN_THERM_STEPDOWN) stepdown = MIN_THERM_STEPDOWN; - else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepdown); - #else - set_level(stepdown); - #endif - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - #if 0 - blip(); - #endif - if (actual_level < target_level) { - //int16_t stepup = actual_level + (arg>>1); - int16_t stepup = actual_level + arg; - if (stepup > target_level) stepup = target_level; - else if (stepup < MIN_THERM_STEPDOWN) stepup = MIN_THERM_STEPDOWN; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepup); - #else - set_level(stepup); - #endif - } - return EVENT_HANDLED; - } - #ifdef USE_SET_LEVEL_GRADUALLY - // temperature is within target window - // (so stop trying to adjust output) - else if (event == EV_temperature_okay) { - // if we're still adjusting output... stop after the current step - if (gradual_target > actual_level) - gradual_target = actual_level + 1; - else if (gradual_target < actual_level) - gradual_target = actual_level - 1; - return EVENT_HANDLED; - } - #endif // ifdef USE_SET_LEVEL_GRADUALLY - #endif // ifdef USE_THERMAL_REGULATION - - ////////// Every action below here is blocked in the simple UI ////////// - // That is, unless we specifically want to enable 3C for smooth/stepped selection in Simple UI - #if defined(USE_SIMPLE_UI) && !defined(USE_SIMPLE_UI_RAMPING_TOGGLE) - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - - // 3 clicks: toggle smooth vs discrete ramping - // (and/or 6 clicks when there are multiple channel modes) - // (handle 3C here anyway, when all but 1 mode is disabled) - else if ((event == EV_3clicks) - #if NUM_CHANNEL_MODES > 1 - || (event == EV_6clicks) - ) { - // detect if > 1 channel mode is enabled, - // and if so, fall through so channel mode code can handle it - // otherwise, change the ramp style - if (event == EV_3clicks) { - uint8_t enabled = 0; - for (uint8_t m=0; m<NUM_CHANNEL_MODES; m++) - enabled += channel_mode_enabled(m); - if (enabled > 1) - return EVENT_NOT_HANDLED; - } - #else - ) { - #endif - - cfg.ramp_style = !cfg.ramp_style; - save_config(); - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); - #endif - blip(); - memorized_level = nearest_level(actual_level); - set_level_and_therm_target(memorized_level); - #ifdef USE_SUNSET_TIMER - reset_sunset_timer(); - #endif - return EVENT_HANDLED; - } - - // If we allowed 3C in Simple UI, now block further actions - #if defined(USE_SIMPLE_UI) && defined(USE_SIMPLE_UI_RAMPING_TOGGLE) - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - - // 3H: momentary turbo (on lights with no tint ramping) - // (or 4H when tint ramping is available) - else if ((event == EV_click3_hold) - #ifdef USE_CHANNEL_MODE_ARGS - || (event == EV_click4_hold) - #endif - ) { - #ifdef USE_CHANNEL_MODE_ARGS - // ramp tint if tint exists in this mode - if ((event == EV_click3_hold) - && (channel_has_args(channel_mode))) - return EVENT_NOT_HANDLED; - #endif - if (! arg) { // first frame only, to allow thermal regulation to work - #ifdef USE_2C_STYLE_CONFIG - uint8_t tl = style_2c ? MAX_LEVEL : turbo_level; - set_level_and_therm_target(tl); - #else - set_level_and_therm_target(turbo_level); - #endif - } - return EVENT_HANDLED; - } - else if ((event == EV_click3_hold_release) - #ifdef USE_CHANNEL_MODE_ARGS - || (event == EV_click4_hold_release) - #endif - ) { - #ifdef USE_CHANNEL_MODE_ARGS - // ramp tint if tint exists in this mode - if ((event == EV_click3_hold_release) - && (channel_has_args(channel_mode))) - return EVENT_NOT_HANDLED; - #endif - set_level_and_therm_target(memorized_level); - return EVENT_HANDLED; - } - - #ifdef USE_MOMENTARY_MODE - // 5 clicks: shortcut to momentary mode - else if (event == EV_5clicks) { - set_level(0); - set_state(momentary_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_RAMP_CONFIG - // 7H: configure this ramp mode - else if (event == EV_click7_hold) { - push_state(ramp_config_state, 0); - return EVENT_HANDLED; - } - #endif - - #ifdef USE_MANUAL_MEMORY - else if (event == EV_10clicks) { - // turn on manual memory and save current brightness - manual_memory_save(); - save_config(); - blink_once(); - return EVENT_HANDLED; - } - else if (event == EV_click10_hold) { - #ifdef USE_RAMP_EXTRAS_CONFIG - // let user configure a bunch of extra ramp options - push_state(ramp_extras_config_state, 0); - #else // manual mem, but no timer - // turn off manual memory; go back to automatic - if (0 == arg) { - cfg.manual_memory = 0; - save_config(); - blink_once(); - } - #endif - return EVENT_HANDLED; - } - #endif // ifdef USE_MANUAL_MEMORY - - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_RAMP_CONFIG -void ramp_config_save(uint8_t step, uint8_t value) { - - // 0 = smooth ramp, 1 = stepped ramp, 2 = simple UI's ramp - uint8_t style = cfg.ramp_style; - #ifdef USE_SIMPLE_UI - if (current_state == simple_ui_config_state) style = 2; - #endif - - #if defined(USE_SIMPLE_UI) && defined(USE_2C_STYLE_CONFIG) - // simple UI config is weird... - // has some ramp extras after floor/ceil/steps - if (4 == step) { - cfg.ramp_2c_style_simple = value; - } - else - #endif - - // save adjusted value to the correct slot - if (value) { - // ceiling value is inverted - if (step == 2) value = MAX_LEVEL + 1 - value; - - // which option are we configuring? - // TODO? maybe rearrange definitions to avoid the need for this table - // (move all ramp values into a single array?) - uint8_t *steps[] = { cfg.ramp_floors, cfg.ramp_ceils, cfg.ramp_stepss }; - uint8_t *option; - option = steps[step-1]; - option[style] = value; - } -} - -uint8_t ramp_config_state(Event event, uint16_t arg) { - #ifdef USE_RAMP_SPEED_CONFIG - const uint8_t num_config_steps = 3; - #else - uint8_t num_config_steps = cfg.ramp_style + 2; - #endif - return config_state_base(event, arg, - num_config_steps, ramp_config_save); -} - -#ifdef USE_SIMPLE_UI -uint8_t simple_ui_config_state(Event event, uint16_t arg) { - #if defined(USE_2C_STYLE_CONFIG) - #define SIMPLE_UI_NUM_MENU_ITEMS 4 - #else - #define SIMPLE_UI_NUM_MENU_ITEMS 3 - #endif - return config_state_base(event, arg, - SIMPLE_UI_NUM_MENU_ITEMS, - ramp_config_save); -} -#endif -#endif // #ifdef USE_RAMP_CONFIG - -#ifdef USE_RAMP_EXTRAS_CONFIG -void ramp_extras_config_save(uint8_t step, uint8_t value) { - // item 1: disable manual memory, go back to automatic - if (manual_memory_config_step == step) { - cfg.manual_memory = 0; - } - - #ifdef USE_MANUAL_MEMORY_TIMER - // item 2: set manual memory timer duration - // FIXME: should be limited to (65535 / SLEEP_TICKS_PER_MINUTE) - // to avoid overflows or impossibly long timeouts - // (by default, the effective limit is 145, but it allows up to 255) - else if (manual_memory_timer_config_step == step) { - cfg.manual_memory_timer = value; - } - #endif - - #ifdef USE_RAMP_AFTER_MOON_CONFIG - // item 3: ramp up after hold-from-off for moon? - // 0 = yes, ramp after moon - // 1+ = no, stay at moon - else if (dont_ramp_after_moon_config_step == step) { - cfg.dont_ramp_after_moon = value; - } - #endif - - #ifdef USE_2C_STYLE_CONFIG - // item 4: Anduril 1 2C turbo, or Anduril 2 2C ceiling? - // 1 = Anduril 1, 2C turbo - // 2+ = Anduril 2, 2C ceiling - else if (ramp_2c_style_config_step == step) { - cfg.ramp_2c_style = value; - } - #endif - - #ifdef USE_SMOOTH_STEPS - else if (smooth_steps_style_config_step == step) { - cfg.smooth_steps_style = value; - } - #endif -} - -uint8_t ramp_extras_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - ramp_extras_config_num_steps - 1, - ramp_extras_config_save); -} -#endif - -#ifdef USE_GLOBALS_CONFIG -void globals_config_save(uint8_t step, uint8_t value) { - if (0) {} - #if defined(USE_CHANNEL_MODE_ARGS) && defined(USE_STEPPED_TINT_RAMPING) - else if (step == tint_style_config_step) { cfg.tint_ramp_style = value; } - #endif - #ifdef USE_JUMP_START - else if (step == jump_start_config_step) { cfg.jump_start_level = value; } - #endif -} - -uint8_t globals_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - globals_config_num_steps - 1, - globals_config_save); -} -#endif - -// find the ramp level closest to the target, -// using only the levels which are allowed in the current state -uint8_t nearest_level(int16_t target) { - // using int16_t here saves us a bunch of logic elsewhere, - // by allowing us to correct for numbers < 0 or > 255 in one central place - - // ensure all globals are correct - ramp_update_config(); - - // bounds check - uint8_t mode_min = ramp_floor; - uint8_t mode_max = ramp_ceil; - uint8_t num_steps = cfg.ramp_stepss[1 - #ifdef USE_SIMPLE_UI - + cfg.simple_ui_active - #endif - ]; - // special case for 1-step ramp... use halfway point between floor and ceiling - if (cfg.ramp_style && (1 == num_steps)) { - uint8_t mid = (mode_max + mode_min) >> 1; - return mid; - } - if (target < mode_min) return mode_min; - if (target > mode_max) return mode_max; - // the rest isn't relevant for smooth ramping - if (! cfg.ramp_style) return target; - - uint8_t ramp_range = mode_max - mode_min; - ramp_discrete_step_size = ramp_range / (num_steps-1); - uint8_t this_level = mode_min; - - for(uint8_t i=0; i<num_steps; i++) { - this_level = mode_min + (i * (uint16_t)ramp_range / (num_steps-1)); - int16_t diff = target - this_level; - if (diff < 0) diff = -diff; - if (diff <= (ramp_discrete_step_size>>1)) - return this_level; - } - return this_level; -} - -// ensure ramp globals are correct -void ramp_update_config() { - uint8_t which = cfg.ramp_style; - #ifdef USE_SIMPLE_UI - if (cfg.simple_ui_active) { which = 2; } - #endif - - ramp_floor = cfg.ramp_floors[which]; - ramp_ceil = cfg.ramp_ceils[which]; -} - -#if defined(USE_THERMAL_REGULATION) || defined(USE_SMOOTH_STEPS) -void set_level_and_therm_target(uint8_t level) { - #ifdef USE_THERMAL_REGULATION - target_level = level; - #endif - #ifdef USE_SMOOTH_STEPS - // if adjusting by more than 1 ramp level, - // animate the step change (if smooth steps enabled) - uint8_t diff = (level > actual_level) - ? (level - actual_level) : (actual_level - level); - if (smooth_steps_in_progress - || (cfg.smooth_steps_style && (diff > 1))) - set_level_smooth(level, 4); - else - #endif - set_level(level); -} -#else -#define set_level_and_therm_target(level) set_level(level) -#endif - -void manual_memory_restore() { - memorized_level = cfg.manual_memory; - #if NUM_CHANNEL_MODES > 1 - channel_mode = cfg.channel_mode = cfg.manual_memory_channel_mode; - #endif - #ifdef USE_CHANNEL_MODE_ARGS - for (uint8_t i=0; i<NUM_CHANNEL_MODES; i++) - cfg.channel_mode_args[i] = cfg.manual_memory_channel_args[i]; - #endif -} - -void manual_memory_save() { - cfg.manual_memory = actual_level; - #if NUM_CHANNEL_MODES > 1 - cfg.manual_memory_channel_mode = channel_mode; - #endif - #ifdef USE_CHANNEL_MODE_ARGS - for (uint8_t i=0; i<NUM_CHANNEL_MODES; i++) - cfg.manual_memory_channel_args[i] = cfg.channel_mode_args[i]; - #endif -} - -#ifdef USE_SUNSET_TIMER -void reset_sunset_timer() { - if (sunset_timer) { - sunset_timer_orig_level = actual_level; - sunset_timer_peak = sunset_timer; - sunset_ticks = 0; - } -} -#endif - diff --git a/spaghetti-monster/anduril/ramp-mode.h b/spaghetti-monster/anduril/ramp-mode.h deleted file mode 100644 index 59c8db0..0000000 --- a/spaghetti-monster/anduril/ramp-mode.h +++ /dev/null @@ -1,224 +0,0 @@ -// ramp-mode.h: Ramping functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifndef RAMP_LENGTH -#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file -#endif - -// thermal properties, if not defined per-driver -#ifndef MIN_THERM_STEPDOWN -// TODO: Replace MAX_Xx7135 with MAX_CH1, MAX_CH2, MAX_REGULATED, etc -#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to -#endif -#ifndef THERM_FASTER_LEVEL - #ifdef MAX_Nx7135 - #define THERM_FASTER_LEVEL MAX_Nx7135 // throttle back faster when high - #else - #define THERM_FASTER_LEVEL (RAMP_SIZE*4/5) // throttle back faster when high - #endif -#endif - -#if defined(USE_SIMPLE_UI) -// TODO: Move these settings to config-default.h? -// start in the simple UI after each factory reset? -#ifndef SIMPLE_UI_ACTIVE -#define SIMPLE_UI_ACTIVE 1 -#endif -#ifndef SIMPLE_UI_FLOOR -#define SIMPLE_UI_FLOOR (RAMP_SIZE*2/15) -#endif -#ifndef SIMPLE_UI_CEIL -#define SIMPLE_UI_CEIL (RAMP_SIZE*9/15) -#endif -#ifndef SIMPLE_UI_STEPS -#define SIMPLE_UI_STEPS 5 -#endif -#endif - - -// configure the timing of turning on/off in regular ramp mode -// press: react as soon as the button is pressed -#define B_PRESS_T 0 -// release: react as soon as the button is released -#define B_RELEASE_T 1 -// timeout: react as soon as we're sure the user isn't doing a double-click -#define B_TIMEOUT_T 2 -// defaults are release on, timeout off -#ifndef B_TIMING_ON -//#define B_TIMING_ON B_PRESS_T -#define B_TIMING_ON B_RELEASE_T -#endif -#ifndef B_TIMING_OFF -//#define B_TIMING_OFF B_RELEASE_T -#define B_TIMING_OFF B_TIMEOUT_T -#endif - - -// default ramp options if not overridden earlier per-driver -#ifndef RAMP_STYLE -#define RAMP_STYLE 0 // smooth default -#endif -#ifndef DEFAULT_RAMP_SPEED -#define DEFAULT_RAMP_SPEED 1 // WDT ticks per "frame", must be 1 or more -#endif -#ifndef RAMP_SMOOTH_FLOOR - #define RAMP_SMOOTH_FLOOR 1 -#endif -#ifndef RAMP_SMOOTH_CEIL - #if PWM_CHANNELS == 3 - #define RAMP_SMOOTH_CEIL MAX_Nx7135 - #else - #define RAMP_SMOOTH_CEIL MAX_LEVEL - 30 - #endif -#endif -#ifndef RAMP_DISCRETE_FLOOR - #define RAMP_DISCRETE_FLOOR 20 -#endif -#ifndef RAMP_DISCRETE_CEIL - #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#endif -#ifndef RAMP_DISCRETE_STEPS - #define RAMP_DISCRETE_STEPS 7 -#endif - -// mile marker(s) partway up the ramp -// default: blink only at border between regulated and FET -#ifdef BLINK_AT_RAMP_MIDDLE - // FIXME: remove PWM_CHANNELS, use some other abstraction - #if PWM_CHANNELS >= 3 - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135 - #ifndef BLINK_AT_RAMP_MIDDLE_2 - #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135 - #endif - #endif - #else - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135 - #endif - #endif -#endif - - -// ramping mode and its related config mode -uint8_t steady_state(Event event, uint16_t arg); - -#ifdef USE_RAMP_CONFIG -uint8_t ramp_config_state(Event event, uint16_t arg); -void ramp_config_save(uint8_t step, uint8_t value); -#ifdef USE_SIMPLE_UI -uint8_t simple_ui_config_state(Event event, uint16_t arg); -#endif -#endif - -#if defined(USE_MANUAL_MEMORY_TIMER) || defined(USE_RAMP_AFTER_MOON_CONFIG) || defined(USE_2C_STYLE_CONFIG) || defined(USE_AUTO_SUNSET) -#define USE_RAMP_EXTRAS_CONFIG -#endif -#ifdef USE_RAMP_EXTRAS_CONFIG -uint8_t ramp_extras_config_state(Event event, uint16_t arg); -#endif - -// calculate the nearest ramp level which would be valid at the moment -// (is a no-op for smooth ramp, but limits discrete ramp to only the -// correct levels for the user's config) -uint8_t nearest_level(int16_t target); - -// ensure ramp globals are correct -void ramp_update_config(); - -#if defined(USE_THERMAL_REGULATION) || defined(USE_SMOOTH_STEPS) -// brightness before thermal step-down -uint8_t target_level = 0; -void set_level_and_therm_target(uint8_t level); -#else -#define set_level_and_therm_target(level) set_level(level) -#endif - - -// brightness control -uint8_t memorized_level = DEFAULT_LEVEL; -#ifdef USE_MANUAL_MEMORY - void manual_memory_restore(); - void manual_memory_save(); - #ifndef DEFAULT_MANUAL_MEMORY - #define DEFAULT_MANUAL_MEMORY 0 - #endif - #ifdef USE_MANUAL_MEMORY_TIMER - #ifndef DEFAULT_MANUAL_MEMORY_TIMER - #define DEFAULT_MANUAL_MEMORY_TIMER 0 - #endif - #endif -#endif - -#ifndef DEFAULT_2C_STYLE_SIMPLE - #define DEFAULT_2C_STYLE_SIMPLE 0 -#endif - -#ifdef USE_2C_STYLE_CONFIG -#ifndef DEFAULT_2C_STYLE -#define DEFAULT_2C_STYLE 2 -#endif - -#ifdef USE_2C_MAX_TURBO -#error Cannot use USE_2C_MAX_TURBO and USE_2C_STYLE_CONFIG at the same time. -#endif -#endif - -#ifdef USE_RAMP_SPEED_CONFIG -#define ramp_speed (cfg.ramp_stepss[0]) -#endif -#ifdef USE_RAMP_AFTER_MOON_CONFIG -#ifndef DEFAULT_DONT_RAMP_AFTER_MOON -#define DEFAULT_DONT_RAMP_AFTER_MOON 0 -#endif -#endif -// current values, regardless of style -uint8_t ramp_floor = RAMP_SMOOTH_FLOOR; -uint8_t ramp_ceil = RAMP_SMOOTH_CEIL; - -uint8_t ramp_discrete_step_size; // don't set this - -#ifdef USE_SUNSET_TIMER -uint8_t sunset_timer_orig_level = 0; -void reset_sunset_timer(); -#endif - -#ifdef USE_RAMP_EXTRAS_CONFIG -typedef enum { - ramp_extras_cfg_zero = 0, - manual_memory_config_step, - #ifdef USE_MANUAL_MEMORY_TIMER - manual_memory_timer_config_step, - #endif - #ifdef USE_RAMP_AFTER_MOON_CONFIG - dont_ramp_after_moon_config_step, - #endif - #ifdef USE_2C_STYLE_CONFIG - ramp_2c_style_config_step, - #endif - #ifdef USE_SMOOTH_STEPS - smooth_steps_style_config_step, - #endif - ramp_extras_config_num_steps -} ramp_extras_config_steps_e; -#endif - -#ifdef USE_GLOBALS_CONFIG -typedef enum { - globals_cfg_zero = 0, - #if defined(USE_CHANNEL_MODE_ARGS) && defined(USE_STEPPED_TINT_RAMPING) - tint_style_config_step, - #endif - #ifdef USE_JUMP_START - jump_start_config_step, - #endif - globals_config_num_steps -} globals_config_steps_e; - -void globals_config_save(uint8_t step, uint8_t value); -uint8_t globals_config_state(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/anduril/smooth-steps.c b/spaghetti-monster/anduril/smooth-steps.c deleted file mode 100644 index 9631e41..0000000 --- a/spaghetti-monster/anduril/smooth-steps.c +++ /dev/null @@ -1,47 +0,0 @@ -// smooth-steps.c: Smooth step adjustments for Anduril. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "smooth-steps.h" - -#ifdef USE_SMOOTH_STEPS - -// one iteration of main loop() -void smooth_steps_iter() { - if (actual_level == smooth_steps_target) { - set_level(smooth_steps_target); - smooth_steps_in_progress = 0; - // restore prev_level when animation ends - prev_level = smooth_steps_start; - } - else if (smooth_steps_target > actual_level) { - // power-linear(ish) ascent - // (jump by ~20% of remaining distance on each frame) - uint8_t diff = smooth_steps_target - actual_level; - uint8_t this = diff / smooth_steps_speed; - if (!this) this = 1; - set_level(actual_level + this); - nice_delay_ms(10); - } else { - // ramp-linear descent - // (jump by 1 on each frame, frame rate gives constant total time) - uint8_t diff = smooth_steps_start - smooth_steps_target; - uint16_t delay = 1 + (30 * smooth_steps_speed / diff); - set_level(actual_level - 1); - // TODO? if delay < one PWM cycle, this can look a little weird - nice_delay_ms(delay); - } -} - -void set_level_smooth(uint8_t level, uint8_t speed) { - smooth_steps_target = level; - smooth_steps_speed = speed; // higher = slower - smooth_steps_in_progress = 1; - // for setting prev_level after animation ends - smooth_steps_start = actual_level; -} - -#endif - diff --git a/spaghetti-monster/anduril/smooth-steps.h b/spaghetti-monster/anduril/smooth-steps.h deleted file mode 100644 index a553af2..0000000 --- a/spaghetti-monster/anduril/smooth-steps.h +++ /dev/null @@ -1,19 +0,0 @@ -// smooth-steps.h: Smooth step adjustments for Anduril. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_SMOOTH_STEPS - -uint8_t smooth_steps_start; -uint8_t smooth_steps_target; -uint8_t smooth_steps_in_progress; -uint8_t smooth_steps_speed; - -void smooth_steps_iter(); - -void set_level_smooth(uint8_t level, uint8_t speed); - -#endif - diff --git a/spaghetti-monster/anduril/sos-mode.c b/spaghetti-monster/anduril/sos-mode.c deleted file mode 100644 index 2a4e97c..0000000 --- a/spaghetti-monster/anduril/sos-mode.c +++ /dev/null @@ -1,56 +0,0 @@ -// sos-mode.c: SOS mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "sos-mode.h" - -#ifdef USE_SOS_MODE_IN_BLINKY_GROUP -uint8_t sos_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: next blinky mode - else if (event == EV_2clicks) { - #if defined(USE_BATTCHECK_MODE) - set_state(battcheck_state, 0); - #elif defined(USE_THERMAL_REGULATION) - set_state(tempcheck_state, 0); - #elif defined(USE_BEACON_MODE) - set_state(beacon_state, 0); - #endif - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - -void sos_blink(uint8_t num, uint8_t dah) { - #define DIT_LENGTH 200 - for (; num > 0; num--) { - set_level(memorized_level); - nice_delay_ms(DIT_LENGTH); - if (dah) { // dah is 3X as long as a dit - nice_delay_ms(DIT_LENGTH*2); - } - set_level(0); - // one "off" dit between blinks - nice_delay_ms(DIT_LENGTH); - } - // three "off" dits (or one "dah") between letters - // (except for SOS, which is collectively treated as a single "letter") - //nice_delay_ms(DIT_LENGTH*2); -} - -inline void sos_mode_iter() { - // one iteration of main loop() - //nice_delay_ms(1000); - sos_blink(3, 0); // S - sos_blink(3, 1); // O - sos_blink(3, 0); // S - nice_delay_ms(2000); -} - diff --git a/spaghetti-monster/anduril/sos-mode.h b/spaghetti-monster/anduril/sos-mode.h deleted file mode 100644 index 5af61be..0000000 --- a/spaghetti-monster/anduril/sos-mode.h +++ /dev/null @@ -1,11 +0,0 @@ -// sos-mode.h: SOS mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_SOS_MODE_IN_BLINKY_GROUP -// automatic SOS emergency signal -uint8_t sos_state(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/anduril/steps.py b/spaghetti-monster/anduril/steps.py deleted file mode 100755 index e19c9a6..0000000 --- a/spaghetti-monster/anduril/steps.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python - -"""steps.py: Calculate the stepped ramp levels used by Anduril. -Usage: steps.py floor ceiling num_steps -For example: - > ./steps.py 1 150 3 - 1: 1 - 2: 75 - 3: 150 -""" - -def main(args): - floor, ceil, steps = [int(x) for x in args[:3]] - for i in range(steps): - guess = floor + (i * (float(ceil-floor)/(steps-1))) - this = nearest_level(guess, floor, ceil, steps) - #print('%i: %i (guess: %i)' % (i+1, this, guess)) - print('%i: %i' % (i+1, this)) - - -def nearest_level(target, floor, ceil, steps): - """Copied/adapted from anduril.c""" - # bounds check - # using int16_t here saves us a bunch of logic elsewhere, - # by allowing us to correct for numbers < 0 or > 255 in one central place - mode_min = floor; - mode_max = ceil; - - if (target < mode_min): return mode_min; - if (target > mode_max): return mode_max; - # the rest isn't relevant for smooth ramping - #if (! ramp_style): return target; - - ramp_range = ceil - floor; - ramp_discrete_step_size = int(ramp_range / (steps-1)); - this_level = floor; - - for i in range(steps): - this_level = floor + (i * int(ramp_range) / (steps-1)); - diff = int(target - this_level); - if (diff < 0): diff = -diff; - if (diff <= (ramp_discrete_step_size>>1)): - return this_level; - - return this_level; - - -if __name__ == "__main__": - import sys - main(sys.argv[1:]) - diff --git a/spaghetti-monster/anduril/strobe-modes-fsm.h b/spaghetti-monster/anduril/strobe-modes-fsm.h deleted file mode 100644 index 4d948ed..0000000 --- a/spaghetti-monster/anduril/strobe-modes-fsm.h +++ /dev/null @@ -1,55 +0,0 @@ -// strobe-modes-fsm.h: FSM config for strobe modes in Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// enable the random number generator if we need it -#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE) -#define USE_PSEUDO_RAND -#endif - -// party strobe uses really short pulses -#ifdef USE_PARTY_STROBE_MODE -#define USE_DELAY_ZERO -#endif - -// candle mode is basically a bunch of stacked random triangle waves -#if defined(USE_CANDLE_MODE) -#define USE_TRIANGLE_WAVE -#endif - -// the presence of strobe mode(s) affects how many eeprom bytes we need, -// so it's relevant for FSM configuration -#if defined(USE_CANDLE_MODE) || defined(USE_BIKE_FLASHER_MODE) || defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) || defined(USE_LIGHTNING_MODE) -#define USE_STROBE_STATE -#endif - -// internal numbering for strobe modes -#ifdef USE_STROBE_STATE -typedef enum { - #ifdef USE_PARTY_STROBE_MODE - party_strobe_e, - #endif - #ifdef USE_TACTICAL_STROBE_MODE - tactical_strobe_e, - #endif - #ifdef USE_POLICE_COLOR_STROBE_MODE - police_color_strobe_e, - #endif - #ifdef USE_LIGHTNING_MODE - lightning_storm_e, - #endif - #ifdef USE_CANDLE_MODE - candle_mode_e, - #endif - #ifdef USE_BIKE_FLASHER_MODE - bike_flasher_e, - #endif - strobe_mode_END -} strobe_mode_te; - -//const int NUM_STROBES = strobe_mode_END; -#define NUM_STROBES strobe_mode_END -#endif - diff --git a/spaghetti-monster/anduril/strobe-modes.c b/spaghetti-monster/anduril/strobe-modes.c deleted file mode 100644 index ad17964..0000000 --- a/spaghetti-monster/anduril/strobe-modes.c +++ /dev/null @@ -1,332 +0,0 @@ -// strobe-modes.c: Strobe modes for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "strobe-modes.h" - -#ifdef USE_STROBE_STATE -uint8_t strobe_state(Event event, uint16_t arg) { - static int8_t ramp_direction = 1; - - // 'st' reduces ROM size slightly - strobe_mode_te st = current_strobe_type; - - #ifdef USE_MOMENTARY_MODE - momentary_mode = 1; // 0 = ramping, 1 = strobes - #endif - - #ifdef USE_CANDLE_MODE - // pass all events to candle mode, when it's active - // (the code is in its own pseudo-state to keep things cleaner) - if (st == candle_mode_e) { - candle_mode_state(event, arg); - } - #endif - - if (0) {} // placeholder - // init anything which needs to be initialized - else if (event == EV_enter_state) { - current_strobe_type = cfg.strobe_type; - ramp_direction = 1; - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: rotate through strobe/flasher modes - else if (event == EV_2clicks) { - current_strobe_type = cfg.strobe_type = (st + 1) % NUM_STROBES; - save_config(); - return EVENT_HANDLED; - } - #if (NUM_CHANNEL_MODES > 1) && defined(USE_CHANNEL_PER_STROBE) - // 3 clicks: rotate through channel modes for the current strobe - else if (event == EV_3clicks) { - // TODO: maybe skip aux modes? - set_channel_mode((channel_mode + 1) % NUM_CHANNEL_MODES); - cfg.strobe_channels[st] = channel_mode; - save_config(); - return EVENT_HANDLED; - } - #endif - // 4 clicks: rotate backward through strobe/flasher modes - else if (event == EV_4clicks) { - current_strobe_type = cfg.strobe_type = (st - 1 + NUM_STROBES) % NUM_STROBES; - save_config(); - return EVENT_HANDLED; - } - // hold: change speed (go faster) - // or change brightness (brighter) - else if (event == EV_click1_hold) { - if (0) {} // placeholder - - // party / tactical strobe faster - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_TACTICAL_STROBE_MODE - else if (st <= tactical_strobe_e) { - #else - else if (st == party_strobe_e) { - #endif - if ((arg & 1) == 0) { - uint8_t d = cfg.strobe_delays[st]; - d -= ramp_direction; - if (d < 8) d = 8; - else if (d > 254) d = 254; - cfg.strobe_delays[st] = d; - } - } - #endif - - // lightning has no adjustments - //else if (st == lightning_storm_e) {} - - // biking mode brighter - #ifdef USE_BIKE_FLASHER_MODE - else if (st == bike_flasher_e) { - cfg.bike_flasher_brightness += ramp_direction; - if (cfg.bike_flasher_brightness < 2) cfg.bike_flasher_brightness = 2; - else if (cfg.bike_flasher_brightness > MAX_BIKING_LEVEL) cfg.bike_flasher_brightness = MAX_BIKING_LEVEL; - set_level(cfg.bike_flasher_brightness); - } - #endif - - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - // ... and save new strobe settings - else if (event == EV_click1_hold_release) { - ramp_direction = -ramp_direction; - save_config(); - return EVENT_HANDLED; - } - // click, hold: change speed (go slower) - // or change brightness (dimmer) - else if (event == EV_click2_hold) { - ramp_direction = 1; - - if (0) {} // placeholder - - // party / tactical strobe slower - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_TACTICAL_STROBE_MODE - else if (st <= tactical_strobe_e) { - #else - else if (st == party_strobe_e) { - #endif - if ((arg & 1) == 0) { - if (cfg.strobe_delays[st] < 255) cfg.strobe_delays[st] ++; - } - } - #endif - - // lightning has no adjustments - //else if (st == lightning_storm_e) {} - - // biking mode dimmer - #ifdef USE_BIKE_FLASHER_MODE - else if (st == bike_flasher_e) { - if (cfg.bike_flasher_brightness > 2) - cfg.bike_flasher_brightness --; - set_level(cfg.bike_flasher_brightness); - } - #endif - - return EVENT_HANDLED; - } - // release hold: save new strobe settings - else if (event == EV_click2_hold_release) { - save_config(); - return EVENT_HANDLED; - } - #ifdef USE_MOMENTARY_MODE - // 5 clicks: go to momentary mode (momentary strobe) - else if (event == EV_5clicks) { - set_state(momentary_state, 0); - set_level(0); - return EVENT_HANDLED; - } - #endif - #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE) - // clock tick: bump the random seed - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == AUTO_REVERSE_TIME) ramp_direction = 1; - - pseudo_rand_seed += arg; - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - -// runs repeatedly in FSM loop() whenever UI is in strobe_state or momentary strobe -inline void strobe_state_iter() { - uint8_t st = current_strobe_type; // can't use switch() on an enum - - #if (NUM_CHANNEL_MODES > 1) && defined(USE_CHANNEL_PER_STROBE) - // remember channel mode for each strobe - channel_mode = cfg.strobe_channels[st]; - #endif - - switch(st) { - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_PARTY_STROBE_MODE - case party_strobe_e: - #endif - #ifdef USE_TACTICAL_STROBE_MODE - case tactical_strobe_e: - #endif - party_tactical_strobe_mode_iter(st); - break; - #endif - - #ifdef USE_POLICE_COLOR_STROBE_MODE - case police_color_strobe_e: - police_color_strobe_iter(); - break; - #endif - - #ifdef USE_LIGHTNING_MODE - case lightning_storm_e: - lightning_storm_iter(); - break; - #endif - - #ifdef USE_BIKE_FLASHER_MODE - case bike_flasher_e: - bike_flasher_iter(); - break; - #endif - } -} -#endif // ifdef USE_STROBE_STATE - -#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) -inline void party_tactical_strobe_mode_iter(uint8_t st) { - // one iteration of main loop() - uint8_t del = cfg.strobe_delays[st]; - // TODO: make tac strobe brightness configurable? - set_level(STROBE_BRIGHTNESS); - if (0) {} // placeholder - #ifdef USE_PARTY_STROBE_MODE - else if (st == party_strobe_e) { // party strobe - #ifdef PARTY_STROBE_ONTIME - nice_delay_ms(PARTY_STROBE_ONTIME); - #else - if (del < 42) delay_zero(); - else nice_delay_ms(1); - #endif - } - #endif - #ifdef USE_TACTICAL_STROBE_MODE - else { //tactical strobe - nice_delay_ms(del >> 1); - } - #endif - set_level(STROBE_OFF_LEVEL); - nice_delay_ms(del); // no return check necessary on final delay -} -#endif - -#ifdef USE_POLICE_COLOR_STROBE_MODE -inline void police_color_strobe_iter() { - // one iteration of main loop() - uint8_t del = 66; - // TODO: make police strobe brightness configurable - uint8_t bright = memorized_level; - //uint8_t channel = channel_mode; - - for (uint8_t i=0; i<10; i++) { - if (0 == i) set_channel_mode(POLICE_COLOR_STROBE_CH1); - else if (5 == i) set_channel_mode(POLICE_COLOR_STROBE_CH2); - set_level(bright); - nice_delay_ms(del >> 1); - set_level(STROBE_OFF_LEVEL); - nice_delay_ms(del); - } - - // restore the channel when done - //set_channel_mode(channel); - channel_mode = cfg.channel_mode; -} -#endif - -#ifdef USE_LIGHTNING_MODE -inline void lightning_storm_iter() { - // one iteration of main loop() - int16_t brightness; - uint16_t rand_time; - - // turn the emitter on at a random level, - // for a random amount of time between 1ms and 32ms - //rand_time = 1 << (pseudo_rand() % 7); - rand_time = pseudo_rand() & 63; - brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64 - brightness += 1 << (pseudo_rand() % 5); // 2 to 80 now - brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias) - if (brightness > MAX_LEVEL) brightness = MAX_LEVEL; - set_level(brightness); - nice_delay_ms(rand_time); - - // decrease the brightness somewhat more gradually, like lightning - uint8_t stepdown = brightness >> 3; - if (stepdown < 1) stepdown = 1; - while(brightness > 1) { - nice_delay_ms(rand_time); - brightness -= stepdown; - if (brightness < 0) brightness = 0; - set_level(brightness); - /* - if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) { - brightness <<= 1; - set_level(brightness); - } - */ - if (! (pseudo_rand() & 3)) { - nice_delay_ms(rand_time); - set_level(brightness>>1); - } - } - - // turn the emitter off, - // for a random amount of time between 1ms and 8192ms - // (with a low bias) - rand_time = 1 << (pseudo_rand() % 13); - rand_time += pseudo_rand() % rand_time; - set_level(0); - nice_delay_ms(rand_time); // no return check necessary on final delay -} -#endif - -#ifdef USE_BIKE_FLASHER_MODE -#ifndef BIKE_STROBE_ONTIME -#define BIKE_STROBE_ONTIME 0 -#endif -inline void bike_flasher_iter() { - // one iteration of main loop() - uint8_t burst = cfg.bike_flasher_brightness << 1; - if (burst > MAX_LEVEL) burst = MAX_LEVEL; - for(uint8_t i=0; i<4; i++) { - set_level(burst); - nice_delay_ms(5 + BIKE_STROBE_ONTIME); - set_level(cfg.bike_flasher_brightness); - nice_delay_ms(65); - } - nice_delay_ms(720); // no return check necessary on final delay - set_level(0); -} -#endif - -#ifdef USE_CANDLE_MODE -#include "candle-mode.c" -#endif - - -#ifdef USE_BORING_STROBE_STATE -#include "ff-strobe-modes.c" -#endif - diff --git a/spaghetti-monster/anduril/strobe-modes.h b/spaghetti-monster/anduril/strobe-modes.h deleted file mode 100644 index 7dc1df4..0000000 --- a/spaghetti-monster/anduril/strobe-modes.h +++ /dev/null @@ -1,71 +0,0 @@ -// strobe-modes.h: Strobe modes for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_STROBE_STATE - -strobe_mode_te current_strobe_type; - -// which strobe mode is active? -#ifdef USE_CANDLE_MODE - #define DEFAULT_STROBE candle_mode_e -#else - #define DEFAULT_STROBE 0 -#endif - -#endif // ifdef USE_STROBE_STATE - - -// full FET strobe can be a bit much... use max regulated level instead, -// if there's a bright enough regulated level -#ifndef STROBE_BRIGHTNESS -#ifdef MAX_Nx7135 -#define STROBE_BRIGHTNESS MAX_Nx7135 -#else -#define STROBE_BRIGHTNESS MAX_LEVEL -#endif -#endif - -// some drivers need to keep the regulator chip on between pulses, -// so set this to 1 to keep the light on at moon mode between pulses, -// and thus keep the regulator powered up for the next flash -#ifndef STROBE_OFF_LEVEL -#define STROBE_OFF_LEVEL 0 -#endif - -// party and tactical strobes -#ifdef USE_STROBE_STATE -uint8_t strobe_state(Event event, uint16_t arg); -inline void strobe_state_iter(); -#endif - -#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) -inline void party_tactical_strobe_mode_iter(uint8_t st); -#endif - -#ifdef USE_POLICE_COLOR_STROBE_MODE -inline void police_color_strobe_iter(); -#endif - -#ifdef USE_LIGHTNING_MODE -inline void lightning_storm_iter(); -#endif - -// bike mode config options -#ifdef USE_BIKE_FLASHER_MODE -#define MAX_BIKING_LEVEL 120 // should be 127 or less -inline void bike_flasher_iter(); -#endif - -#ifdef USE_CANDLE_MODE -#include "candle-mode.h" -#endif - - -#if defined(USE_POLICE_STROBE_MODE) || defined(USE_SOS_MODE_IN_FF_GROUP) -#define USE_BORING_STROBE_STATE -#include "ff-strobe-modes.h" -#endif - diff --git a/spaghetti-monster/anduril/sunset-timer.c b/spaghetti-monster/anduril/sunset-timer.c deleted file mode 100644 index e4fc512..0000000 --- a/spaghetti-monster/anduril/sunset-timer.c +++ /dev/null @@ -1,60 +0,0 @@ -// sunset-timer.c: Sunset / candle auto-shutoff functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "sunset-timer.h" - -uint8_t sunset_timer_state(Event event, uint16_t arg) { - - #if defined(USE_SIMPLE_UI) && !defined(USE_EXTENDED_SIMPLE_UI) - // No timer functions in Simple UI - if (cfg.simple_ui_active) return EVENT_NOT_HANDLED; - #endif - - // reset on start - if (event == EV_enter_state) { - sunset_timer = 0; - sunset_ticks = 0; - return EVENT_HANDLED; - } - // hold: maybe "bump" the timer if it's active and almost expired - else if (event == EV_hold) { - // ramping up should "bump" the timer to extend the deadline a bit - if ((sunset_timer > 0) && (sunset_timer < 4)) { - sunset_timer = 3; // 3 minutes - sunset_timer_peak = 3; - sunset_ticks = 0; // re-start current "minute" - } - } - // 5H: add 5m to timer, per second, until released - else if (event == EV_click5_hold) { - if (0 == (arg % TICKS_PER_SECOND)) { - if (sunset_timer < (255 - SUNSET_TIMER_UNIT)) { - // add a few minutes to the timer - sunset_timer += SUNSET_TIMER_UNIT; - sunset_timer_peak = sunset_timer; // reset ceiling - sunset_ticks = 0; // reset phase - // let the user know something happened - blink_once(); - } - } - return EVENT_HANDLED; - } - // tick: count down until time expires - else if (event == EV_tick) { - // time passed - sunset_ticks ++; - // did we reach a minute mark? - if (sunset_ticks >= TICKS_PER_MINUTE) { - sunset_ticks = 0; - if (sunset_timer > 0) { - sunset_timer --; - } - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/sunset-timer.h b/spaghetti-monster/anduril/sunset-timer.h deleted file mode 100644 index 963804e..0000000 --- a/spaghetti-monster/anduril/sunset-timer.h +++ /dev/null @@ -1,17 +0,0 @@ -// sunset-timer.h: Sunset / candle auto-shutoff functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// how many minutes to add each time the user "bumps" the timer? -#define SUNSET_TIMER_UNIT 5 - -#define TICKS_PER_MINUTE (TICKS_PER_SECOND*60) - -// automatic shutoff timer -uint8_t sunset_timer = 0; // minutes remaining in countdown -uint8_t sunset_timer_peak = 0; // total minutes in countdown -uint16_t sunset_ticks = 0; // counts from 0 to TICKS_PER_MINUTE, then repeats -uint8_t sunset_timer_state(Event event, uint16_t arg); - diff --git a/spaghetti-monster/anduril/tactical-mode.c b/spaghetti-monster/anduril/tactical-mode.c deleted file mode 100644 index 0035496..0000000 --- a/spaghetti-monster/anduril/tactical-mode.c +++ /dev/null @@ -1,109 +0,0 @@ -// tactical-mode.c: Tactical (ish) mode for Anduril. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "tactical-mode.h" - - -uint8_t tactical_state(Event event, uint16_t arg) { - // momentary(ish) tactical mode - uint8_t mem_lvl = memorized_level; // save this to restore it later - uint8_t ret = EVENT_NOT_HANDLED; - - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - // 1H: 1st level - // 2H: 2nd level - // 3H: 3rd level - // 4+: nothing - momentary_active = 0; - ret = EVENT_HANDLED; - uint8_t click = event & 0x0f; // click number - if (click <= 3) { - momentary_active = 1; - uint8_t lvl; - lvl = cfg.tactical_levels[click-1]; - if ((1 <= lvl) && (lvl <= RAMP_SIZE)) { // steady output - memorized_level = lvl; - momentary_mode = 0; - #if NUM_CHANNEL_MODES > 1 - // use ramp mode's channel - channel_mode = cfg.channel_mode; - #endif - } else { // momentary strobe mode - momentary_mode = 1; - if (lvl > RAMP_SIZE) { - current_strobe_type = (lvl - RAMP_SIZE - 1) % strobe_mode_END; - } - } - } - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - momentary_active = 0; - set_level(0); - interrupt_nice_delays(); // stop animations in progress - } - - // delegate to momentary mode while button is pressed - if (momentary_active) { - momentary_state(event, arg); - } - - memorized_level = mem_lvl; // restore temporarily overridden mem level - - // copy lockout mode's aux LED and sleep behaviors - if (event == EV_enter_state) { - lockout_state(event, arg); - } - else if (event == EV_tick) { - if (! momentary_active) { - return lockout_state(event, arg); - } - return EVENT_HANDLED; - } - else if (event == EV_sleep_tick) { - return lockout_state(event, arg); - } - - // 6 clicks: exit and turn off - else if (event == EV_6clicks) { - blink_once(); - set_state(off_state, 0); - return EVENT_HANDLED; - } - - ////////// Every action below here is blocked in the simple UI ////////// - // (unnecessary since this entire mode is blocked in simple UI) - /* - #ifdef USE_SIMPLE_UI - if (cfg.simple_ui_active) { - return EVENT_NOT_HANDLED; - } - #endif - */ - - // 7H: configure tactical mode - else if (event == EV_click7_hold) { - push_state(tactical_config_state, 0); - return EVENT_HANDLED; - } - - return ret; -} - -void tactical_config_save(uint8_t step, uint8_t value) { - // update tac mode values - // 3 values - // each value is 1 to 150, or other: - // - 1..150 is a ramp level - // - other means "strobe mode" - cfg.tactical_levels[step - 1] = value; -} - -uint8_t tactical_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, 3, tactical_config_save); -} - diff --git a/spaghetti-monster/anduril/tactical-mode.h b/spaghetti-monster/anduril/tactical-mode.h deleted file mode 100644 index 528a796..0000000 --- a/spaghetti-monster/anduril/tactical-mode.h +++ /dev/null @@ -1,22 +0,0 @@ -// tactical-mode.h: Tactical mode for Anduril. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifndef TACTICAL_LEVELS - // high, low, tactical strobe - // only do color strobe here if it's main LEDs, not aux LEDs - #if defined(USE_POLICE_COLOR_STROBE_MODE) && !defined(POLICE_STROBE_USES_AUX) - // 2-color police style strobe - #define TACTICAL_LEVELS 120,30,(RAMP_SIZE+3) - #else - // regular tactical strobe (1 color) - #define TACTICAL_LEVELS 120,30,(RAMP_SIZE+2) - #endif -#endif - -// tactical(ish) mode -uint8_t tactical_state(Event event, uint16_t arg); -uint8_t tactical_config_state(Event event, uint16_t arg); - diff --git a/spaghetti-monster/anduril/tempcheck-mode.c b/spaghetti-monster/anduril/tempcheck-mode.c deleted file mode 100644 index 5d160bd..0000000 --- a/spaghetti-monster/anduril/tempcheck-mode.c +++ /dev/null @@ -1,56 +0,0 @@ -// tempcheck-mode.c: Temperature check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "tempcheck-mode.h" - -uint8_t tempcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: next blinky mode - else if (event == EV_2clicks) { - #if defined(USE_BEACON_MODE) - set_state(beacon_state, 0); - #elif defined(USE_SOS_MODE) && defined(USE_SOS_MODE_IN_BLINKY_GROUP) - set_state(sos_state, 0); - #elif defined(USE_BATTCHECK) - set_state(battcheck_state, 0); - #endif - return EVENT_HANDLED; - } - // 7H: thermal config mode - else if (event == EV_click7_hold) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -void thermal_config_save(uint8_t step, uint8_t value) { - if (value) { - // item 1: calibrate room temperature - if (step == 1) { - int8_t rawtemp = temperature - cfg.therm_cal_offset; - cfg.therm_cal_offset = value - rawtemp; - adc_reset = 2; // invalidate all recent temperature data - } - - // item 2: set maximum heat limit - else { - cfg.therm_ceil = 30 + value - 1; - } - } - - if (cfg.therm_ceil > MAX_THERM_CEIL) cfg.therm_ceil = MAX_THERM_CEIL; -} - -uint8_t thermal_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 2, thermal_config_save); -} - diff --git a/spaghetti-monster/anduril/tempcheck-mode.h b/spaghetti-monster/anduril/tempcheck-mode.h deleted file mode 100644 index 15dd03e..0000000 --- a/spaghetti-monster/anduril/tempcheck-mode.h +++ /dev/null @@ -1,12 +0,0 @@ -// tempcheck-mode.h: Temperature check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#define USE_BLINK_NUM // FIXME: this only matters in an earlier header - -uint8_t tempcheck_state(Event event, uint16_t arg); -uint8_t thermal_config_state(Event event, uint16_t arg); -void thermal_config_save(uint8_t step, uint8_t value); - diff --git a/spaghetti-monster/anduril/tint-ramping.c b/spaghetti-monster/anduril/tint-ramping.c deleted file mode 100644 index 9418113..0000000 --- a/spaghetti-monster/anduril/tint-ramping.c +++ /dev/null @@ -1,86 +0,0 @@ -// tint-ramping.c: Tint ramping functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "tint-ramping.h" - -uint8_t tint_ramping_state(Event event, uint16_t arg) { - static int8_t tint_ramp_direction = 1; - static uint8_t prev_tint = 0; - // don't activate auto-tint modes unless the user hits the edge - // and keeps pressing for a while - static uint8_t past_edge_counter = 0; - // bugfix: click-click-hold from off to strobes would invoke tint ramping - // in addition to changing state... so ignore any tint-ramp events which - // don't look like they were meant to be here - static uint8_t active = 0; - - // click, click, hold: change the tint - if (event == EV_click3_hold) { - ///// tint-toggle mode - // toggle once on first frame; ignore other frames - if (tint_style) { - // only respond on first frame - if (arg) return EVENT_NOT_HANDLED; - - // force tint to be 1 or 254 - if (tint != 254) { tint = 1; } - // invert between 1 and 254 - tint = tint ^ 0xFF; - set_level(actual_level); - return EVENT_HANDLED; - } - - ///// smooth tint-ramp mode - // reset at beginning of movement - if (! arg) { - active = 1; // first frame means this is for us - past_edge_counter = 0; // doesn't start until user hits the edge - } - // ignore event if we weren't the ones who handled the first frame - if (! active) return EVENT_HANDLED; - - // change normal tints - if ((tint_ramp_direction > 0) && (tint < 254)) { - tint += 1; - } - else if ((tint_ramp_direction < 0) && (tint > 1)) { - tint -= 1; - } - // if the user kept pressing long enough, go the final step - if (past_edge_counter == 64) { - past_edge_counter ++; - tint ^= 1; // 0 -> 1, 254 -> 255 - blip(); - } - // if tint change stalled, let user know we hit the edge - else if (prev_tint == tint) { - if (past_edge_counter == 0) blip(); - // count up but don't wrap back to zero - if (past_edge_counter < 255) past_edge_counter ++; - } - prev_tint = tint; - set_level(actual_level); - return EVENT_HANDLED; - } - - // click, click, hold, release: reverse direction for next ramp - else if (event == EV_click3_hold_release) { - active = 0; // ignore next hold if it wasn't meant for us - // reverse - tint_ramp_direction = -tint_ramp_direction; - if (tint <= 1) tint_ramp_direction = 1; - else if (tint >= 254) tint_ramp_direction = -1; - // remember tint after battery change - save_config(); - // bug?: for some reason, brightness can seemingly change - // from 1/150 to 2/150 without this next line... not sure why - set_level(actual_level); - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - diff --git a/spaghetti-monster/anduril/tint-ramping.h b/spaghetti-monster/anduril/tint-ramping.h deleted file mode 100644 index 19b8dde..0000000 --- a/spaghetti-monster/anduril/tint-ramping.h +++ /dev/null @@ -1,21 +0,0 @@ -// tint-ramping.h: Tint ramping functions for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// 0: smooth tint ramp -// 1: toggle tint only between two extremes -#ifdef TINT_RAMP_TOGGLE_ONLY -uint8_t tint_style = 1; -#else -uint8_t tint_style = 0; -#endif - -#ifdef USE_MANUAL_MEMORY -uint8_t manual_memory_tint; -#endif - -// not actually a mode, more of a fallback under other modes -uint8_t tint_ramping_state(Event event, uint16_t arg); - diff --git a/spaghetti-monster/anduril/version-check-mode.c b/spaghetti-monster/anduril/version-check-mode.c deleted file mode 100644 index a47706f..0000000 --- a/spaghetti-monster/anduril/version-check-mode.c +++ /dev/null @@ -1,31 +0,0 @@ -// version-check-mode.c: Version check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "version-check-mode.h" - -// empty state; logic is handled in FSM loop() instead -uint8_t version_check_state(Event event, uint16_t arg) { - return EVENT_NOT_HANDLED; -} - -// this happens in FSM loop() -inline void version_check_iter() { - for (uint8_t i=0; i<sizeof(version_number)-1; i++) { - uint8_t digit = pgm_read_byte(version_number + i) - '0'; - if (digit < 10) blink_digit(digit); - else { // "buzz" for non-numeric characters - for(uint8_t frame=0; frame<25; frame++) { - set_level((frame&1) << 5); - nice_delay_ms(16); - } - nice_delay_ms(BLINK_SPEED * 8 / 12); - } - nice_delay_ms(300); - } - - set_state_deferred(off_state, 0); -} - diff --git a/spaghetti-monster/anduril/version-check-mode.h b/spaghetti-monster/anduril/version-check-mode.h deleted file mode 100644 index 72bad3f..0000000 --- a/spaghetti-monster/anduril/version-check-mode.h +++ /dev/null @@ -1,19 +0,0 @@ -// version-check-mode.h: Version check mode for Anduril. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#define USE_BLINK_DIGIT // FIXME: does nothing unless defined earlier - -#ifndef MODEL_NUMBER -// if no model number, it's a build error -//#define MODEL_NUMBER "0000" -#error MODEL_NUMBER undefined -#endif - -#include "version.h" -const PROGMEM uint8_t version_number[] = MODEL_NUMBER "." VERSION_NUMBER; -uint8_t version_check_state(Event event, uint16_t arg); -inline void version_check_iter(); - diff --git a/spaghetti-monster/anduril/version.h b/spaghetti-monster/anduril/version.h deleted file mode 100644 index b548e13..0000000 --- a/spaghetti-monster/anduril/version.h +++ /dev/null @@ -1,4 +0,0 @@ -// this file is replaced automatically by the build script -// set your own date here if you're not using the build script -// otherwise, default to first human contact with the moon -#define VERSION_NUMBER "1969-07-20" diff --git a/spaghetti-monster/anduril/wurkkos-cfg.h b/spaghetti-monster/anduril/wurkkos-cfg.h deleted file mode 100644 index b9992fb..0000000 --- a/spaghetti-monster/anduril/wurkkos-cfg.h +++ /dev/null @@ -1,26 +0,0 @@ -// Wurkkos config options for Anduril -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -// allow Aux Config and Strobe Modes in Simple UI -#define USE_EXTENDED_SIMPLE_UI - -// Allow 3C in Simple UI for switching between smooth and stepped ramping -#define USE_SIMPLE_UI_RAMPING_TOGGLE - -// enable 2 click turbo (Anduril 1 style) -#define DEFAULT_2C_STYLE 1 - -// enable SOS in the blinkies group -#define USE_SOS_MODE -#define USE_SOS_MODE_IN_BLINKY_GROUP - -// enable factory reset on 13H without loosening tailcap -// only really needed on TS10, but doesn't hurt on other models -#define USE_SOFT_FACTORY_RESET - -// higher temperature limit because attiny1616 is more accurate -#undef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 50 - diff --git a/spaghetti-monster/baton/baton.c b/spaghetti-monster/baton/baton.c deleted file mode 100644 index e672755..0000000 --- a/spaghetti-monster/baton/baton.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Baton: Olight Baton-like UI for SpaghettiMonster. - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "hwdef-Emisar_D4.h" -#define USE_LVP -#define USE_THERMAL_REGULATION -#define USE_DELAY_MS -#include "spaghetti-monster.h" - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -uint8_t steady_state(Event event, uint16_t arg); -uint8_t lockout_state(Event event, uint16_t arg); - -// brightness control -uint8_t memorized_level = 1; -uint8_t actual_level = 0; -#ifdef USE_THERMAL_REGULATION -uint8_t target_level = 0; -#endif - -// moon + ../../bin/level_calc.py 2 6 7135 18 10 150 FET 1 10 1500 -uint8_t pwm1_levels[] = { 3, 18, 110, 255, 255, 255, 0, }; -uint8_t pwm2_levels[] = { 0, 0, 0, 9, 58, 138, 255, }; -#define MAX_LEVEL (sizeof(pwm1_levels)-1) - -// set LED brightness -void set_level(uint8_t lvl) { - actual_level = lvl; - PWM1_LVL = pwm1_levels[lvl]; - PWM2_LVL = pwm2_levels[lvl]; -} - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - go_to_standby = 1; // sleep while off (lower power use) - return EVENT_HANDLED; - } - // hold (initially): go to lowest level, but allow abort for regular click - else if (event == EV_click1_press) { - set_level(0); - return EVENT_HANDLED; - } - // hold (longer): go to lowest level - else if (event == EV_click1_hold) { - set_state(steady_state, 0); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - set_level(memorized_level); - return EVENT_HANDLED; - } - // 1 click: regular mode - else if (event == EV_1click) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // 2 clicks: highest mode - else if (event == EV_2clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 4 clicks: soft lockout - else if (event == EV_4clicks) { - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -uint8_t steady_state(Event event, uint16_t arg) { - // turn LED on when we first enter the mode - if (event == EV_enter_state) { - // remember this level, unless it's moon or turbo - if ((arg > 0) && (arg < MAX_LEVEL)) memorized_level = arg; - // use the requested level even if not memorized - #ifdef USE_THERMAL_REGULATION - target_level = arg; - #endif - set_level(arg); - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: go to/from highest level - else if (event == EV_2clicks) { - if (actual_level < MAX_LEVEL) { // go to turbo - memorized_level = actual_level; // in case we're on moon - #ifdef USE_THERMAL_REGULATION - target_level = MAX_LEVEL; - #endif - set_level(MAX_LEVEL); - } - else { // return from turbo - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // hold: change brightness - else if (event == EV_click1_hold) { - if ((arg % HOLD_TIMEOUT) == 0) { - memorized_level = (actual_level+1) % (MAX_LEVEL+1); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - } - return EVENT_HANDLED; - } - #ifdef USE_THERMAL_REGULATION - // overheating: drop by 1 level - else if (event == EV_temperature_high) { - if (actual_level > 1) { set_level(actual_level - 1); } - return EVENT_HANDLED; - } - // underheating: increase by 1 level if we're lower than the target - else if (event == EV_temperature_low) { - if (actual_level < target_level) { set_level(actual_level + 1); } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - -uint8_t lockout_state(Event event, uint16_t arg) { - // stay asleep while locked - if (event == EV_tick) { - PWM1_LVL = 0; PWM2_LVL = 0; // make sure emitters are off - // sleep 1 second after user stops pressing buttons - if (arg > TICKS_PER_SECOND) { go_to_standby = 1; } - return EVENT_HANDLED; - } - // 4 clicks: exit, and turn on at "low" level - else if (event == EV_4clicks) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -void low_voltage() { - // step down by one level or turn off - if (actual_level > 0) { - set_level(actual_level - 1); - #ifdef USE_THERMAL_REGULATION - target_level = actual_level; // don't let low temperature override LVP - #endif - } - else { - set_state(off_state, 0); - } -} - -void setup() { - // blink when power is connected - set_level(MAX_LEVEL/2); - delay_ms(10); - set_level(0); - - push_state(off_state, 0); -} - -void loop() { -} diff --git a/spaghetti-monster/baton/baton.txt b/spaghetti-monster/baton/baton.txt deleted file mode 100644 index 2f0c22f..0000000 --- a/spaghetti-monster/baton/baton.txt +++ /dev/null @@ -1,21 +0,0 @@ -This is a very simple clone of the Olight Baton interface. It is not -exact, but it has the basics. Mostly, it exists for the purposes of -demonstrating how to create interfaces in FSM. - -While off: - - - 1 click: Turn on (at memorized level). - - Hold: Turn on (at moon level). - - 2 clicks: Turn on (at highest level). - - 4 clicks: Soft lockout mode. - -While on: - - - 1 click: Turn off. - - Hold: Change the brightness. Goes up in steps, then wraps around. - - 2 clicks: Go to/from highest level. - -While locked: - - - 4 clicks: Exit lockout mode. - diff --git a/spaghetti-monster/chan-aux.c b/spaghetti-monster/chan-aux.c deleted file mode 100644 index e04e6a2..0000000 --- a/spaghetti-monster/chan-aux.c +++ /dev/null @@ -1,11 +0,0 @@ -// channel modes for single color aux LEDs -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -void set_level_aux(uint8_t level) { - indicator_led(!(!(level)) << 1); // high (or off) -} - -bool gradual_tick_null(uint8_t gt) { return true; } // do nothing - diff --git a/spaghetti-monster/chan-aux.h b/spaghetti-monster/chan-aux.h deleted file mode 100644 index ff599b8..0000000 --- a/spaghetti-monster/chan-aux.h +++ /dev/null @@ -1,25 +0,0 @@ -// channel modes for single color aux LEDs -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define NUM_AUX_CHANNEL_MODES 1 - -// include / exclude field based on compile options -#ifdef USE_CHANNEL_MODE_ARGS - #define AUX_HAS_ARGS , .has_args = 0 -#else - #define AUX_HAS_ARGS -#endif - -#define AUX_CHANNELS \ - { \ - .set_level = set_level_aux, \ - .gradual_tick = gradual_tick_null \ - AUX_HAS_ARGS \ - } - -void set_level_aux(uint8_t level); - -bool gradual_tick_null(uint8_t gt); - diff --git a/spaghetti-monster/chan-rgbaux.c b/spaghetti-monster/chan-rgbaux.c deleted file mode 100644 index 19d18a6..0000000 --- a/spaghetti-monster/chan-rgbaux.c +++ /dev/null @@ -1,35 +0,0 @@ -// channel modes for RGB aux LEDs -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -void set_level_auxred(uint8_t level) { - rgb_led_set(!(!(level)) * 0b000010); // red, high (or off) -} - -void set_level_auxyel(uint8_t level) { - rgb_led_set(!(!(level)) * 0b001010); // red+green, high (or off) -} - -void set_level_auxgrn(uint8_t level) { - rgb_led_set(!(!(level)) * 0b001000); // green, high (or off) -} - -void set_level_auxcyn(uint8_t level) { - rgb_led_set(!(!(level)) * 0b101000); // green+blue, high (or off) -} - -void set_level_auxblu(uint8_t level) { - rgb_led_set(!(!(level)) * 0b100000); // blue, high (or off) -} - -void set_level_auxprp(uint8_t level) { - rgb_led_set(!(!(level)) * 0b100010); // red+blue, high (or off) -} - -void set_level_auxwht(uint8_t level) { - rgb_led_set(!(!(level)) * 0b101010); // red+green+blue, high (or off) -} - -bool gradual_tick_null(uint8_t gt) { return true; } // do nothing - diff --git a/spaghetti-monster/chan-rgbaux.h b/spaghetti-monster/chan-rgbaux.h deleted file mode 100644 index 6ef5d89..0000000 --- a/spaghetti-monster/chan-rgbaux.h +++ /dev/null @@ -1,72 +0,0 @@ -// channel modes for RGB aux LEDs -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later -#pragma once - -#define RGB_AUX_ENUMS \ - CM_AUXRED, \ - CM_AUXYEL, \ - CM_AUXGRN, \ - CM_AUXCYN, \ - CM_AUXBLU, \ - CM_AUXPRP, \ - CM_AUXWHT - -#define RGB_AUX_CM_ARGS 0,0,0,0,0,0,0 - -#define NUM_RGB_AUX_CHANNEL_MODES 7 - -// include / exclude field based on compile options -#ifdef USE_CHANNEL_MODE_ARGS - #define AUX_RGB_HAS_ARGS , .has_args = 0 -#else - #define AUX_RGB_HAS_ARGS -#endif - -#define RGB_AUX_CHANNELS \ - { \ - .set_level = set_level_auxred, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxyel, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxgrn, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxcyn, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxblu, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxprp, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - }, \ - { \ - .set_level = set_level_auxwht, \ - .gradual_tick = gradual_tick_null \ - AUX_RGB_HAS_ARGS \ - } - -void set_level_auxred(uint8_t level); -void set_level_auxyel(uint8_t level); -void set_level_auxgrn(uint8_t level); -void set_level_auxcyn(uint8_t level); -void set_level_auxblu(uint8_t level); -void set_level_auxprp(uint8_t level); -void set_level_auxwht(uint8_t level); - -bool gradual_tick_null(uint8_t gt); - diff --git a/spaghetti-monster/darkhorse/darkhorse.c b/spaghetti-monster/darkhorse/darkhorse.c deleted file mode 100644 index aa37b92..0000000 --- a/spaghetti-monster/darkhorse/darkhorse.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * DarkHorse: Improved ZebraLight clone UI for SpaghettiMonster. - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "hwdef-Emisar_D4.h" -#define USE_LVP -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 -#define USE_RAMPING -#define RAMP_LENGTH 150 -#define USE_BATTCHECK -#define BATTCHECK_4bars -#define DONT_DELAY_AFTER_BATTCHECK -#define USE_EEPROM -#define EEPROM_BYTES 5 -#include "spaghetti-monster.h" - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -uint8_t low_mode_state(Event event, uint16_t arg); -uint8_t med_mode_state(Event event, uint16_t arg); -uint8_t hi_mode_state(Event event, uint16_t arg); -uint8_t strobe_beacon_state(Event event, uint16_t arg); -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg); -#endif -// Not a FSM state, just handles stuff common to all low/med/hi states -uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes); - -void load_config(); -void save_config(); - -// toggle between L1/L2, M1/M2, H1/H2 -uint8_t L1 = 1; -uint8_t M1 = 1; -uint8_t H1 = 1; -// brightness for L2, M2, H2 (valid range 1 to 3 inclusive) -uint8_t L2 = 1; -uint8_t M2 = 1; -uint8_t H2 = 1; -// mode groups, ish -uint8_t low_modes[] = {12, 3, 5, 9}; // 3.3 lm, 2.0 lm, 0.8 lm, 0.3 lm -uint8_t med_modes[] = {56, 21, 29, 37}; // 101 lm, 35 lm, 20 lm, 10 lm -uint8_t hi_modes[] = {MAX_LEVEL, 81, 96, 113}; // 1500 lm, 678 lm, 430 lm, 270 lm -// strobe/beacon modes: -// 0: 0.2 Hz beacon at L1 -// 1: 0.2 Hz beacon at H1 -// 2: 4 Hz strobe at H1 -// 3: 19 Hz strobe at H1 -uint8_t strobe_beacon_mode = 0; - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - -void set_any_mode(uint8_t primary, uint8_t secondary, uint8_t *modes) { - // primary (H1/M1/L1) - if (primary) { - set_level(modes[0]); - } - // secondary (H2/M2/L2) - else { - set_level(modes[secondary]); - } - #ifdef USE_THERMAL_REGULATION - target_level = actual_level; - #endif -} - -inline void set_low_mode() { set_any_mode(L1, L2, low_modes); } -inline void set_med_mode() { set_any_mode(M1, M2, med_modes); } -inline void set_hi_mode() { set_any_mode(H1, H2, hi_modes); } - - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - set_level(0); - // sleep while off (lower power use) - go_to_standby = 1; - return EVENT_HANDLED; - } - // hold (initially): go to lowest level, but allow abort for regular click - else if (event == EV_click1_press) { - set_low_mode(); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to high level, but allow abort for double click - else if (event == EV_click1_release) { - set_hi_mode(); - return EVENT_HANDLED; - } - // 1 click: high mode - else if (event == EV_1click) { - set_state(hi_mode_state, 0); - return EVENT_HANDLED; - } - // click, press (initially): go to medium mode, but allow abort - else if (event == EV_click2_press) { - set_med_mode(); - return EVENT_HANDLED; - } - // 2 clicks: medium mode - else if (event == EV_2clicks) { - set_state(med_mode_state, 0); - return EVENT_HANDLED; - } - // click, click, press (initially): light off, prep for blinkies - else if (event == EV_click3_press) { - set_level(0); - return EVENT_HANDLED; - } - // 3 clicks: strobe mode - else if (event == EV_3clicks) { - set_state(strobe_beacon_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_BATTCHECK - // 4 clicks: battcheck mode - else if (event == EV_4clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // hold: go to low mode, but allow ramping up - else if (event == EV_click1_hold) { - // don't start ramping immediately; - // give the user time to release at low mode - if (arg >= HOLD_TIMEOUT) - set_state(low_mode_state, 0); - return EVENT_HANDLED; - } - // hold, release quickly: go to low mode - else if (event == EV_click1_hold_release) { - set_state(low_mode_state, 0); - return EVENT_HANDLED; - } - /* TODO: implement - // click-release-hold: discrete ramp through all levels - else if (event == EV_click2_hold) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - */ - return EVENT_NOT_HANDLED; -} - - -uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes) { - // turn on LED when entering the mode - if (event == EV_enter_state) { - set_any_mode(*primary, *secondary, modes); - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // hold: change brightness (low, med, hi, always starting at low) - else if (event == EV_click1_hold) { - uint8_t which = arg % (HOLD_TIMEOUT * 3) / HOLD_TIMEOUT; - switch(which) { - case 0: - set_state(low_mode_state, 0); - break; - case 1: - set_state(med_mode_state, 0); - break; - case 2: - set_state(hi_mode_state, 0); - break; - } - return EVENT_HANDLED; - } - // 2 clicks: toggle primary/secondary level - else if (event == EV_2clicks) { - *primary ^= 1; - set_any_mode(*primary, *secondary, modes); - save_config(); - return EVENT_HANDLED; - } - // click-release-hold: change secondary level - else if (event == EV_click2_hold) { - if (arg % HOLD_TIMEOUT == 0) { - *secondary = (*secondary + 1) & 3; - if (! *secondary) *secondary = 1; - *primary = 0; - set_any_mode(*primary, *secondary, modes); - } - return EVENT_HANDLED; - } - // click, hold, release: save secondary level - else if (event == EV_click2_hold_release) { - save_config(); - } - #ifdef USE_THERMAL_REGULATION - // TODO: test this on a real light - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - if (actual_level > MAX_LEVEL/4) { - uint8_t stepdown = actual_level - arg; - if (stepdown < MAX_LEVEL/4) stepdown = MAX_LEVEL/4; - set_level(stepdown); - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - if (actual_level < target_level) { - uint8_t stepup = actual_level + (arg>>1); - if (stepup > target_level) stepup = target_level; - set_level(stepup); - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - -uint8_t low_mode_state(Event event, uint16_t arg) { - return any_mode_state(event, arg, &L1, &L2, low_modes); -} - -uint8_t med_mode_state(Event event, uint16_t arg) { - return any_mode_state(event, arg, &M1, &M2, med_modes); -} - -uint8_t hi_mode_state(Event event, uint16_t arg) { - return any_mode_state(event, arg, &H1, &H2, hi_modes); -} - - -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg) { - return EVENT_NOT_HANDLED; -} -#endif - - -uint8_t strobe_beacon_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 1 click (initially): cancel current blink - // FIXME: this is no longer necessary; FSM does this automatically now - if (event == EV_click1_release) { - interrupt_nice_delays(); - return EVENT_HANDLED; - } - // 2 clicks: rotate through blinky modes - else if (event == EV_2clicks) { - strobe_beacon_mode = (strobe_beacon_mode + 1) & 3; - save_config(); - interrupt_nice_delays(); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -void low_voltage() { - if (current_state == hi_mode_state) { - set_state(med_mode_state, 0); - } - else if (current_state == med_mode_state) { - set_state(low_mode_state, 0); - } - else if (current_state == low_mode_state) { - set_state(off_state, 0); - } - // "step down" from blinkies to low - else if (current_state == strobe_beacon_state) { - set_state(low_mode_state, 0); - } -} - -void strobe(uint8_t level, uint16_t ontime, uint16_t offtime) { - set_level(level); - if (! nice_delay_ms(ontime)) return; - set_level(0); - nice_delay_ms(offtime); -} - -void load_config() { - if (load_eeprom()) { - H1 = !(!(eeprom[0] & 0b00000100)); - M1 = !(!(eeprom[0] & 0b00000010)); - L1 = !(!(eeprom[0] & 0b00000001)); - H2 = eeprom[1]; - M2 = eeprom[2]; - L2 = eeprom[3]; - strobe_beacon_mode = eeprom[4]; - } -} - -void save_config() { - eeprom[0] = (H1<<2) | (M1<<1) | (L1); - eeprom[1] = H2; - eeprom[2] = M2; - eeprom[3] = L2; - eeprom[4] = strobe_beacon_mode; - - save_eeprom(); -} - -void setup() { - set_level(RAMP_SIZE/8); - delay_4ms(3); - set_level(0); - - load_config(); - - push_state(off_state, 0); -} - -void loop() { - if (current_state == strobe_beacon_state) { - switch(strobe_beacon_mode) { - // 0.2 Hz beacon at L1 - case 0: - strobe(low_modes[0], 500, 4500); - break; - // 0.2 Hz beacon at H1 - case 1: - strobe(hi_modes[0], 500, 4500); - break; - // 4 Hz tactical strobe at H1 - case 2: - strobe(hi_modes[0], 83, 167); - break; - // 19 Hz tactical strobe at H1 - case 3: - strobe(hi_modes[0], 17, 35); - break; - } - } - - #ifdef USE_BATTCHECK - else if (current_state == battcheck_state) { - nice_delay_ms(500); // wait a moment to measure voltage - battcheck(); - set_state(off_state, 0); - } - #endif -} - - diff --git a/spaghetti-monster/fireflies-ui/Makefile b/spaghetti-monster/fireflies-ui/Makefile deleted file mode 100644 index 0b59898..0000000 --- a/spaghetti-monster/fireflies-ui/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: - ./build-all.sh - -clean: - rm -f *.hex cfg-ff-[pr]*.h *~ *.elf *.o - -.phony: clean diff --git a/spaghetti-monster/fireflies-ui/build-all.sh b/spaghetti-monster/fireflies-ui/build-all.sh deleted file mode 100755 index 81ebd97..0000000 --- a/spaghetti-monster/fireflies-ui/build-all.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -cp -av --no-clobber ../anduril/cfg-ff*.h . - -UI=fireflies-ui - -for TARGET in cfg-*.h ; do - NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";') - echo "===== $NAME =====" - echo ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" - ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" - mv -f "$UI".hex "$UI".$NAME.hex -done diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-e01.h b/spaghetti-monster/fireflies-ui/cfg-ff-e01.h deleted file mode 100644 index 42c23b2..0000000 --- a/spaghetti-monster/fireflies-ui/cfg-ff-e01.h +++ /dev/null @@ -1,44 +0,0 @@ -// Fireflies EDC thrower config options for Fireflies UI -// (uses PL47 driver) -#include "hwdef-FF_PL47.h" - -// disable indicator LED; it's hardwired -#ifdef USE_INDICATOR_LED -#undef USE_INDICATOR_LED -#endif - -// don't do this -#undef BLINK_AT_RAMP_MIDDLE -#undef BLINK_AT_RAMP_CEILING - -// ramp shape and size -#define RAMP_LENGTH 150 - -// driver is a FET + 3x7135, ~413 lm at highest regulated level -// ../../../bin/level_calc.py seventh 2 150 7135 1 12 414 FET 2 10 1930 -#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,10,10,11,12,13,14,15,15,16,17,18,20,21,22,23,24,26,27,28,30,31,33,34,36,38,39,41,43,45,47,49,51,53,56,58,60,63,65,68,71,74,77,80,83,86,89,93,96,100,103,107,111,115,119,124,128,132,137,142,147,152,157,163,168,174,180,186,192,198,204,211,218,225,232,240,247,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0 -#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,7,9,12,14,16,19,22,24,27,30,33,36,39,42,45,48,52,55,58,62,66,69,73,77,81,85,90,94,98,103,107,112,117,122,127,132,137,143,148,154,160,166,172,178,184,191,197,204,211,218,225,232,240,247,255 -#define MAX_1x7135 93 -#define HALFSPEED_LEVEL 14 -#define QUARTERSPEED_LEVEL 7 - -#define MIN_THERM_STEPDOWN 65 // lowest value it'll step down to - - -// ceiling is level 130/150 (50% power) -#define RAMP_SMOOTH_FLOOR 1 -#define RAMP_SMOOTH_CEIL 130 - -// 20, 56, [93], 130 (93 is highest regulated) -// (8 / 102 / 413 / 1163 + 1930 lm) -#define RAMP_DISCRETE_FLOOR 20 -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#define RAMP_DISCRETE_STEPS 4 - -// ~25 lm to ~400 lm -#define MUGGLE_FLOOR 30 -#define MUGGLE_CEILING MAX_1x7135 - -// throttle back faster when high -#define THERM_FASTER_LEVEL 130 - diff --git a/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h b/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h deleted file mode 100644 index 48f9c15..0000000 --- a/spaghetti-monster/fireflies-ui/cfg-ff-e07-2.h +++ /dev/null @@ -1,27 +0,0 @@ -// Fireflies E07-2 config options for Anduril / FFUI -// mostly the same as PL47 -#include "cfg-ff-pl47.h" - -// ceiling is level 130/150 (50% power) -#undef RAMP_SMOOTH_CEIL -#define RAMP_SMOOTH_CEIL 130 - -// 20, 56, 93, 130 (83 is highest regulated) -// (requested config is 1%, 5%, 25%, 50%, double-click-turbo) -// (but this doesn't allow us to hit level 83) -#undef RAMP_DISCRETE_FLOOR -#define RAMP_DISCRETE_FLOOR 20 -#undef RAMP_DISCRETE_CEIL -#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#undef RAMP_DISCRETE_STEPS -#define RAMP_DISCRETE_STEPS 4 - -// regulate down faster when the FET is active, slower otherwise -#undef THERM_FASTER_LEVEL -#define THERM_FASTER_LEVEL 130 // throttle back faster when high - -// play it safe, don't try to regulate above the recommended safe level -#ifndef THERM_HARD_TURBO_DROP -#define THERM_HARD_TURBO_DROP -#endif - diff --git a/spaghetti-monster/fireflies-ui/fireflies-ui.c b/spaghetti-monster/fireflies-ui/fireflies-ui.c deleted file mode 100644 index 34f8293..0000000 --- a/spaghetti-monster/fireflies-ui/fireflies-ui.c +++ /dev/null @@ -1,2386 +0,0 @@ -/* - * Fireflies UI: A custom UI for Fireflies-brand flashlights. - * (based on Anduril by ToyKeeper) - * - * Copyright (C) 2019 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/********* User-configurable options *********/ -// UI config file name (set it here or define it at the gcc command line) -//#define CONFIGFILE cfg-ff-pl47.h - -#define USE_LVP // FIXME: won't build when this option is turned off - -// parameters for this defined below or per-driver -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this - -// short blip when crossing from "click" to "hold" from off -// (helps the user hit moon mode exactly, instead of holding too long -// or too short) -#define MOON_TIMING_HINT -// short blips while ramping -#define BLINK_AT_RAMP_MIDDLE -//#define BLINK_AT_RAMP_FLOOR -#define BLINK_AT_RAMP_CEILING -//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode - -// ramp down via regular button hold if a ramp-up ended <1s ago -// ("hold, release, hold" ramps down instead of up) -#define USE_REVERSING - -// battery readout style (pick one) -#define BATTCHECK_VpT -//#define BATTCHECK_8bars // FIXME: breaks build -//#define BATTCHECK_4bars // FIXME: breaks build - -// enable/disable various strobe modes -#define USE_BIKE_FLASHER_MODE -#define USE_PARTY_STROBE_MODE -#define USE_TACTICAL_STROBE_MODE -#define USE_LIGHTNING_MODE -#define USE_CANDLE_MODE - -// enable sunset (goodnight) mode -#define USE_GOODNIGHT_MODE -#define GOODNIGHT_TIME 60 // minutes (approximately) -#define GOODNIGHT_LEVEL 24 // ~11 lm - -// enable beacon mode -#define USE_BEACON_MODE - -//Muggle mode for easy UI -#define USE_MUGGLE_MODE - -// make the ramps configurable by the user -#define USE_RAMP_CONFIG - -// boring strobes nobody really likes, but sometimes flashlight companies want -// (these replace the fun strobe group, -// so don't enable them at the same time as any of the above strobes) -//#define USE_POLICE_STROBE_MODE -//#define USE_SOS_MODE - -// dual-switch support (second switch is a tail clicky) -//#define START_AT_MEMORIZED_LEVEL - -/***** specific settings for known driver types *****/ -#include "tk.h" -#include incfile(CONFIGFILE) - -///// Fireflies-specific configuration -// disable ramp config -#ifdef USE_RAMP_CONFIG -#undef USE_RAMP_CONFIG -#endif - -// no muggle mode -#ifdef USE_MUGGLE_MODE -#undef USE_MUGGLE_MODE -#endif - -// turn off strobe mode entirely; we're replacing it -#ifdef USE_BIKE_FLASHER_MODE -#undef USE_BIKE_FLASHER_MODE -#endif -#ifdef USE_PARTY_STROBE_MODE -#undef USE_PARTY_STROBE_MODE -#endif -#ifdef USE_TACTICAL_STROBE_MODE -#undef USE_TACTICAL_STROBE_MODE -#endif -#ifdef USE_LIGHTNING_MODE -#undef USE_LIGHTNING_MODE -#endif -#ifdef USE_CANDLE_MODE -#undef USE_CANDLE_MODE -#endif - -// remove other blinkies too -#ifdef USE_GOODNIGHT_MODE -#undef USE_GOODNIGHT_MODE -#endif -#ifdef USE_BEACON_MODE -#undef USE_BEACON_MODE -#endif - -// use these strobes instead -#define USE_POLICE_STROBE_MODE -#define USE_SOS_MODE - -// thermal config mode on 10 clicks from off -#define USE_TENCLICK_THERMAL_CONFIG - -///// end Fireflies-specific configuration - -// thermal properties, if not defined per-driver -#ifndef MIN_THERM_STEPDOWN -#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to -#endif -#ifndef THERM_FASTER_LEVEL - #ifdef MAX_Nx7135 - #define THERM_FASTER_LEVEL MAX_Nx7135 // throttle back faster when high - #else - #define THERM_FASTER_LEVEL (RAMP_SIZE*4/5) // throttle back faster when high - #endif -#endif -#ifdef USE_THERMAL_REGULATION -#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments -#endif - - -/********* Configure SpaghettiMonster *********/ -#define USE_DELAY_ZERO -#define USE_RAMPING -#ifndef RAMP_LENGTH -#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file -#endif -#define MAX_BIKING_LEVEL 120 // should be 127 or less -#define USE_BATTCHECK - -#if defined(USE_MUGGLE_MODE) -#ifndef MUGGLE_FLOOR -#define MUGGLE_FLOOR 22 -#endif -#ifndef MUGGLE_CEILING -#define MUGGLE_CEILING (MAX_1x7135+20) -#endif -#endif -#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending -#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency - -// full FET strobe can be a bit much... use max regulated level instead, -// if there's a bright enough regulated level -#ifdef MAX_Nx7135 -#define STROBE_BRIGHTNESS MAX_Nx7135 -#else -#define STROBE_BRIGHTNESS MAX_LEVEL -#endif - -#if defined(USE_CANDLE_MODE) || defined(USE_BIKE_FLASHER_MODE) || defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) || defined(USE_LIGHTNING_MODE) -#define USE_STROBE_STATE -#endif - -#if defined(USE_POLICE_STROBE_MODE) || defined(USE_SOS_MODE) -#define USE_BORING_STROBE_STATE -#endif - -// auto-detect how many eeprom bytes -#define USE_EEPROM -typedef enum { - ramp_style_e, - #ifdef USE_RAMP_CONFIG - ramp_smooth_floor_e, - ramp_smooth_ceil_e, - ramp_discrete_floor_e, - ramp_discrete_ceil_e, - ramp_discrete_steps_e, - #endif - #ifdef USE_TINT_RAMPING - tint_e, - #endif - #ifdef USE_STROBE_STATE - strobe_type_e, - #endif - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - strobe_delays_0_e, - strobe_delays_1_e, - #endif - #ifdef USE_BIKE_FLASHER_MODE - bike_flasher_brightness_e, - #endif - #ifdef USE_BEACON_MODE - beacon_seconds_e, - #endif - #ifdef USE_MUGGLE_MODE - muggle_mode_active_e, - #endif - #ifdef USE_THERMAL_REGULATION - therm_ceil_e, - therm_cal_offset_e, - #endif - #ifdef USE_INDICATOR_LED - indicator_led_mode_e, - #endif - eeprom_indexes_e_END -} eeprom_indexes_e; -#define EEPROM_BYTES eeprom_indexes_e_END - -#ifdef START_AT_MEMORIZED_LEVEL -#define USE_EEPROM_WL -#define EEPROM_WL_BYTES 1 -#endif - -// auto-configure other stuff... -#if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE) -#define USE_PSEUDO_RAND -#endif - -#if defined(USE_CANDLE_MODE) -#ifndef USE_TRIANGLE_WAVE -#define USE_TRIANGLE_WAVE -#endif -#endif - -#include "spaghetti-monster.h" - - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -// simple numeric entry config menu -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()); -#define MAX_CONFIG_VALUES 3 -uint8_t config_state_values[MAX_CONFIG_VALUES]; -// ramping mode and its related config mode -uint8_t steady_state(Event event, uint16_t arg); -#ifdef USE_RAMP_CONFIG -uint8_t ramp_config_state(Event event, uint16_t arg); -#endif -#ifdef USE_TINT_RAMPING -// not actually a mode, more of a fallback under other modes -uint8_t tint_ramping_state(Event event, uint16_t arg); -#endif -// party and tactical strobes -#ifdef USE_STROBE_STATE -uint8_t strobe_state(Event event, uint16_t arg); -#endif -#ifdef USE_BORING_STROBE_STATE -uint8_t boring_strobe_state(Event event, uint16_t arg); -volatile uint8_t boring_strobe_type = 0; -void sos_blink(uint8_t num, uint8_t dah); -#define strobe_state boring_strobe_state // use the right strobes -#define NUM_BORING_STROBES 2 -#endif -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg); -#endif -#ifdef USE_THERMAL_REGULATION -uint8_t tempcheck_state(Event event, uint16_t arg); -uint8_t thermal_config_state(Event event, uint16_t arg); -#endif -#ifdef USE_GOODNIGHT_MODE -// 1-hour ramp down from low, then automatic off -uint8_t goodnight_state(Event event, uint16_t arg); -#endif -#ifdef USE_BEACON_MODE -// beacon mode and its related config mode -uint8_t beacon_state(Event event, uint16_t arg); -uint8_t beacon_config_state(Event event, uint16_t arg); -#endif -// soft lockout -#define MOON_DURING_LOCKOUT_MODE -// if enabled, 2nd lockout click goes to the other ramp's floor level -#define LOCKOUT_MOON_FANCY -uint8_t lockout_state(Event event, uint16_t arg); -// momentary / signalling mode -uint8_t momentary_state(Event event, uint16_t arg); -uint8_t momentary_mode = 0; // 0 = ramping, 1 = strobe -uint8_t momentary_active = 0; // boolean, true if active *right now* -#ifdef USE_MUGGLE_MODE -// muggle mode, super-simple, hard to exit -uint8_t muggle_state(Event event, uint16_t arg); -uint8_t muggle_mode_active = 0; -#endif - -// general helper function for config modes -uint8_t number_entry_state(Event event, uint16_t arg); -// return value from number_entry_state() -volatile uint8_t number_entry_value; - -void blink_confirm(uint8_t num); -void blip(); -#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) -void indicator_blink(uint8_t arg); -#endif - -// remember stuff even after battery was changed -void load_config(); -void save_config(); -#ifdef START_AT_MEMORIZED_LEVEL -void save_config_wl(); -#endif - -// default ramp options if not overridden earlier per-driver -#ifndef RAMP_STYLE -#define RAMP_STYLE 0 // smooth default -#endif -#ifndef RAMP_SMOOTH_FLOOR - #define RAMP_SMOOTH_FLOOR 1 -#endif -#ifndef RAMP_SMOOTH_CEIL - #if PWM_CHANNELS == 3 - #define RAMP_SMOOTH_CEIL MAX_Nx7135 - #else - #define RAMP_SMOOTH_CEIL MAX_LEVEL - 30 - #endif -#endif -#ifndef RAMP_DISCRETE_FLOOR - #define RAMP_DISCRETE_FLOOR 20 -#endif -#ifndef RAMP_DISCRETE_CEIL - #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#endif -#ifndef RAMP_DISCRETE_STEPS - #define RAMP_DISCRETE_STEPS 7 -#endif - -// mile marker(s) partway up the ramp -// default: blink only at border between regulated and FET -#ifdef BLINK_AT_RAMP_MIDDLE - #if PWM_CHANNELS >= 3 - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135 - #ifndef BLINK_AT_RAMP_MIDDLE_2 - #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135 - #endif - #endif - #else - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135 - #endif - #endif -#endif - -// brightness control -#ifndef DEFAULT_LEVEL -#define DEFAULT_LEVEL MAX_1x7135 -#endif -uint8_t memorized_level = DEFAULT_LEVEL; -// smooth vs discrete ramping -volatile uint8_t ramp_style = RAMP_STYLE; // 0 = smooth, 1 = discrete -volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR; -volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL; -volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR; -volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL; -volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS; -uint8_t ramp_discrete_step_size; // don't set this - -#ifdef USE_INDICATOR_LED - // bits 2-3 control lockout mode - // bits 0-1 control "off" mode - // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled) - #ifdef INDICATOR_LED_DEFAULT_MODE - uint8_t indicator_led_mode = INDICATOR_LED_DEFAULT_MODE; - #else - #ifdef USE_INDICATOR_LED_WHILE_RAMPING - //uint8_t indicator_led_mode = (1<<2) + 2; - uint8_t indicator_led_mode = (2<<2) + 1; - #else - uint8_t indicator_led_mode = (3<<2) + 1; - #endif - #endif -#endif - -// calculate the nearest ramp level which would be valid at the moment -// (is a no-op for smooth ramp, but limits discrete ramp to only the -// correct levels for the user's config) -uint8_t nearest_level(int16_t target); - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - -// internal numbering for strobe modes -#ifdef USE_STROBE_STATE -typedef enum { - #ifdef USE_PARTY_STROBE_MODE - party_strobe_e, - #endif - #ifdef USE_TACTICAL_STROBE_MODE - tactical_strobe_e, - #endif - #ifdef USE_LIGHTNING_MODE - lightning_storm_e, - #endif - #ifdef USE_CANDLE_MODE - candle_mode_e, - #endif - #ifdef USE_BIKE_FLASHER_MODE - bike_flasher_e, - #endif - strobe_mode_END -} strobe_mode_te; - -const int NUM_STROBES = strobe_mode_END; - -// which strobe mode is active? -#ifdef USE_CANDLE_MODE -volatile strobe_mode_te strobe_type = candle_mode_e; -#else -volatile strobe_mode_te strobe_type = 0; -#endif -#endif - -#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) -// party / tactical strobe timing -volatile uint8_t strobe_delays[] = { 40, 67 }; // party strobe, tactical strobe -#endif - -// bike mode config options -#ifdef USE_BIKE_FLASHER_MODE -volatile uint8_t bike_flasher_brightness = MAX_1x7135; -#endif - -#ifdef USE_CANDLE_MODE -uint8_t candle_mode_state(Event event, uint16_t arg); -uint8_t triangle_wave(uint8_t phase); -#ifndef CANDLE_AMPLITUDE -#define CANDLE_AMPLITUDE 25 -#endif -#endif - -#ifdef USE_BEACON_MODE -// beacon timing -volatile uint8_t beacon_seconds = 2; -#endif - - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - set_level(0); - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode & 0x03); - #endif - // sleep while off (lower power use) - go_to_standby = 1; - return EVENT_HANDLED; - } - // go back to sleep eventually if we got bumped but didn't leave "off" state - else if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode & 0x03); - #endif - } - return EVENT_HANDLED; - } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) - // blink the indicator LED, maybe - else if (event == EV_sleep_tick) { - if ((indicator_led_mode & 0b00000011) == 0b00000011) { - indicator_blink(arg); - } - return EVENT_HANDLED; - } - #endif - // hold (initially): go to lowest level (floor), but allow abort for regular click - else if (event == EV_click1_press) { - set_level(nearest_level(1)); - return EVENT_HANDLED; - } - // hold: go to lowest level - else if (event == EV_click1_hold) { - #ifdef MOON_TIMING_HINT - if (arg == 0) { - // let the user know they can let go now to stay at moon - blip(); - } else - #endif - // don't start ramping immediately; - // give the user time to release at moon level - //if (arg >= HOLD_TIMEOUT) { // smaller - if (arg >= (!ramp_style) * HOLD_TIMEOUT) { // more consistent - set_state(steady_state, 1); - } - return EVENT_HANDLED; - } - // hold, release quickly: go to lowest level (floor) - else if (event == EV_click1_hold_release) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - set_level(nearest_level(memorized_level)); - return EVENT_HANDLED; - } - // 1 click: regular mode - else if (event == EV_1click) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // click, hold: go to highest level (ceiling) (for ramping down) - else if (event == EV_click2_hold) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 2 clicks: highest mode (ceiling) - else if (event == EV_2clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 3 clicks (initial press): off, to prep for later events - else if (event == EV_click3_press) { - set_level(0); - return EVENT_HANDLED; - } - #ifdef USE_BATTCHECK - // 3 clicks: battcheck mode / blinky mode group 1 - else if (event == EV_3clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // click, click, long-click: strobe mode - #ifdef USE_STROBE_STATE - else if (event == EV_click3_hold) { - set_state(strobe_state, 0); - return EVENT_HANDLED; - } - #elif defined(USE_BORING_STROBE_STATE) - else if (event == EV_click3_hold) { - set_state(boring_strobe_state, 0); - return EVENT_HANDLED; - } - #endif - // 4 clicks: soft lockout - else if (event == EV_4clicks) { - blink_confirm(2); - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - // 5 clicks: momentary mode - else if (event == EV_5clicks) { - blink_confirm(1); - set_state(momentary_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_MUGGLE_MODE - // 6 clicks: muggle mode - else if (event == EV_6clicks) { - blink_confirm(1); - set_state(muggle_state, 0); - return EVENT_HANDLED; - } - #endif - #ifdef USE_INDICATOR_LED - // 7 clicks: change indicator LED mode - else if (event == EV_7clicks) { - uint8_t mode = (indicator_led_mode & 3) + 1; - #ifdef TICK_DURING_STANDBY - mode = mode & 3; - #else - mode = mode % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (indicator_led_mode & 0b11111100) | mode; - indicator_led(mode); - save_config(); - return EVENT_HANDLED; - } - #endif - // 8 clicks: temperature check - else if (event == EV_8clicks) { - set_state(tempcheck_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_TENCLICK_THERMAL_CONFIG - // 10 clicks: thermal config mode - else if (event == EV_10clicks) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -uint8_t steady_state(Event event, uint16_t arg) { - uint8_t mode_min = ramp_smooth_floor; - uint8_t mode_max = ramp_smooth_ceil; - uint8_t ramp_step_size = 1; - #ifdef USE_REVERSING - static int8_t ramp_direction = 1; - #endif - if (ramp_style) { - mode_min = ramp_discrete_floor; - mode_max = ramp_discrete_ceil; - ramp_step_size = ramp_discrete_step_size; - } - - // turn LED on when we first enter the mode - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - momentary_mode = 0; // 0 = ramping, 1 = strobes - // if we just got back from config mode, go back to memorized level - if (event == EV_reenter_state) { - arg = memorized_level; - } - // remember this level, unless it's moon or turbo - if ((arg > mode_min) && (arg < mode_max)) - memorized_level = arg; - // use the requested level even if not memorized - arg = nearest_level(arg); - #ifdef USE_THERMAL_REGULATION - target_level = arg; - #endif - set_level(arg); - #ifdef USE_REVERSING - ramp_direction = 1; - #endif - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: go to/from highest level - else if (event == EV_2clicks) { - if (actual_level < MAX_LEVEL) { - #ifdef USE_THERMAL_REGULATION - target_level = MAX_LEVEL; - #endif - // true turbo, not the mode-specific ceiling - set_level(MAX_LEVEL); - } - else { - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // 3 clicks: toggle smooth vs discrete ramping - else if (event == EV_3clicks) { - ramp_style = !ramp_style; - memorized_level = nearest_level(actual_level); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #ifdef USE_SET_LEVEL_GRADUALLY - //set_level_gradually(lvl); - #endif - #endif - save_config(); - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); - #endif - blip(); - set_level(memorized_level); - return EVENT_HANDLED; - } - #ifdef USE_RAMP_CONFIG - // 4 clicks: configure this ramp mode - else if (event == EV_4clicks) { - push_state(ramp_config_state, 0); - return EVENT_HANDLED; - } - #endif - // hold: change brightness (brighter) - else if (event == EV_click1_hold) { - // ramp slower in discrete mode - if (ramp_style && (arg % HOLD_TIMEOUT != 0)) { - return EVENT_HANDLED; - } - #ifdef USE_REVERSING - // fix ramp direction on first frame if necessary - if (!arg) { - // make it ramp down instead, if already at max - if (actual_level >= mode_max) { ramp_direction = -1; } - // make it ramp up if already at min - // (off->hold->stepped_min->release causes this state) - else if (actual_level <= mode_min) { ramp_direction = 1; } - } - memorized_level = nearest_level((int16_t)actual_level \ - + (ramp_step_size * ramp_direction)); - #else - memorized_level = nearest_level((int16_t)actual_level + ramp_step_size); - #endif - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #ifdef BLINK_AT_RAMP_MIDDLE_1 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_1) - #endif - #ifdef BLINK_AT_RAMP_MIDDLE_2 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_2) - #endif - #ifdef BLINK_AT_RAMP_CEILING - || (memorized_level == mode_max) - #endif - #if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR) - || (memorized_level == mode_min) - #endif - )) { - blip(); - } - #endif - #if defined(BLINK_AT_STEPS) - uint8_t foo = ramp_style; - ramp_style = 1; - uint8_t nearest = nearest_level((int16_t)actual_level); - ramp_style = foo; - // only blink once for each threshold - if ((memorized_level != actual_level) && - (ramp_style == 0) && - (memorized_level == nearest) - ) - { - blip(); - } - #endif - set_level(memorized_level); - return EVENT_HANDLED; - } - #if defined(USE_REVERSING) || defined(START_AT_MEMORIZED_LEVEL) - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - #ifdef USE_REVERSING - ramp_direction = -ramp_direction; - #endif - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); - #endif - return EVENT_HANDLED; - } - #endif - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - #ifdef USE_REVERSING - ramp_direction = 1; - #endif - // ramp slower in discrete mode - if (ramp_style && (arg % HOLD_TIMEOUT != 0)) { - return EVENT_HANDLED; - } - // TODO? make it ramp up instead, if already at min? - memorized_level = nearest_level((int16_t)actual_level - ramp_step_size); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #ifdef BLINK_AT_RAMP_MIDDLE_1 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_1) - #endif - #ifdef BLINK_AT_RAMP_MIDDLE_2 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_2) - #endif - #ifdef BLINK_AT_RAMP_FLOOR - || (memorized_level == mode_min) - #endif - )) { - blip(); - } - #endif - #if defined(BLINK_AT_STEPS) - uint8_t foo = ramp_style; - ramp_style = 1; - uint8_t nearest = nearest_level((int16_t)actual_level); - ramp_style = foo; - // only blink once for each threshold - if ((memorized_level != actual_level) && - (ramp_style == 0) && - (memorized_level == nearest) - ) - { - blip(); - } - #endif - set_level(memorized_level); - return EVENT_HANDLED; - } - #ifdef START_AT_MEMORIZED_LEVEL - // click, release, hold, release: save new ramp level (if necessary) - else if (event == EV_click2_hold_release) { - save_config_wl(); - return EVENT_HANDLED; - } - #endif - #if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING) - else if (event == EV_tick) { - #ifdef USE_REVERSING - // un-reverse after 1 second - if (arg == TICKS_PER_SECOND) ramp_direction = 1; - #endif - #ifdef USE_SET_LEVEL_GRADUALLY - // make thermal adjustment speed scale with magnitude - if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) { - return EVENT_HANDLED; // adjust slower when not a high mode - } - #ifdef THERM_HARD_TURBO_DROP - else if ((! (actual_level < THERM_FASTER_LEVEL)) - && (actual_level > gradual_target)) { - gradual_tick(); - } - else { - #endif - // [int(62*4 / (x**0.8)) for x in (1,2,4,8,16,32,64,128)] - //uint8_t intervals[] = {248, 142, 81, 46, 26, 15, 8, 5}; - // [int(62*4 / (x**0.9)) for x in (1,2,4,8,16,32,64,128)] - //uint8_t intervals[] = {248, 132, 71, 38, 20, 10, 5, 3}; - // [int(62*4 / (x**0.95)) for x in (1,2,4,8,16,32,64,128)] - uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2}; - uint8_t diff; - static uint8_t ticks_since_adjust = 0; - ticks_since_adjust ++; - if (gradual_target > actual_level) diff = gradual_target - actual_level; - else { - diff = actual_level - gradual_target; - } - uint8_t magnitude = 0; - #ifndef THERM_HARD_TURBO_DROP - // if we're on a really high mode, drop faster - if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; } - #endif - while (diff) { - magnitude ++; - diff >>= 1; - } - uint8_t ticks_per_adjust = intervals[magnitude]; - if (ticks_since_adjust > ticks_per_adjust) - { - gradual_tick(); - ticks_since_adjust = 0; - } - //if (!(arg % ticks_per_adjust)) gradual_tick(); - #ifdef THERM_HARD_TURBO_DROP - } - #endif - #endif - return EVENT_HANDLED; - } - #endif - #ifdef USE_THERMAL_REGULATION - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - #if 0 - blip(); - #endif - #ifdef THERM_HARD_TURBO_DROP - if (actual_level > THERM_FASTER_LEVEL) { - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(THERM_FASTER_LEVEL); - #else - set_level(THERM_FASTER_LEVEL); - #endif - target_level = THERM_FASTER_LEVEL; - } else - #endif - if (actual_level > MIN_THERM_STEPDOWN) { - int16_t stepdown = actual_level - arg; - if (stepdown < MIN_THERM_STEPDOWN) stepdown = MIN_THERM_STEPDOWN; - else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepdown); - #else - set_level(stepdown); - #endif - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - #if 0 - blip(); - #endif - if (actual_level < target_level) { - //int16_t stepup = actual_level + (arg>>1); - int16_t stepup = actual_level + arg; - if (stepup > target_level) stepup = target_level; - else if (stepup < MIN_THERM_STEPDOWN) stepup = MIN_THERM_STEPDOWN; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepup); - #else - set_level(stepup); - #endif - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_TINT_RAMPING -uint8_t tint_ramping_state(Event event, uint16_t arg) { - static int8_t tint_ramp_direction = 1; - static uint8_t prev_tint = 0; - // don't activate auto-tint modes unless the user hits the edge - // and keeps pressing for a while - static uint8_t past_edge_counter = 0; - // bugfix: click-click-hold from off to strobes would invoke tint ramping - // in addition to changing state... so ignore any tint-ramp events which - // don't look like they were meant to be here - static uint8_t active = 0; - - // click, click, hold: change the tint - if (event == EV_click3_hold) { - // reset at beginning of movement - if (! arg) { - active = 1; // first frame means this is for us - past_edge_counter = 0; // doesn't start until user hits the edge - } - // ignore event if we weren't the ones who handled the first frame - if (! active) return EVENT_HANDLED; - - // change normal tints - if ((tint_ramp_direction > 0) && (tint < 254)) { - tint += 1; - } - else if ((tint_ramp_direction < 0) && (tint > 1)) { - tint -= 1; - } - // if the user kept pressing long enough, go the final step - if (past_edge_counter == 64) { - past_edge_counter ++; - tint ^= 1; // 0 -> 1, 254 -> 255 - blip(); - } - // if tint change stalled, let user know we hit the edge - else if (prev_tint == tint) { - if (past_edge_counter == 0) blip(); - // count up but don't wrap back to zero - if (past_edge_counter < 255) past_edge_counter ++; - } - prev_tint = tint; - set_level(actual_level); - return EVENT_HANDLED; - } - - // click, click, hold, release: reverse direction for next ramp - else if (event == EV_click3_hold_release) { - active = 0; // ignore next hold if it wasn't meant for us - // reverse - tint_ramp_direction = -tint_ramp_direction; - if (tint == 0) tint_ramp_direction = 1; - else if (tint == 255) tint_ramp_direction = -1; - // remember tint after battery change - save_config(); - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} -#endif // ifdef USE_TINT_RAMPING - - -#ifdef USE_STROBE_STATE -uint8_t strobe_state(Event event, uint16_t arg) { - static int8_t ramp_direction = 1; - - // 'st' reduces ROM size by avoiding access to a volatile var - // (maybe I should just make it nonvolatile?) - strobe_mode_te st = strobe_type; - - momentary_mode = 1; // 0 = ramping, 1 = strobes - - #ifdef USE_CANDLE_MODE - // pass all events to candle mode, when it's active - // (the code is in its own pseudo-state to keep things cleaner) - if (st == candle_mode_e) { - candle_mode_state(event, arg); - } - #endif - - if (0) {} // placeholder - // init anything which needs to be initialized - else if (event == EV_enter_state) { - ramp_direction = 1; - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: rotate through strobe/flasher modes - else if (event == EV_2clicks) { - strobe_type = (st + 1) % NUM_STROBES; - save_config(); - return EVENT_HANDLED; - } - // hold: change speed (go faster) - // or change brightness (brighter) - else if (event == EV_click1_hold) { - if (0) {} // placeholder - - // party / tactical strobe faster - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_TACTICAL_STROBE_MODE - else if (st <= tactical_strobe_e) { - #else - else if (st == party_strobe_e) { - #endif - if ((arg & 1) == 0) { - uint8_t d = strobe_delays[st]; - d -= ramp_direction; - if (d < 8) d = 8; - else if (d > 254) d = 254; - strobe_delays[st] = d; - } - } - #endif - - // lightning has no adjustments - //else if (st == lightning_storm_e) {} - - // biking mode brighter - #ifdef USE_BIKE_FLASHER_MODE - else if (st == bike_flasher_e) { - bike_flasher_brightness += ramp_direction; - if (bike_flasher_brightness < 2) bike_flasher_brightness = 2; - else if (bike_flasher_brightness > MAX_BIKING_LEVEL) bike_flasher_brightness = MAX_BIKING_LEVEL; - set_level(bike_flasher_brightness); - } - #endif - - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - // ... and save new strobe settings - else if (event == EV_click1_hold_release) { - ramp_direction = -ramp_direction; - save_config(); - return EVENT_HANDLED; - } - // click, hold: change speed (go slower) - // or change brightness (dimmer) - else if (event == EV_click2_hold) { - ramp_direction = 1; - - if (0) {} // placeholder - - // party / tactical strobe slower - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_TACTICAL_STROBE_MODE - else if (st <= tactical_strobe_e) { - #else - else if (st == party_strobe_e) { - #endif - if ((arg & 1) == 0) { - if (strobe_delays[st] < 255) strobe_delays[st] ++; - } - } - #endif - - // lightning has no adjustments - //else if (st == lightning_storm_e) {} - - // biking mode dimmer - #ifdef USE_BIKE_FLASHER_MODE - else if (st == bike_flasher_e) { - if (bike_flasher_brightness > 2) - bike_flasher_brightness --; - set_level(bike_flasher_brightness); - } - #endif - - return EVENT_HANDLED; - } - // release hold: save new strobe settings - else if (event == EV_click2_hold_release) { - save_config(); - return EVENT_HANDLED; - } - #if defined(USE_LIGHTNING_MODE) || defined(USE_CANDLE_MODE) - // clock tick: bump the random seed - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == TICKS_PER_SECOND) ramp_direction = 1; - - pseudo_rand_seed += arg; - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - -#if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) -inline void party_tactical_strobe_mode_iter(uint8_t st) { - // one iteration of main loop() - uint8_t del = strobe_delays[st]; - // TODO: make tac strobe brightness configurable? - set_level(STROBE_BRIGHTNESS); - if (0) {} // placeholde0 - #ifdef USE_PARTY_STROBE_MODE - else if (st == party_strobe_e) { // party strobe - if (del < 42) delay_zero(); - else nice_delay_ms(1); - } - #endif - #ifdef USE_TACTICAL_STROBE_MODE - else { //tactical strobe - nice_delay_ms(del >> 1); - } - #endif - set_level(0); - nice_delay_ms(del); // no return check necessary on final delay -} -#endif - -#ifdef USE_LIGHTNING_MODE -inline void lightning_storm_iter() { - // one iteration of main loop() - int16_t brightness; - uint16_t rand_time; - - // turn the emitter on at a random level, - // for a random amount of time between 1ms and 32ms - //rand_time = 1 << (pseudo_rand() % 7); - rand_time = pseudo_rand() & 63; - brightness = 1 << (pseudo_rand() % 7); // 1, 2, 4, 8, 16, 32, 64 - brightness += 1 << (pseudo_rand() % 5); // 2 to 80 now - brightness += pseudo_rand() % brightness; // 2 to 159 now (w/ low bias) - if (brightness > MAX_LEVEL) brightness = MAX_LEVEL; - set_level(brightness); - nice_delay_ms(rand_time); - - // decrease the brightness somewhat more gradually, like lightning - uint8_t stepdown = brightness >> 3; - if (stepdown < 1) stepdown = 1; - while(brightness > 1) { - nice_delay_ms(rand_time); - brightness -= stepdown; - if (brightness < 0) brightness = 0; - set_level(brightness); - /* - if ((brightness < MAX_LEVEL/2) && (! (pseudo_rand() & 15))) { - brightness <<= 1; - set_level(brightness); - } - */ - if (! (pseudo_rand() & 3)) { - nice_delay_ms(rand_time); - set_level(brightness>>1); - } - } - - // turn the emitter off, - // for a random amount of time between 1ms and 8192ms - // (with a low bias) - rand_time = 1 << (pseudo_rand() % 13); - rand_time += pseudo_rand() % rand_time; - set_level(0); - nice_delay_ms(rand_time); // no return check necessary on final delay -} -#endif - -#ifdef USE_BIKE_FLASHER_MODE -inline void bike_flasher_iter() { - // one iteration of main loop() - uint8_t burst = bike_flasher_brightness << 1; - if (burst > MAX_LEVEL) burst = MAX_LEVEL; - for(uint8_t i=0; i<4; i++) { - set_level(burst); - nice_delay_ms(5); - set_level(bike_flasher_brightness); - nice_delay_ms(65); - } - nice_delay_ms(720); // no return check necessary on final delay -} -#endif - -#endif // ifdef USE_STROBE_STATE - -#ifdef USE_CANDLE_MODE -uint8_t candle_mode_state(Event event, uint16_t arg) { - static int8_t ramp_direction = 1; - #define MAX_CANDLE_LEVEL (RAMP_LENGTH-CANDLE_AMPLITUDE-15) - static uint8_t candle_wave1 = 0; - static uint8_t candle_wave2 = 0; - static uint8_t candle_wave3 = 0; - static uint8_t candle_wave2_speed = 0; - // these should add up to 100 - #define CANDLE_WAVE1_MAXDEPTH 30 - #define CANDLE_WAVE2_MAXDEPTH 45 - #define CANDLE_WAVE3_MAXDEPTH 25 - static const uint8_t candle_wave1_depth = CANDLE_WAVE1_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_wave2_depth = CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_wave3_depth = CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100; - static uint8_t candle_mode_brightness = 24; - static uint8_t candle_mode_timer = 0; - #define TICKS_PER_CANDLE_MINUTE 4096 // about 65 seconds - #define MINUTES_PER_CANDLE_HALFHOUR 27 // ish - - if (event == EV_enter_state) { - candle_mode_timer = 0; // in case any time was left over from earlier - ramp_direction = 1; - return EVENT_HANDLED; - } - // 2 clicks: cancel timer - else if (event == EV_2clicks) { - // parent state just rotated through strobe/flasher modes, - // so cancel timer... in case any time was left over from earlier - candle_mode_timer = 0; - return EVENT_HANDLED; - } - // hold: change brightness (brighter) - else if (event == EV_click1_hold) { - // ramp away from extremes - if (! arg) { - if (candle_mode_brightness >= MAX_CANDLE_LEVEL) { ramp_direction = -1; } - else if (candle_mode_brightness <= 1) { ramp_direction = 1; } - } - // change brightness, but not too far - candle_mode_brightness += ramp_direction; - if (candle_mode_brightness < 1) candle_mode_brightness = 1; - else if (candle_mode_brightness > MAX_CANDLE_LEVEL) candle_mode_brightness = MAX_CANDLE_LEVEL; - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - ramp_direction = -ramp_direction; - return EVENT_HANDLED; - } - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - ramp_direction = 1; - if (candle_mode_brightness > 1) - candle_mode_brightness --; - return EVENT_HANDLED; - } - // 3 clicks: add 30m to candle timer - else if (event == EV_3clicks) { - if (candle_mode_timer < (255 - MINUTES_PER_CANDLE_HALFHOUR)) { - // add 30m to the timer - candle_mode_timer += MINUTES_PER_CANDLE_HALFHOUR; - // blink to confirm - set_level(actual_level + 32); - delay_4ms(2); - } - return EVENT_HANDLED; - } - // clock tick: animate candle brightness - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == TICKS_PER_SECOND) ramp_direction = 1; - - // self-timer dims the light during the final minute - uint8_t subtract = 0; - if (candle_mode_timer == 1) { - subtract = ((candle_mode_brightness+CANDLE_AMPLITUDE) - * ((arg & (TICKS_PER_CANDLE_MINUTE-1)) >> 4)) - >> 8; - } - // we passed a minute mark, decrease timer if it's running - if ((arg & (TICKS_PER_CANDLE_MINUTE-1)) == (TICKS_PER_CANDLE_MINUTE - 1)) { - if (candle_mode_timer > 0) { - candle_mode_timer --; - //set_level(0); delay_4ms(2); - // if the timer ran out, shut off - if (! candle_mode_timer) { - set_state(off_state, 0); - } - } - } - // 3-oscillator synth for a relatively organic pattern - uint8_t add; - add = ((triangle_wave(candle_wave1) * candle_wave1_depth) >> 8) - + ((triangle_wave(candle_wave2) * candle_wave2_depth) >> 8) - + ((triangle_wave(candle_wave3) * candle_wave3_depth) >> 8); - int8_t brightness = candle_mode_brightness + add - subtract; - if (brightness < 0) { brightness = 0; } - set_level(brightness); - - // wave1: slow random LFO - // TODO: make wave slower and more erratic? - if ((arg & 1) == 0) candle_wave1 += pseudo_rand() & 1; - // wave2: medium-speed erratic LFO - candle_wave2 += candle_wave2_speed; - // wave3: erratic fast wave - candle_wave3 += pseudo_rand() % 37; - // S&H on wave2 frequency to make it more erratic - if ((pseudo_rand() & 0b00111111) == 0) - candle_wave2_speed = pseudo_rand() % 13; - // downward sawtooth on wave2 depth to simulate stabilizing - if ((candle_wave2_depth > 0) && ((pseudo_rand() & 0b00111111) == 0)) - candle_wave2_depth --; - // random sawtooth retrigger - if (pseudo_rand() == 0) { - // random amplitude - //candle_wave2_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); - candle_wave2_depth = pseudo_rand() % (CANDLE_WAVE2_MAXDEPTH * CANDLE_AMPLITUDE / 100); - //candle_wave3_depth = 5; - candle_wave2 = 0; - } - // downward sawtooth on wave3 depth to simulate stabilizing - if ((candle_wave3_depth > 2) && ((pseudo_rand() & 0b00011111) == 0)) - candle_wave3_depth --; - if ((pseudo_rand() & 0b01111111) == 0) - // random amplitude - //candle_wave3_depth = 2 + (pseudo_rand() % ((CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100) - 2)); - candle_wave3_depth = pseudo_rand() % (CANDLE_WAVE3_MAXDEPTH * CANDLE_AMPLITUDE / 100); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif // #ifdef USE_CANDLE_MODE - - -#ifdef USE_BORING_STROBE_STATE -uint8_t boring_strobe_state(Event event, uint16_t arg) { - // police strobe and SOS, meh - // 'st' reduces ROM size by avoiding access to a volatile var - // (maybe I should just make it nonvolatile?) - uint8_t st = boring_strobe_type; - - momentary_mode = 1; // 0 = ramping, 1 = strobes - - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - // reset to police strobe for next time - boring_strobe_type = 0; - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: rotate through strobe/flasher modes - else if (event == EV_2clicks) { - boring_strobe_type = (st + 1) % NUM_BORING_STROBES; - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -#ifdef USE_POLICE_STROBE_MODE -inline void police_strobe_iter() { - // one iteration of main loop() - // flash at 16 Hz then 8 Hz, 8 times each - for (uint8_t del=41; del<100; del+=41) { - for (uint8_t f=0; f<8; f++) { - set_level(STROBE_BRIGHTNESS); - nice_delay_ms(del >> 1); - set_level(0); - nice_delay_ms(del); - } - } -} -#endif - -#ifdef USE_SOS_MODE -void sos_blink(uint8_t num, uint8_t dah) { - #define DIT_LENGTH 200 - for (; num > 0; num--) { - set_level(memorized_level); - nice_delay_ms(DIT_LENGTH); - if (dah) { // dah is 3X as long as a dit - nice_delay_ms(DIT_LENGTH*2); - } - set_level(0); - // one "off" dit between blinks - nice_delay_ms(DIT_LENGTH); - } - // three "off" dits (or one "dah") between letters - nice_delay_ms(DIT_LENGTH*2); -} - -inline void sos_mode_iter() { - // one iteration of main loop() - nice_delay_ms(1000); - sos_blink(3, 0); // S - sos_blink(3, 1); // O - sos_blink(3, 0); // S - nice_delay_ms(1000); -} -#endif // #ifdef USE_SOS_MODE -#endif // #ifdef USE_BORING_STROBE_STATE - - -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - #if defined(USE_GOODNIGHT_MODE) || defined(USE_BEACON_MODE) - // 2 clicks: next mode - else if (event == EV_2clicks) { - #ifdef USE_GOODNIGHT_MODE - set_state(goodnight_state, 0); - #elif defined(USE_BEACON_MODE) - set_state(beacon_state, 0); - #endif - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} -#endif - - -#ifdef USE_THERMAL_REGULATION -uint8_t tempcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - #if 0 // not part of a loop in this UI - // 2 clicks: battcheck mode - else if (event == EV_2clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // 4 clicks: thermal config mode - else if (event == EV_4clicks) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -#ifdef USE_BEACON_MODE -uint8_t beacon_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // TODO: use sleep ticks to measure time between pulses, - // to save power - // 2 clicks: tempcheck mode - else if (event == EV_2clicks) { - #ifdef USE_THERMAL_REGULATION - set_state(tempcheck_state, 0); - #else - set_state(battcheck_state, 0); - #endif - return EVENT_HANDLED; - } - // 4 clicks: beacon config mode - else if (event == EV_4clicks) { - push_state(beacon_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif // #ifdef USE_BEACON_MODE - - -#ifdef USE_GOODNIGHT_MODE -#define GOODNIGHT_TICKS_PER_STEPDOWN (GOODNIGHT_TIME*TICKS_PER_SECOND*60L/GOODNIGHT_LEVEL) -uint8_t goodnight_state(Event event, uint16_t arg) { - static uint16_t ticks_since_stepdown = 0; - // blink on start - if (event == EV_enter_state) { - ticks_since_stepdown = 0; - blink_confirm(2); - set_level(GOODNIGHT_LEVEL); - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: beacon mode - else if (event == EV_2clicks) { - #ifdef USE_BEACON_MODE - set_state(beacon_state, 0); - #elif defined(USE_TEMPCHECK_MODE) - set_state(tempcheck_state, 0); - #endif - return EVENT_HANDLED; - } - // tick: step down (maybe) or off (maybe) - else if (event == EV_tick) { - if (++ticks_since_stepdown > GOODNIGHT_TICKS_PER_STEPDOWN) { - ticks_since_stepdown = 0; - set_level(actual_level-1); - if (! actual_level) { - #if 0 // test blink, to help measure timing - set_level(MAX_LEVEL>>2); - delay_4ms(8/2); - set_level(0); - #endif - set_state(off_state, 0); - } - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -uint8_t lockout_state(Event event, uint16_t arg) { - #ifdef MOON_DURING_LOCKOUT_MODE - // momentary(ish) moon mode during lockout - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - #ifdef LOCKOUT_MOON_LOWEST - // Use lowest moon configured - uint8_t lvl = ramp_smooth_floor; - if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor; - set_level(lvl); - #elif defined(LOCKOUT_MOON_FANCY) - uint8_t levels[] = { ramp_smooth_floor, ramp_discrete_floor }; - if ((event & 0x0f) == 2) { - set_level(levels[ramp_style^1]); - } else { - set_level(levels[ramp_style]); - } - #else - // Use moon from current ramp - set_level(nearest_level(1)); - #endif - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - set_level(0); - } - #endif - - // regular event handling - // conserve power while locked out - // (allow staying awake long enough to exit, but otherwise - // be persistent about going back to sleep every few seconds - // even if the user keeps pressing the button) - #ifdef USE_INDICATOR_LED - if (event == EV_enter_state) { - indicator_led(indicator_led_mode >> 2); - } else - #endif - if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode >> 2); - #endif - } - return EVENT_HANDLED; - } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) - else if (event == EV_sleep_tick) { - if ((indicator_led_mode & 0b00001100) == 0b00001100) { - indicator_blink(arg); - } - return EVENT_HANDLED; - } - #endif - #ifdef USE_INDICATOR_LED - // 3 clicks: rotate through indicator LED modes (lockout mode) - else if (event == EV_3clicks) { - uint8_t mode = indicator_led_mode >> 2; - #ifdef TICK_DURING_STANDBY - mode = (mode + 1) & 3; - #else - mode = (mode + 1) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03); - indicator_led(mode); - save_config(); - return EVENT_HANDLED; - } - #if 0 // old method, deprecated in favor of "7 clicks from off" - // click, click, hold: rotate through indicator LED modes (off mode) - else if (event == EV_click3_hold) { - #ifndef USE_INDICATOR_LED_WHILE_RAMPING - // if main LED obscures aux LEDs, turn it off - set_level(0); - #endif - #ifdef TICK_DURING_STANDBY - uint8_t mode = (arg >> 5) & 3; - #else - uint8_t mode = (arg >> 5) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (indicator_led_mode & 0b11111100) | mode; - #ifdef TICK_DURING_STANDBY - if (mode == 3) - indicator_led(mode & (arg&3)); - else - indicator_led(mode); - #else - indicator_led(mode); - #endif - //save_config(); - return EVENT_HANDLED; - } - // click, click, hold, release: save indicator LED mode (off mode) - else if (event == EV_click3_hold_release) { - save_config(); - return EVENT_HANDLED; - } - #endif - #endif - // 4 clicks: exit - else if (event == EV_4clicks) { - blink_confirm(1); - set_state(off_state, 0); - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - - -uint8_t momentary_state(Event event, uint16_t arg) { - // TODO: momentary strobe here? (for light painting) - - // init strobe mode, if relevant - if ((event == EV_enter_state) && (momentary_mode == 1)) { - strobe_state(event, arg); - } - - // light up when the button is pressed; go dark otherwise - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - momentary_active = 1; - // 0 = ramping, 1 = strobes - if (momentary_mode == 0) { - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - momentary_active = 0; - set_level(0); - //go_to_standby = 1; // sleep while light is off - return EVENT_HANDLED; - } - - // Sleep, dammit! (but wait a few seconds first) - // (because standby mode uses such little power that it can interfere - // with exiting via tailcap loosen+tighten unless you leave power - // disconnected for several seconds, so we want to be awake when that - // happens to speed up the process) - else if (event == EV_tick) { - if (momentary_active) { - // 0 = ramping, 1 = strobes - if (momentary_mode == 1) { - return strobe_state(event, arg); - } - } - else { - if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds - go_to_standby = 1; // sleep while light is off - // TODO: lighted button should use lockout config? - } - } - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_MUGGLE_MODE -uint8_t muggle_state(Event event, uint16_t arg) { - static int8_t ramp_direction; - static int8_t muggle_off_mode; - - // turn LED off when we first enter the mode - if (event == EV_enter_state) { - ramp_direction = 1; - - #ifdef START_AT_MEMORIZED_LEVEL - memorized_level = arg; - muggle_off_mode = 0; - set_level(memorized_level); - - if (! muggle_mode_active) { // don't write eeprom at every boot - muggle_mode_active = 1; - save_config(); - } - #else - muggle_mode_active = 1; - save_config(); - - muggle_off_mode = 1; - //memorized_level = MAX_1x7135; - memorized_level = (MUGGLE_FLOOR + MUGGLE_CEILING) / 2; - #endif - return EVENT_HANDLED; - } - // initial press: moon hint - else if (event == EV_click1_press) { - if (muggle_off_mode) - set_level(MUGGLE_FLOOR); - } - // initial release: direct to memorized level - else if (event == EV_click1_release) { - if (muggle_off_mode) - set_level(memorized_level); - } - // if the user keeps pressing, turn off - else if (event == EV_click2_press) { - muggle_off_mode = 1; - set_level(0); - } - // 1 click: on/off - else if (event == EV_1click) { - muggle_off_mode ^= 1; - if (muggle_off_mode) { - set_level(0); - } - /* - else { - set_level(memorized_level); - } - */ - return EVENT_HANDLED; - } - // hold: change brightness - else if (event == EV_click1_hold) { - // ramp at half speed - if (arg & 1) return EVENT_HANDLED; - - // if off, start at bottom - if (muggle_off_mode) { - muggle_off_mode = 0; - ramp_direction = 1; - set_level(MUGGLE_FLOOR); - } - else { - uint8_t m; - m = actual_level; - // ramp down if already at ceiling - if ((arg <= 1) && (m >= MUGGLE_CEILING)) ramp_direction = -1; - // ramp - m += ramp_direction; - if (m < MUGGLE_FLOOR) - m = MUGGLE_FLOOR; - if (m > MUGGLE_CEILING) - m = MUGGLE_CEILING; - memorized_level = m; - set_level(m); - } - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - ramp_direction = -ramp_direction; - #ifdef START_AT_MEMORIZED_LEVEL - save_config_wl(); // momentary use should retain brightness level - #endif - return EVENT_HANDLED; - } - /* - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - ramp_direction = 1; - if (memorized_level > MUGGLE_FLOOR) - memorized_level = actual_level - 1; - set_level(memorized_level); - return EVENT_HANDLED; - } - */ - // 6 clicks: exit muggle mode - else if (event == EV_6clicks) { - blink_confirm(1); - muggle_mode_active = 0; - save_config(); - set_state(off_state, 0); - return EVENT_HANDLED; - } - // tick: housekeeping - else if (event == EV_tick) { - // un-reverse after 1 second - if (arg == TICKS_PER_SECOND) ramp_direction = 1; - - // turn off, but don't go to the main "off" state - if (muggle_off_mode) { - if (arg > TICKS_PER_SECOND*1) { // sleep after 1 second - go_to_standby = 1; // sleep while light is off - } - } - return EVENT_HANDLED; - } - #ifdef USE_THERMAL_REGULATION - // overheating is handled specially in muggle mode - else if(event == EV_temperature_high) { - #if 0 - blip(); - #endif - // step down proportional to the amount of overheating - uint8_t new = actual_level - arg; - if (new < MUGGLE_FLOOR) { new = MUGGLE_FLOOR; } - set_level(new); - return EVENT_HANDLED; - } - #endif - // low voltage is handled specially in muggle mode - else if(event == EV_voltage_low) { - uint8_t lvl = (actual_level >> 1) + (actual_level >> 2); - if (lvl >= MUGGLE_FLOOR) { - set_level(lvl); - } else { - muggle_off_mode = 1; - } - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} -#endif - - -// ask the user for a sequence of numbers, then save them and return to caller -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()) { - static uint8_t config_step; - if (event == EV_enter_state) { - config_step = 0; - set_level(0); - return EVENT_HANDLED; - } - // advance forward through config steps - else if (event == EV_tick) { - if (config_step < num_config_steps) { - push_state(number_entry_state, config_step + 1); - } - else { - // TODO: blink out some sort of success pattern - savefunc(); - save_config(); - //set_state(retstate, retval); - pop_state(); - } - return EVENT_HANDLED; - } - // an option was set (return from number_entry_state) - else if (event == EV_reenter_state) { - config_state_values[config_step] = number_entry_value; - config_step ++; - return EVENT_HANDLED; - } - //return EVENT_NOT_HANDLED; - // eat all other events; don't pass any through to parent - return EVENT_HANDLED; -} - -#ifdef USE_RAMP_CONFIG -void ramp_config_save() { - // parse values - uint8_t val; - if (ramp_style) { // discrete / stepped ramp - - val = config_state_values[0]; - if (val) { ramp_discrete_floor = val; } - - val = config_state_values[1]; - if (val) { ramp_discrete_ceil = MAX_LEVEL + 1 - val; } - - val = config_state_values[2]; - if (val) ramp_discrete_steps = val; - - } else { // smooth ramp - - val = config_state_values[0]; - if (val) { ramp_smooth_floor = val; } - - val = config_state_values[1]; - if (val) { ramp_smooth_ceil = MAX_LEVEL + 1 - val; } - - } -} - -uint8_t ramp_config_state(Event event, uint16_t arg) { - uint8_t num_config_steps; - num_config_steps = 2 + ramp_style; - return config_state_base(event, arg, - num_config_steps, ramp_config_save); -} -#endif // #ifdef USE_RAMP_CONFIG - - -#ifdef USE_THERMAL_REGULATION -void thermal_config_save() { - // parse values - uint8_t val; - - // calibrate room temperature - val = config_state_values[0]; - if (val) { - int8_t rawtemp = temperature - therm_cal_offset; - therm_cal_offset = val - rawtemp; - reset_thermal_history = 1; // invalidate all recent temperature data - } - - val = config_state_values[1]; - if (val) { - // set maximum heat limit - therm_ceil = 30 + val - 1; - } - if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL; -} - -uint8_t thermal_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 2, thermal_config_save); -} -#endif // #ifdef USE_THERMAL_REGULATION - - -#ifdef USE_BEACON_MODE -void beacon_config_save() { - // parse values - uint8_t val = config_state_values[0]; - if (val) { - beacon_seconds = val; - } -} - -uint8_t beacon_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 1, beacon_config_save); -} - -inline void beacon_mode_iter() { - // one iteration of main loop() - set_level(memorized_level); - nice_delay_ms(100); - set_level(0); - nice_delay_ms(((beacon_seconds) * 1000) - 100); -} -#endif // #ifdef USE_BEACON_MODE - - -uint8_t number_entry_state(Event event, uint16_t arg) { - static uint8_t value; - static uint8_t blinks_left; - static uint8_t entry_step; - static uint16_t wait_ticks; - if (event == EV_enter_state) { - value = 0; - blinks_left = arg; - entry_step = 0; - wait_ticks = 0; - return EVENT_HANDLED; - } - // advance through the process: - // 0: wait a moment - // 1: blink out the 'arg' value - // 2: wait a moment - // 3: "buzz" while counting clicks - // 4: save and exit - else if (event == EV_tick) { - // wait a moment - if ((entry_step == 0) || (entry_step == 2)) { - if (wait_ticks < TICKS_PER_SECOND/2) - wait_ticks ++; - else { - entry_step ++; - wait_ticks = 0; - } - } - // blink out the option number - else if (entry_step == 1) { - if (blinks_left) { - if ((wait_ticks & 31) == 10) { - set_level(RAMP_SIZE/4); - } - else if ((wait_ticks & 31) == 20) { - set_level(0); - } - else if ((wait_ticks & 31) == 31) { - blinks_left --; - } - wait_ticks ++; - } - else { - entry_step ++; - wait_ticks = 0; - } - } - else if (entry_step == 3) { // buzz while waiting for a number to be entered - wait_ticks ++; - // buzz for N seconds after last event - if ((wait_ticks & 3) == 0) { - set_level(RAMP_SIZE/6); - } - else if ((wait_ticks & 3) == 2) { - set_level(RAMP_SIZE/8); - } - // time out after 3 seconds - if (wait_ticks > TICKS_PER_SECOND*3) { - //number_entry_value = value; - set_level(0); - entry_step ++; - } - } - else if (entry_step == 4) { - number_entry_value = value; - pop_state(); - } - return EVENT_HANDLED; - } - // count clicks - else if (event == EV_click1_release) { - empty_event_sequence(); - if (entry_step == 3) { // only count during the "buzz" - value ++; - wait_ticks = 0; - // flash briefly - set_level(RAMP_SIZE/2); - delay_4ms(8/2); - set_level(0); - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -// find the ramp level closest to the target, -// using only the levels which are allowed in the current state -uint8_t nearest_level(int16_t target) { - // bounds check - // using int16_t here saves us a bunch of logic elsewhere, - // by allowing us to correct for numbers < 0 or > 255 in one central place - uint8_t mode_min = ramp_smooth_floor; - uint8_t mode_max = ramp_smooth_ceil; - if (ramp_style) { - mode_min = ramp_discrete_floor; - mode_max = ramp_discrete_ceil; - } - if (target < mode_min) return mode_min; - if (target > mode_max) return mode_max; - // the rest isn't relevant for smooth ramping - if (! ramp_style) return target; - - uint8_t ramp_range = ramp_discrete_ceil - ramp_discrete_floor; - ramp_discrete_step_size = ramp_range / (ramp_discrete_steps-1); - uint8_t this_level = ramp_discrete_floor; - - for(uint8_t i=0; i<ramp_discrete_steps; i++) { - this_level = ramp_discrete_floor + (i * (uint16_t)ramp_range / (ramp_discrete_steps-1)); - int16_t diff = target - this_level; - if (diff < 0) diff = -diff; - if (diff <= (ramp_discrete_step_size>>1)) - return this_level; - } - return this_level; -} - - -void blink_confirm(uint8_t num) { - for (; num>0; num--) { - set_level(MAX_LEVEL/4); - delay_4ms(10/4); - set_level(0); - delay_4ms(100/4); - } -} - -// Just go dark for a moment to indicate to user that something happened -void blip() { - uint8_t temp = actual_level; - set_level(0); - delay_4ms(3); - set_level(temp); -} - - -#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) -// beacon-like mode for the indicator LED -void indicator_blink(uint8_t arg) { - #define USE_FANCIER_BLINKING_INDICATOR - #ifdef USE_FANCIER_BLINKING_INDICATOR - - // fancy blink, set off/low/high levels here: - uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0}; - indicator_led(seq[arg & 15]); - - #else // basic blink, 1/8th duty cycle - - if (! (arg & 7)) { - indicator_led(2); - } - else { - indicator_led(0); - } - - #endif -} -#endif - - -void load_config() { - if (load_eeprom()) { - ramp_style = eeprom[ramp_style_e]; - #ifdef USE_RAMP_CONFIG - ramp_smooth_floor = eeprom[ramp_smooth_floor_e]; - ramp_smooth_ceil = eeprom[ramp_smooth_ceil_e]; - ramp_discrete_floor = eeprom[ramp_discrete_floor_e]; - ramp_discrete_ceil = eeprom[ramp_discrete_ceil_e]; - ramp_discrete_steps = eeprom[ramp_discrete_steps_e]; - #endif - #ifdef USE_TINT_RAMPING - tint = eeprom[tint_e]; - #endif - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - strobe_type = eeprom[strobe_type_e]; // TODO: move this to eeprom_wl? - strobe_delays[0] = eeprom[strobe_delays_0_e]; - strobe_delays[1] = eeprom[strobe_delays_1_e]; - #endif - #ifdef USE_BIKE_FLASHER_MODE - bike_flasher_brightness = eeprom[bike_flasher_brightness_e]; - #endif - #ifdef USE_BEACON_MODE - beacon_seconds = eeprom[beacon_seconds_e]; - #endif - #ifdef USE_MUGGLE_MODE - muggle_mode_active = eeprom[muggle_mode_active_e]; - #endif - #ifdef USE_THERMAL_REGULATION - therm_ceil = eeprom[therm_ceil_e]; - therm_cal_offset = eeprom[therm_cal_offset_e]; - #endif - #ifdef USE_INDICATOR_LED - indicator_led_mode = eeprom[indicator_led_mode_e]; - #endif - } - #ifdef START_AT_MEMORIZED_LEVEL - if (load_eeprom_wl()) { - memorized_level = eeprom_wl[0]; - } - #endif -} - -void save_config() { - eeprom[ramp_style_e] = ramp_style; - #ifdef USE_RAMP_CONFIG - eeprom[ramp_smooth_floor_e] = ramp_smooth_floor; - eeprom[ramp_smooth_ceil_e] = ramp_smooth_ceil; - eeprom[ramp_discrete_floor_e] = ramp_discrete_floor; - eeprom[ramp_discrete_ceil_e] = ramp_discrete_ceil; - eeprom[ramp_discrete_steps_e] = ramp_discrete_steps; - #endif - #ifdef USE_TINT_RAMPING - eeprom[tint_e] = tint; - #endif - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - eeprom[strobe_type_e] = strobe_type; // TODO: move this to eeprom_wl? - eeprom[strobe_delays_0_e] = strobe_delays[0]; - eeprom[strobe_delays_1_e] = strobe_delays[1]; - #endif - #ifdef USE_BIKE_FLASHER_MODE - eeprom[bike_flasher_brightness_e] = bike_flasher_brightness; - #endif - #ifdef USE_BEACON_MODE - eeprom[beacon_seconds_e] = beacon_seconds; - #endif - #ifdef USE_MUGGLE_MODE - eeprom[muggle_mode_active_e] = muggle_mode_active; - #endif - #ifdef USE_THERMAL_REGULATION - eeprom[therm_ceil_e] = therm_ceil; - eeprom[therm_cal_offset_e] = therm_cal_offset; - #endif - #ifdef USE_INDICATOR_LED - eeprom[indicator_led_mode_e] = indicator_led_mode; - #endif - - save_eeprom(); -} - -#ifdef START_AT_MEMORIZED_LEVEL -void save_config_wl() { - eeprom_wl[0] = memorized_level; - save_eeprom_wl(); -} -#endif - - -void low_voltage() { - StatePtr state = current_state; - - // TODO: turn off aux LED(s) when power is really low - - if (0) {} // placeholder - - #ifdef USE_STROBE_STATE - // "step down" from strobe to something low - else if (state == strobe_state) { - set_state(steady_state, RAMP_SIZE/6); - } - #endif - - // in normal or muggle mode, step down or turn off - //else if ((state == steady_state) || (state == muggle_state)) { - else if (state == steady_state) { - if (actual_level > 1) { - uint8_t lvl = (actual_level >> 1) + (actual_level >> 2); - set_level(lvl); - #ifdef USE_THERMAL_REGULATION - target_level = lvl; - #ifdef USE_SET_LEVEL_GRADUALLY - // not needed? - //set_level_gradually(lvl); - #endif - #endif - } - else { - set_state(off_state, 0); - } - } - // all other modes, just turn off when voltage is low - else { - set_state(off_state, 0); - } -} - - -void setup() { - #ifdef START_AT_MEMORIZED_LEVEL - // dual switch: e-switch + power clicky - // power clicky acts as a momentary mode - load_config(); - - #ifdef USE_MUGGLE_MODE - if (muggle_mode_active) - push_state(muggle_state, memorized_level); - else - #endif - if (button_is_pressed()) - // hold button to go to moon - push_state(steady_state, 1); - else - // otherwise use memory - push_state(steady_state, memorized_level); - - #else // if not START_AT_MEMORIZED_LEVEL - - // blink at power-on to let user know power is connected - set_level(RAMP_SIZE/8); - delay_4ms(3); - set_level(0); - - load_config(); - - #ifdef USE_TINT_RAMPING - // add tint ramping underneath every other state - push_state(tint_ramping_state, 0); - #endif // ifdef USE_TINT_RAMPING - - #ifdef USE_MUGGLE_MODE - if (muggle_mode_active) - push_state(muggle_state, (MUGGLE_FLOOR+MUGGLE_CEILING)/2); - else - #endif - push_state(off_state, 0); - - #endif // ifdef START_AT_MEMORIZED_LEVEL -} - - -void loop() { - - StatePtr state = current_state; - - if (0) {} - - #ifdef USE_STROBE_STATE - else if ((state == strobe_state) - || ((state == momentary_state) && (momentary_mode == 1) && (momentary_active)) ) { // also handle momentary strobes - uint8_t st = strobe_type; - - switch(st) { - #if defined(USE_PARTY_STROBE_MODE) || defined(USE_TACTICAL_STROBE_MODE) - #ifdef USE_PARTY_STROBE_MODE - case party_strobe_e: - #endif - #ifdef USE_TACTICAL_STROBE_MODE - case tactical_strobe_e: - #endif - party_tactical_strobe_mode_iter(st); - break; - #endif - - #ifdef USE_LIGHTNING_MODE - case lightning_storm_e: - lightning_storm_iter(); - break; - #endif - - #ifdef USE_BIKE_FLASHER_MODE - case bike_flasher_e: - bike_flasher_iter(); - break; - #endif - } - - } - #endif // #ifdef USE_STROBE_STATE - - #ifdef USE_BORING_STROBE_STATE - else if ((state == boring_strobe_state) - || ((state == momentary_state) && (momentary_mode == 1) && (momentary_active)) ) { // also handle momentary strobes - switch(boring_strobe_type) { - #ifdef USE_POLICE_STROBE_MODE - case 0: // police strobe - police_strobe_iter(); - break; - #endif - - #ifdef USE_SOS_MODE - default: // SOS - sos_mode_iter(); - break; - #endif - } - } - #endif // #ifdef USE_BORING_STROBE_STATE - - #ifdef USE_BATTCHECK - else if (state == battcheck_state) { - battcheck(); - } - #endif - - #ifdef USE_BEACON_MODE - else if (state == beacon_state) { - beacon_mode_iter(); - } - #endif - - #ifdef USE_THERMAL_REGULATION - // TODO: blink out therm_ceil during thermal_config_state? - else if (state == tempcheck_state) { - blink_num(temperature); - nice_delay_ms(1000); - } - #endif - - #ifdef USE_IDLE_MODE - else { - // doze until next clock tick - idle_mode(); - } - #endif - -} diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c deleted file mode 100644 index 31b250f..0000000 --- a/spaghetti-monster/fsm-adc.c +++ /dev/null @@ -1,573 +0,0 @@ -// fsm-adc.c: ADC (voltage, temperature) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// override onboard temperature sensor definition, if relevant -#ifdef USE_EXTERNAL_TEMP_SENSOR -#ifdef ADMUX_THERM -#undef ADMUX_THERM -#endif -#define ADMUX_THERM ADMUX_THERM_EXTERNAL_SENSOR -#endif - -#include <avr/sleep.h> - - -static inline void set_admux_therm() { - #if (ATTINY == 1634) - ADMUX = ADMUX_THERM; - #elif (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - ADMUX = ADMUX_THERM | (1 << ADLAR); - #elif (ATTINY == 841) // FIXME: not tested - ADMUXA = ADMUXA_THERM; - ADMUXB = ADMUXB_THERM; - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; // read temperature - ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Internal ADC reference - #else - #error Unrecognized MCU type - #endif - adc_channel = 1; - adc_sample_count = 0; // first result is unstable - ADC_start_measurement(); -} - -inline void set_admux_voltage() { - #if (ATTINY == 1634) - #ifdef USE_VOLTAGE_DIVIDER // 1.1V / pin7 - ADMUX = ADMUX_VOLTAGE_DIVIDER; - #else // VCC / 1.1V reference - ADMUX = ADMUX_VCC; - #endif - #elif (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - #ifdef USE_VOLTAGE_DIVIDER // 1.1V / pin7 - ADMUX = ADMUX_VOLTAGE_DIVIDER | (1 << ADLAR); - #else // VCC / 1.1V reference - ADMUX = ADMUX_VCC | (1 << ADLAR); - #endif - #elif (ATTINY == 841) // FIXME: not tested - #ifdef USE_VOLTAGE_DIVIDER // 1.1V / pin7 - ADMUXA = ADMUXA_VOLTAGE_DIVIDER; - ADMUXB = ADMUXB_VOLTAGE_DIVIDER; - #else // VCC / 1.1V reference - ADMUXA = ADMUXA_VCC; - ADMUXB = ADMUXB_VCC; - #endif - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - #ifdef USE_VOLTAGE_DIVIDER // 1.1V / ADC input pin - // verify that this is correct!!! untested - ADC0.MUXPOS = ADMUX_VOLTAGE_DIVIDER; // read the requested ADC pin - ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Use internal ADC reference - #else // VCC / 1.1V reference - ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc; // read internal reference - ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_VDDREF_gc; // Vdd (Vcc) be ADC reference - #endif - #else - #error Unrecognized MCU type - #endif - adc_channel = 0; - adc_sample_count = 0; // first result is unstable - ADC_start_measurement(); -} - - -#ifdef TICK_DURING_STANDBY -inline void adc_sleep_mode() { - // needs a special sleep mode to get accurate measurements quickly - // ... full power-down ends up using more power overall, and causes - // some weird issues when the MCU doesn't stay awake enough cycles - // to complete a reading - #ifdef SLEEP_MODE_ADC - // attiny1634 - set_sleep_mode(SLEEP_MODE_ADC); - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - set_sleep_mode(SLEEP_MODE_STANDBY); - #else - #error No ADC sleep mode defined for this hardware. - #endif -} -#endif - -inline void ADC_start_measurement() { - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 841) || (ATTINY == 1634) - ADCSRA |= (1 << ADSC) | (1 << ADIE); - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - ADC0.INTCTRL |= ADC_RESRDY_bm; // enable interrupt - ADC0.COMMAND |= ADC_STCONV_bm; // Start the ADC conversions - #else - #error unrecognized MCU type - #endif -} - -// set up ADC for reading battery voltage -inline void ADC_on() -{ - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) - set_admux_voltage(); - #ifdef USE_VOLTAGE_DIVIDER - // disable digital input on divider pin to reduce power consumption - VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); - #else - // disable digital input on VCC pin to reduce power consumption - //VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); // FIXME: unsure how to handle for VCC pin - #endif - #if (ATTINY == 1634) - //ACSRA |= (1 << ACD); // turn off analog comparator to save power - ADCSRB |= (1 << ADLAR); // left-adjust flag is here instead of ADMUX - #endif - // enable, start, auto-retrigger, prescale - ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | ADC_PRSCL; - // end tiny25/45/85 - #elif (ATTINY == 841) // FIXME: not tested, missing left-adjust - ADCSRB = 0; // Right adjusted, auto trigger bits cleared. - //ADCSRA = (1 << ADEN ) | 0b011; // ADC on, prescaler division factor 8. - set_admux_voltage(); - // enable, start, auto-retrigger, prescale - ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | ADC_PRSCL; - //ADCSRA |= (1 << ADSC); // start measuring - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - VREF.CTRLA |= VREF_ADC0REFSEL_1V1_gc; // Set Vbg ref to 1.1V - // Enabled, free-running (aka, auto-retrigger), run in standby - ADC0.CTRLA = ADC_ENABLE_bm | ADC_FREERUN_bm | ADC_RUNSTBY_bm; - // set a INITDLY value because the AVR manual says so (section 30.3.5) - // (delay 1st reading until Vref is stable) - ADC0.CTRLD |= ADC_INITDLY_DLY16_gc; - set_admux_voltage(); - #else - #error Unrecognized MCU type - #endif -} - -inline void ADC_off() { - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - ADC0.CTRLA &= ~(ADC_ENABLE_bm); // disable the ADC - #else - ADCSRA &= ~(1<<ADEN); //ADC off - #endif -} - -#ifdef USE_VOLTAGE_DIVIDER -static inline uint8_t calc_voltage_divider(uint16_t value) { - // use 9.7 fixed-point to get sufficient precision - uint16_t adc_per_volt = ((ADC_44<<5) - (ADC_22<<5)) / (44-22); - // shift incoming value into a matching position - uint8_t result = ((value / adc_per_volt) - + VOLTAGE_FUDGE_FACTOR - #ifdef USE_VOLTAGE_CORRECTION - + VOLT_CORR - 7 - #endif - ) >> 1; - return result; -} -#endif - -// Each full cycle runs ~2X per second with just voltage enabled, -// or ~1X per second with voltage and temperature. -#if defined(USE_LVP) && defined(USE_THERMAL_REGULATION) -#define ADC_CYCLES_PER_SECOND 1 -#else -#define ADC_CYCLES_PER_SECOND 2 -#endif - -#ifdef AVRXMEGA3 // ATTINY816, 817, etc -#define ADC_vect ADC0_RESRDY_vect -#endif -// happens every time the ADC sampler finishes a measurement -ISR(ADC_vect) { - - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - ADC0.INTFLAGS = ADC_RESRDY_bm; // clear the interrupt - #endif - - if (adc_sample_count) { - - uint16_t m; // latest measurement - uint16_t s; // smoothed measurement - uint8_t channel = adc_channel; - - // update the latest value - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - // Use the factory calibrated values in SIGROW.TEMPSENSE0 and SIGROW.TEMPSENSE1 - // to calculate a temperature reading in Kelvin, then left-align it. - if (channel == 1) { // thermal, convert ADC reading to left-aligned Kelvin - int8_t sigrow_offset = SIGROW.TEMPSENSE1; // Read signed value from signature row - uint8_t sigrow_gain = SIGROW.TEMPSENSE0; // Read unsigned value from signature row - uint32_t temp = ADC0.RES - sigrow_offset; - temp *= sigrow_gain; // Result might overflow 16 bit variable (10bit+8bit) - temp += 0x80; // Add 1/2 to get correct rounding on division below - temp >>= 8; // Divide result to get Kelvin - m = (temp << 6); // left align it - } - else { m = (ADC0.RES << 6); } // voltage, force left-alignment - - #else - m = ADC; - #endif - adc_raw[channel] = m; - - // lowpass the value - //s = adc_smooth[channel]; // easier to read - uint16_t *v = adc_smooth + channel; // compiles smaller - s = *v; - if (m > s) { s++; } - if (m < s) { s--; } - //adc_smooth[channel] = s; - *v = s; - - // track what woke us up, and enable deferred logic - irq_adc = 1; - - } - - // the next measurement isn't the first - adc_sample_count = 1; - // rollover doesn't really matter - //adc_sample_count ++; - -} - -void adc_deferred() { - irq_adc = 0; // event handled - - #ifdef USE_PSEUDO_RAND - // real-world entropy makes this a true random, not pseudo - // Why here instead of the ISR? Because it makes the time-critical ISR - // code a few cycles faster and we don't need crypto-grade randomness. - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - pseudo_rand_seed += ADC0.RESL; // right aligned, not left... so should be equivalent? - #else - pseudo_rand_seed += (ADCL >> 6) + (ADCH << 2); - #endif - #endif - - // the ADC triggers repeatedly when it's on, but we only need to run the - // voltage and temperature regulation stuff once in a while...so disable - // this after each activation, until it's manually enabled again - if (! adc_deferred_enable) return; - - // disable after one iteration - adc_deferred_enable = 0; - - // what is being measured? 0 = battery voltage, 1 = temperature - uint8_t adc_step; - - #if defined(USE_LVP) && defined(USE_THERMAL_REGULATION) - // do whichever one is currently active - adc_step = adc_channel; - #else - // unless there's no temperature sensor... then just do voltage - adc_step = 0; - #endif - - #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP) - // in sleep mode, turn off after just one measurement - // (having the ADC on raises standby power by about 250 uA) - // (and the usual standby level is only ~20 uA) - if (go_to_standby) { - ADC_off(); - // if any measurements were in progress, they're done now - adc_active_now = 0; - // also, only check the battery while asleep, not the temperature - adc_channel = 0; - } - #endif - - if (0) {} // placeholder for easier syntax - - #ifdef USE_LVP - else if (0 == adc_step) { // voltage - ADC_voltage_handler(); - #ifdef USE_THERMAL_REGULATION - // set the correct type of measurement for next time - if (! go_to_standby) set_admux_therm(); - #endif - } - #endif - - #ifdef USE_THERMAL_REGULATION - else if (1 == adc_step) { // temperature - ADC_temperature_handler(); - #ifdef USE_LVP - // set the correct type of measurement for next time - set_admux_voltage(); - #endif - } - #endif - - if (adc_reset) adc_reset --; -} - - -#ifdef USE_LVP -static inline void ADC_voltage_handler() { - // rate-limit low-voltage warnings to a max of 1 per N seconds - static uint8_t lvp_timer = 0; - #define LVP_TIMER_START (VOLTAGE_WARNING_SECONDS*ADC_CYCLES_PER_SECOND) // N seconds between LVP warnings - - #ifdef NO_LVP_WHILE_BUTTON_PRESSED - // don't run if button is currently being held - // (because the button causes a reading of zero volts) - if (button_last_state) return; - #endif - - uint16_t measurement; - - // latest ADC value - if (adc_reset) { // just after waking, don't lowpass - measurement = adc_raw[0]; - adc_smooth[0] = measurement; // no lowpass, just use the latest value - } - #ifdef USE_LOWPASS_WHILE_ASLEEP - else if (go_to_standby) { // weaker lowpass while asleep - // occasionally the aux LED color can oscillate during standby, - // while using "voltage" mode ... so try to reduce the oscillation - uint16_t r = adc_raw[0]; - uint16_t s = adc_smooth[0]; - #if 0 - // fixed-rate lowpass, stable but very slow - // (move by only 0.5 ADC units per measurement, 1 ADC unit = 64) - if (r < s) { s -= 32; } - if (r > s) { s += 32; } - #elif 1 - // 1/8th proportional lowpass, faster but less stable - int16_t diff = (r/8) - (s/8); - s += diff; - #else - // 50% proportional lowpass, fastest but least stable - s = (r>>1) + (s>>1); - #endif - adc_smooth[0] = s; - measurement = s; - } - #endif - else measurement = adc_smooth[0]; - - // values stair-step between intervals of 64, with random variations - // of 1 or 2 in either direction, so if we chop off the last 6 bits - // it'll flap between N and N-1... but if we add half an interval, - // the values should be really stable after right-alignment - // (instead of 99.98, 100.00, and 100.02, it'll hit values like - // 100.48, 100.50, and 100.52... which are stable when truncated) - //measurement += 32; - //measurement = (measurement + 16) >> 5; - measurement = (measurement + 16) & 0xffe0; // 1111 1111 1110 0000 - - #ifdef USE_VOLTAGE_DIVIDER - voltage = calc_voltage_divider(measurement); - #else - // calculate actual voltage: volts * 10 - // ADC = 1.1 * 1024 / volts - // volts = 1.1 * 1024 / ADC - voltage = ((uint16_t)(2*1.1*1024*10)/(measurement>>6) - + VOLTAGE_FUDGE_FACTOR - #ifdef USE_VOLTAGE_CORRECTION - + VOLT_CORR - 7 - #endif - ) >> 1; - #endif - - // if low, callback EV_voltage_low / EV_voltage_critical - // (but only if it has been more than N seconds since last call) - if (lvp_timer) { - lvp_timer --; - } else { // it has been long enough since the last warning - #ifdef DUAL_VOLTAGE_FLOOR - if (((voltage < VOLTAGE_LOW) && (voltage > DUAL_VOLTAGE_FLOOR)) || (voltage < DUAL_VOLTAGE_LOW_LOW)) { - #else - if (voltage < VOLTAGE_LOW) { - #endif - // send out a warning - emit(EV_voltage_low, 0); - // reset rate-limit counter - lvp_timer = LVP_TIMER_START; - } - } -} -#endif - - -#ifdef USE_THERMAL_REGULATION -// generally happens once per second while awake -static inline void ADC_temperature_handler() { - // coarse adjustment - #ifndef THERM_LOOKAHEAD - #define THERM_LOOKAHEAD 4 - #endif - // reduce frequency of minor warnings - #ifndef THERM_NEXT_WARNING_THRESHOLD - #define THERM_NEXT_WARNING_THRESHOLD 24 - #endif - // fine-grained adjustment - // how proportional should the adjustments be? - #ifndef THERM_RESPONSE_MAGNITUDE - #define THERM_RESPONSE_MAGNITUDE 64 - #endif - // acceptable temperature window size in C - #define THERM_WINDOW_SIZE 2 - - // TODO? make this configurable per build target? - // (shorter time for hosts with a lower power-to-mass ratio) - // (because then it'll have smaller responses) - #define NUM_TEMP_HISTORY_STEPS 8 // don't change; it'll break stuff - static uint8_t history_step = 0; - static uint16_t temperature_history[NUM_TEMP_HISTORY_STEPS]; - static int8_t warning_threshold = 0; - - if (adc_reset) { // wipe out old data - // ignore average, use latest sample - uint16_t foo = adc_raw[1]; - adc_smooth[1] = foo; - - // forget any past measurements - for(uint8_t i=0; i<NUM_TEMP_HISTORY_STEPS; i++) - temperature_history[i] = (foo + 16) >> 5; - } - - // latest 16-bit ADC reading - uint16_t measurement = adc_smooth[1]; - - // values stair-step between intervals of 64, with random variations - // of 1 or 2 in either direction, so if we chop off the last 6 bits - // it'll flap between N and N-1... but if we add half an interval, - // the values should be really stable after right-alignment - // (instead of 99.98, 100.00, and 100.02, it'll hit values like - // 100.48, 100.50, and 100.52... which are stable when truncated) - //measurement += 32; - measurement = (measurement + 16) >> 5; - //measurement = (measurement + 16) & 0xffe0; // 1111 1111 1110 0000 - - // let the UI see the current temperature in C - // Convert ADC units to Celsius (ish) - #ifndef USE_EXTERNAL_TEMP_SENSOR - // onboard sensor for attiny25/45/85/1634 - temperature = (measurement>>1) + THERM_CAL_OFFSET + (int16_t)TH_CAL - 275; - #else - // external sensor - temperature = EXTERN_TEMP_FORMULA(measurement>>1) + THERM_CAL_OFFSET + (int16_t)TH_CAL; - #endif - - // how much has the temperature changed between now and a few seconds ago? - int16_t diff; - diff = measurement - temperature_history[history_step]; - - // update / rotate the temperature history - temperature_history[history_step] = measurement; - history_step = (history_step + 1) & (NUM_TEMP_HISTORY_STEPS-1); - - // PI[D]: guess what the temperature will be in a few seconds - uint16_t pt; // predicted temperature - pt = measurement + (diff * THERM_LOOKAHEAD); - - // convert temperature limit from C to raw 16-bit ADC units - // C = (ADC>>6) - 275 + THERM_CAL_OFFSET + TH_CAL; - // ... so ... - // (C + 275 - THERM_CAL_OFFSET - TH_CAL) << 6 = ADC; - uint16_t ceil = (TH_CEIL + 275 - TH_CAL - THERM_CAL_OFFSET) << 1; - int16_t offset = pt - ceil; - - // bias small errors toward zero, while leaving large errors mostly unaffected - // (a diff of 1 C is 2 ADC units, * 4 for therm lookahead, so it becomes 8) - // (but a diff of 1 C should only send a warning of magnitude 1) - // (this also makes it only respond to small errors at the time the error - // happened, not after the temperature has stabilized) - for(uint8_t foo=0; foo<3; foo++) { - if (offset > 0) { - offset --; - } else if (offset < 0) { - offset ++; - } - } - - // Too hot? - // (if it's too hot and not getting cooler...) - if ((offset > 0) && (diff > -1)) { - // accumulated error isn't big enough yet to send a warning - if (warning_threshold > 0) { - warning_threshold -= offset; - } else { // error is big enough; send a warning - // how far above the ceiling? - // original method works, but is too slow on some small hosts: - // (and typically has a minimum response magnitude of 2 instead of 1) - // int16_t howmuch = offset; - // ... so increase the amount, except for small values - // (for example, 1:1, 2:1, 3:3, 4:5, 6:9, 8:13, 10:17, 40:77) - // ... and let us tune the response per build target if desired - int16_t howmuch = (offset + offset - 3) * THERM_RESPONSE_MAGNITUDE / 128; - if (howmuch < 1) howmuch = 1; - warning_threshold = THERM_NEXT_WARNING_THRESHOLD - (uint8_t)howmuch; - - // send a warning - emit(EV_temperature_high, howmuch); - } - } - - // Too cold? - // (if it's too cold and still getting colder...) - // the temperature is this far below the floor: - #define BELOW (offset + (THERM_WINDOW_SIZE<<1)) - else if ((BELOW < 0) && (diff < 0)) { - // accumulated error isn't big enough yet to send a warning - if (warning_threshold < 0) { - warning_threshold -= BELOW; - } else { // error is big enough; send a warning - warning_threshold = (-THERM_NEXT_WARNING_THRESHOLD) - BELOW; - - // how far below the floor? - // int16_t howmuch = ((-BELOW) >> 1) * THERM_RESPONSE_MAGNITUDE / 128; - int16_t howmuch = (-BELOW) >> 1; - // send a notification (unless voltage is low) - // (LVP and underheat warnings fight each other) - if (voltage > (VOLTAGE_LOW + 1)) - emit(EV_temperature_low, howmuch); - } - } - #undef BELOW - - // Goldilocks? - // (temperature is within target window, or at least heading toward it) - else { - // send a notification (unless voltage is low) - // (LVP and temp-okay events fight each other) - if (voltage > VOLTAGE_LOW) - emit(EV_temperature_okay, 0); - } -} -#endif - - -#ifdef USE_BATTCHECK -#ifdef BATTCHECK_4bars -PROGMEM const uint8_t voltage_blinks[] = { - 30, 35, 38, 40, 42, 99, -}; -#endif -#ifdef BATTCHECK_6bars -PROGMEM const uint8_t voltage_blinks[] = { - 30, 34, 36, 38, 40, 41, 43, 99, -}; -#endif -#ifdef BATTCHECK_8bars -PROGMEM const uint8_t voltage_blinks[] = { - 30, 33, 35, 37, 38, 39, 40, 41, 42, 99, -}; -#endif -void battcheck() { - #ifdef BATTCHECK_VpT - blink_num(voltage); - #else - uint8_t i; - for(i=0; - voltage >= pgm_read_byte(voltage_blinks + i); - i++) {} - #ifdef DONT_DELAY_AFTER_BATTCHECK - blink_digit(i); - #else - if (blink_digit(i)) - nice_delay_ms(1000); - #endif - #endif -} -#endif - diff --git a/spaghetti-monster/fsm-adc.h b/spaghetti-monster/fsm-adc.h deleted file mode 100644 index 1bb67ed..0000000 --- a/spaghetti-monster/fsm-adc.h +++ /dev/null @@ -1,112 +0,0 @@ -// fsm-adc.h: ADC (voltage, temperature) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION) -// use raw value instead of lowpassed value for the next N measurements -// (2 = 1 for voltage + 1 for temperature) -volatile uint8_t adc_reset = 2; -#endif - -#ifdef USE_LVP -// default 5 seconds between low-voltage warning events -#ifndef VOLTAGE_WARNING_SECONDS -#define VOLTAGE_WARNING_SECONDS 5 -#endif -// low-battery threshold in volts * 10 -#ifndef VOLTAGE_LOW -#define VOLTAGE_LOW 29 -#endif -// battery is low but not critical -#ifndef VOLTAGE_RED -#define VOLTAGE_RED 33 -#endif -// MCU sees voltage 0.X volts lower than actual, add X/2 to readings -#ifndef VOLTAGE_FUDGE_FACTOR -#ifdef USE_VOLTAGE_DIVIDER -#define VOLTAGE_FUDGE_FACTOR 0 -#else -#define VOLTAGE_FUDGE_FACTOR 5 -#endif -#endif - -#ifdef TICK_DURING_STANDBY -volatile uint8_t adc_active_now = 0; // sleep LVP needs a different sleep mode -#endif -volatile uint8_t irq_adc = 0; // ADC interrupt happened? -uint8_t adc_sample_count = 0; // skip the first sample; it's junk -uint8_t adc_channel = 0; // 0=voltage, 1=temperature -uint16_t adc_raw[2]; // last ADC measurements (0=voltage, 1=temperature) -uint16_t adc_smooth[2]; // lowpassed ADC measurements (0=voltage, 1=temperature) -// ADC code is split into two parts: -// - ISR: runs immediately at each interrupt, does the bare minimum because time is critical here -// - deferred: the bulk of the logic runs later when time isn't so critical -uint8_t adc_deferred_enable = 0; // stop waiting and run the deferred code -void adc_deferred(); // do the actual ADC-related calculations - -static inline void ADC_voltage_handler(); -uint8_t voltage = 0; -#ifdef USE_VOLTAGE_CORRECTION - #ifdef USE_CFG - #define VOLT_CORR cfg.voltage_correction - #else - // same 0.05V units as fudge factor, - // but 7 is neutral, and the expected range is from 1 to 13 - uint8_t voltage_correction = 7; - #define VOLT_CORR voltage_correction - #endif -#endif -#ifdef USE_LVP -void low_voltage(); -#endif - -#ifdef USE_BATTCHECK -void battcheck(); -#ifdef BATTCHECK_VpT -#define USE_BLINK_NUM -#endif -#if defined(BATTCHECK_8bars) || defined(BATTCHECK_6bars) || defined(BATTCHECK_4bars) -#define USE_BLINK_DIGIT -#endif -#endif -#endif // ifdef USE_LVP - - -#ifdef USE_THERMAL_REGULATION -// try to keep temperature below 45 C -#ifndef DEFAULT_THERM_CEIL -#define DEFAULT_THERM_CEIL 45 -#endif -// don't allow user to set ceiling above 70 C -#ifndef MAX_THERM_CEIL -#define MAX_THERM_CEIL 70 -#endif -// Local per-MCU calibration value -#ifndef THERM_CAL_OFFSET -#define THERM_CAL_OFFSET 0 -#endif -// temperature now, in C (ish) -int16_t temperature; -#ifdef USE_CFG - #define TH_CEIL cfg.therm_ceil - #define TH_CAL cfg.therm_cal_offset -#else - #define TH_CEIL therm_ceil - #define TH_CAL therm_cal_offset - uint8_t therm_ceil = DEFAULT_THERM_CEIL; - int8_t therm_cal_offset = 0; -#endif -static inline void ADC_temperature_handler(); -#endif // ifdef USE_THERMAL_REGULATION - - -inline void ADC_on(); -inline void ADC_off(); -inline void ADC_start_measurement(); - -#ifdef TICK_DURING_STANDBY -inline void adc_sleep_mode(); -#endif - diff --git a/spaghetti-monster/fsm-channels.c b/spaghetti-monster/fsm-channels.c deleted file mode 100644 index cc78536..0000000 --- a/spaghetti-monster/fsm-channels.c +++ /dev/null @@ -1,357 +0,0 @@ -// fsm-channels.c: Channel mode functions for SpaghettiMonster. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "fsm-ramping.h" - - -#if NUM_CHANNEL_MODES > 1 -void set_channel_mode(uint8_t mode) { - if (mode == channel_mode) return; // abort if nothing to do - - uint8_t cur_level = actual_level; - - // turn off old LEDs before changing channel - set_level(0); - - // change the channel - channel_mode = mode; - - // update the LEDs - set_level(cur_level); -} -#endif // if NUM_CHANNEL_MODES > 1 - - -#ifdef USE_CALC_2CH_BLEND -// calculate a "tint ramp" blend between 2 channels -// results are placed in *warm and *cool vars -// brightness : total amount of light units to distribute -// top : maximum allowed brightness per channel -// blend : ratio between warm and cool (0 = warm, 128 = 50%, 255 = cool) -void calc_2ch_blend( - PWM_DATATYPE *warm, - PWM_DATATYPE *cool, - PWM_DATATYPE brightness, - PWM_DATATYPE top, - uint8_t blend) { - - #ifndef TINT_RAMPING_CORRECTION - #define TINT_RAMPING_CORRECTION 26 // 140% brightness at middle tint - #endif - - // calculate actual PWM levels based on a single-channel ramp - // and a blend value - PWM_DATATYPE warm_PWM, cool_PWM; - PWM_DATATYPE2 base_PWM = brightness; - - #if defined(TINT_RAMPING_CORRECTION) && (TINT_RAMPING_CORRECTION > 0) - uint8_t level = actual_level - 1; - - // middle tints sag, so correct for that effect - // by adding extra power which peaks at the middle tint - // (correction is only necessary when PWM is fast) - if (level > HALFSPEED_LEVEL) { - base_PWM = brightness - + ((((PWM_DATATYPE2)brightness) * TINT_RAMPING_CORRECTION / 64) - * triangle_wave(blend) / 255); - } - // fade the triangle wave out when above 100% power, - // so it won't go over 200% - if (brightness > top) { - base_PWM -= 2 * ( - ((brightness - top) * TINT_RAMPING_CORRECTION / 64) - * triangle_wave(blend) / 255 - ); - } - // guarantee no more than 200% power - if (base_PWM > (top << 1)) { base_PWM = top << 1; } - #endif - - cool_PWM = (((PWM_DATATYPE2)blend * (PWM_DATATYPE2)base_PWM) + 127) / 255; - warm_PWM = base_PWM - cool_PWM; - // when running at > 100% power, spill extra over to other channel - if (cool_PWM > top) { - warm_PWM += (cool_PWM - top); - cool_PWM = top; - } else if (warm_PWM > top) { - cool_PWM += (warm_PWM - top); - warm_PWM = top; - } - - *warm = warm_PWM; - *cool = cool_PWM; -} -#endif // ifdef USE_CALC_2CH_BLEND - - -#ifdef USE_HSV2RGB -RGB_t hsv2rgb(uint8_t h, uint8_t s, uint16_t v) { - RGB_t color; - - if (s == 0) { // grey - color.r = color.g = color.b = v; - return color; - } - - uint8_t region; - uint16_t fpart; - uint16_t high, low, rising, falling; - - // hue has 6 segments, 0-5 - region = ((uint16_t)h * 6) >> 8; - // find remainder part, make it from 0-255 - fpart = ((uint16_t)h * 6) - (region << 8); - - // calculate graph segments, doing integer multiplication - // TODO: calculate 16-bit results, not 8-bit - high = v; - low = ((uint32_t)v * (255 - s)) >> 8; - // TODO: use a cosine crossfade instead of linear - // (because it looks better and feels more natural) - falling = ((uint32_t)v * (255 - ((s * fpart) >> 8))) >> 8; - rising = ((uint32_t)v * (255 - ((s * (255 - fpart)) >> 8))) >> 8; - - // default floor - color.r = low; - color.g = low; - color.b = low; - - // assign graph shapes based on color cone region - switch (region) { - case 0: - color.r = high; - color.g = rising; - //color.b = low; - break; - case 1: - color.r = falling; - color.g = high; - //color.b = low; - break; - case 2: - //color.r = low; - color.g = high; - color.b = rising; - break; - case 3: - //color.r = low; - color.g = falling; - color.b = high; - break; - case 4: - color.r = rising; - //color.g = low; - color.b = high; - break; - default: - color.r = high; - //color.g = low; - color.b = falling; - break; - } - - return color; -} -#endif // ifdef USE_HSV2RGB - - -///// Common set_level_*() functions shared by multiple lights ///// -// (unique lights should use their own, -// but these common versions cover most of the common hardware designs) - -// TODO: upgrade some older lights to dynamic PWM -// TODO: 1ch w/ dynamic PWM -// TODO: 1ch w/ dynamic PWM and opamp enable pins? -// TODO: 2ch stacked w/ dynamic PWM -// TODO: 2ch stacked w/ dynamic PWM and opamp enable pins? - - -#ifdef USE_SET_LEVEL_1CH -// single set of LEDs with 1 power channel -void set_level_1ch(uint8_t level) { - if (level == 0) { - LOW_PWM_LVL = 0; - } else { - level --; // PWM array index = level - 1 - LOW_PWM_LVL = PWM_GET(low_pwm_levels, level); - } -} -#endif - - -#ifdef USE_SET_LEVEL_2CH_STACKED -// single set of LEDs with 2 stacked power channels, DDFET+1 or DDFET+linear -void set_level_2ch_stacked(uint8_t level) { - if (level == 0) { - LOW_PWM_LVL = 0; - HIGH_PWM_LVL = 0; - } else { - level --; // PWM array index = level - 1 - LOW_PWM_LVL = PWM_GET(low_pwm_levels, level); - HIGH_PWM_LVL = PWM_GET(high_pwm_levels, level); - } -} -#endif - - -#ifdef USE_SET_LEVEL_3CH_STACKED -// single set of LEDs with 3 stacked power channels, like DDFET+N+1 -void set_level_3ch_stacked(uint8_t level) { - if (level == 0) { - LOW_PWM_LVL = 0; - MED_PWM_LVL = 0; - HIGH_PWM_LVL = 0; - } else { - level --; // PWM array index = level - 1 - LOW_PWM_LVL = PWM_GET(low_pwm_levels, level); - MED_PWM_LVL = PWM_GET(med_pwm_levels, level); - HIGH_PWM_LVL = PWM_GET(high_pwm_levels, level); - } -} -#endif - - -#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY)) -void set_level_2ch_blend() { - #ifndef TINT_RAMPING_CORRECTION - #define TINT_RAMPING_CORRECTION 26 // 140% brightness at middle tint - #endif - - // calculate actual PWM levels based on a single-channel ramp - // and a global tint value - //PWM_DATATYPE brightness = PWM_GET(pwm1_levels, level); - uint16_t brightness = PWM1_LVL; - uint16_t warm_PWM, cool_PWM; - #ifdef USE_STACKED_DYN_PWM - uint16_t top = PWM1_TOP; - //uint16_t top = PWM_GET(pwm_tops, actual_level-1); - #else - const uint16_t top = PWM_TOP; - #endif - - // auto-tint modes - uint8_t mytint; - uint8_t level = actual_level - 1; - #if 1 - // perceptual by ramp level - if (tint == 0) { mytint = 255 * (uint16_t)level / RAMP_SIZE; } - else if (tint == 255) { mytint = 255 - (255 * (uint16_t)level / RAMP_SIZE); } - #else - // linear with power level - //if (tint == 0) { mytint = brightness; } - //else if (tint == 255) { mytint = 255 - brightness; } - #endif - // stretch 1-254 to fit 0-255 range (hits every value except 98 and 198) - else { mytint = (tint * 100 / 99) - 1; } - - PWM_DATATYPE2 base_PWM = brightness; - #if defined(TINT_RAMPING_CORRECTION) && (TINT_RAMPING_CORRECTION > 0) - // middle tints sag, so correct for that effect - // by adding extra power which peaks at the middle tint - // (correction is only necessary when PWM is fast) - if (level > HALFSPEED_LEVEL) { - base_PWM = brightness - + ((((PWM_DATATYPE2)brightness) * TINT_RAMPING_CORRECTION / 64) * triangle_wave(mytint) / 255); - } - // fade the triangle wave out when above 100% power, - // so it won't go over 200% - if (brightness > top) { - base_PWM -= 2 * ( - ((brightness - top) * TINT_RAMPING_CORRECTION / 64) - * triangle_wave(mytint) / 255 - ); - } - // guarantee no more than 200% power - if (base_PWM > (top << 1)) { base_PWM = top << 1; } - #endif - - cool_PWM = (((PWM_DATATYPE2)mytint * (PWM_DATATYPE2)base_PWM) + 127) / 255; - warm_PWM = base_PWM - cool_PWM; - // when running at > 100% power, spill extra over to other channel - if (cool_PWM > top) { - warm_PWM += (cool_PWM - top); - cool_PWM = top; - } else if (warm_PWM > top) { - cool_PWM += (warm_PWM - top); - warm_PWM = top; - } - - TINT1_LVL = warm_PWM; - TINT2_LVL = cool_PWM; - - // disable the power channel, if relevant - #ifdef LED_ENABLE_PIN - if (warm_PWM) - LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); - else - LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); - #endif - #ifdef LED2_ENABLE_PIN - if (cool_PWM) - LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); - else - LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); - #endif -} -#endif // ifdef USE_TINT_RAMPING - - -#ifdef USE_GRADUAL_TICK_1CH -void gradual_tick_1ch() { - GRADUAL_TICK_SETUP(); - - GRADUAL_ADJUST_1CH(low_pwm_levels, LOW_PWM_LVL); - - // did we go far enough to hit the next defined ramp level? - // if so, update the main ramp level tracking var - if ((LOW_PWM_LVL == PWM_GET(low_pwm_levels, gt))) - { - GRADUAL_IS_ACTUAL(); - } -} -#endif - - -#ifdef USE_GRADUAL_TICK_2CH_STACKED -void gradual_tick_2ch_stacked() { - GRADUAL_TICK_SETUP(); - - GRADUAL_ADJUST(low_pwm_levels, LOW_PWM_LVL, PWM_TOP); - GRADUAL_ADJUST_1CH(high_pwm_levels, HIGH_PWM_LVL); - - // did we go far enough to hit the next defined ramp level? - // if so, update the main ramp level tracking var - if ( (LOW_PWM_LVL == PWM_GET(low_pwm_levels, gt)) - && (HIGH_PWM_LVL == PWM_GET(high_pwm_levels, gt)) - ) - { - GRADUAL_IS_ACTUAL(); - } -} -#endif - - -#ifdef USE_GRADUAL_TICK_3CH_STACKED -void gradual_tick_3ch_stacked() { - GRADUAL_TICK_SETUP(); - - GRADUAL_ADJUST(low_pwm_levels, LOW_PWM_LVL, PWM_TOP); - GRADUAL_ADJUST(med_pwm_levels, MED_PWM_LVL, PWM_TOP); - GRADUAL_ADJUST_1CH(high_pwm_levels, HIGH_PWM_LVL); - - // did we go far enough to hit the next defined ramp level? - // if so, update the main ramp level tracking var - if ( (LOW_PWM_LVL == PWM_GET(low_pwm_levels, gt)) - && (MED_PWM_LVL == PWM_GET(med_pwm_levels, gt)) - && (HIGH_PWM_LVL == PWM_GET(high_pwm_levels, gt)) - ) - { - GRADUAL_IS_ACTUAL(); - } -} -#endif - - diff --git a/spaghetti-monster/fsm-channels.h b/spaghetti-monster/fsm-channels.h deleted file mode 100644 index 218f4f5..0000000 --- a/spaghetti-monster/fsm-channels.h +++ /dev/null @@ -1,141 +0,0 @@ -// fsm-channels.h: Channel mode functions for SpaghettiMonster. -// Copyright (C) 2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// always enable channel modes, even if there is only one -#define USE_CHANNEL_MODES - -// typedefs -typedef void SetLevelFunc(uint8_t level); -typedef SetLevelFunc * SetLevelFuncPtr; - -typedef bool GradualTickFunc(uint8_t gt); -typedef GradualTickFunc * GradualTickFuncPtr; - -// TODO: implement custom 3H handlers -typedef void ChannelArgFunc(); -typedef ChannelArgFunc * ChannelArgFuncPtr; - -typedef struct Channel { - SetLevelFuncPtr set_level; - #ifdef USE_SET_LEVEL_GRADUALLY - GradualTickFuncPtr gradual_tick; - #endif - #ifdef USE_CUSTOM_3H_HANDLERS - // TODO: implement custom 3H handlers - ChannelArgFuncPtr ramp_channel_arg; - #endif - #ifdef USE_CHANNEL_MODE_ARGS - bool has_args; - //uint8_t arg; // is in the config struct, not here - #endif -} Channel; - -Channel channels[]; // values are defined in the hwdef-*.c - -// TODO: size-optimize the case with only 1 channel mode? -// (the arrays and stuff shouldn't be needed) - -#if NUM_CHANNEL_MODES > 1 - #define USE_CHANNEL_MODES - // current multi-channel mode - uint8_t channel_mode = DEFAULT_CHANNEL_MODE; -#else - #define channel_mode 0 -#endif - -#ifdef USE_CUSTOM_CHANNEL_3H_MODES -// different 3H behavior per channel? -// TODO: move to progmem -// TODO: move to Anduril, not FSM -StatePtr channel_3H_modes[NUM_CHANNEL_MODES]; -#endif - -//#ifdef USE_CHANNEL_MODE_TOGGLES -#if NUM_CHANNEL_MODES > 1 -// user can take unwanted modes out of the rotation -// bitmask -#ifdef USE_CFG - #define channel_mode_enabled(n) ((cfg.channel_modes_enabled >> n) & 1) - #define channel_mode_enable(n) cfg.channel_modes_enabled |= (1 << n) - #define channel_mode_disable(n) cfg.channel_modes_enabled &= ((1 << n) ^ 0xff) -#else - uint16_t channel_modes_enabled = CHANNEL_MODES_ENABLED; - #define channel_mode_enabled(n) ((channel_modes_enabled >> n) & 1) - #define channel_mode_enable(n) channel_modes_enabled |= (1 << n) - #define channel_mode_disable(n) channel_modes_enabled &= ((1 << n) ^ 0xff) - #endif -#endif - -#ifdef USE_CHANNEL_MODE_ARGS - #ifndef USE_CFG - // one byte of extra data per channel mode, like for tint value - uint8_t channel_mode_args[NUM_CHANNEL_MODES] = { CHANNEL_MODE_ARGS }; - #endif - // which modes respond to their "arg", and which don't? - //const uint8_t channel_has_args = CHANNEL_HAS_ARGS; - //#define channel_has_args(n) ((CHANNEL_HAS_ARGS >> n) & 1) - // struct member - #define channel_has_args(n) (channels[n].has_args) -#endif - -#if NUM_CHANNEL_MODES > 1 -void set_channel_mode(uint8_t mode); -#endif - -#ifdef USE_CALC_2CH_BLEND -void calc_2ch_blend( - PWM_DATATYPE *warm, - PWM_DATATYPE *cool, - PWM_DATATYPE brightness, - PWM_DATATYPE top, - uint8_t blend); -#endif - -#ifdef USE_HSV2RGB -typedef struct RGB_t { - uint16_t r; - uint16_t g; - uint16_t b; -} RGB_t; -RGB_t hsv2rgb(uint8_t h, uint8_t s, uint16_t v); -#endif // ifdef USE_HSV2RGB - - -#ifdef USE_SET_LEVEL_1CH -// TODO: remove this -void set_level_1ch(uint8_t level); -#endif - -#ifdef USE_SET_LEVEL_2CH_STACKED -// TODO: remove this -void set_level_2ch_stacked(uint8_t level); -#endif - -#ifdef USE_SET_LEVEL_3CH_STACKED -// TODO: remove this -void set_level_3ch_stacked(uint8_t level); -#endif - -#if defined(USE_TINT_RAMPING) && (!defined(TINT_RAMP_TOGGLE_ONLY)) -// TODO: remove this -void set_level_2ch_blend(); -#endif - -#ifdef USE_GRADUAL_TICK_1CH -// TODO: remove this -void gradual_tick_1ch(); -#endif - -#ifdef USE_GRADUAL_TICK_2CH_STACKED -// TODO: remove this -void gradual_tick_2ch_stacked(); -#endif - -#ifdef USE_GRADUAL_TICK_3CH_STACKED -// TODO: remove this -void gradual_tick_3ch_stacked(); -#endif - diff --git a/spaghetti-monster/fsm-eeprom.c b/spaghetti-monster/fsm-eeprom.c deleted file mode 100644 index 66cdd78..0000000 --- a/spaghetti-monster/fsm-eeprom.c +++ /dev/null @@ -1,112 +0,0 @@ -// fsm-eeprom.c: EEPROM API for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "fsm-eeprom.h" - -#ifdef USE_EEPROM -#ifdef EEPROM_OVERRIDE -uint8_t *eeprom; -#else -uint8_t eeprom[EEPROM_BYTES]; -#endif - -uint8_t load_eeprom() { - #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) - delay_4ms(2); // wait for power to stabilize - #endif - - cli(); - // check if eeprom has been initialized; abort if it hasn't - uint8_t marker = eeprom_read_byte((uint8_t *)EEP_START); - if (marker != EEP_MARKER) { sei(); return 0; } - - // load the actual data - for(uint8_t i=0; i<EEPROM_BYTES; i++) { - eeprom[i] = eeprom_read_byte((uint8_t *)(EEP_START+1+i)); - } - sei(); - return 1; -} - -void save_eeprom() { - #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) - delay_4ms(2); // wait for power to stabilize - #endif - - cli(); - - // save the actual data - for(uint8_t i=0; i<EEPROM_BYTES; i++) { - eeprom_update_byte((uint8_t *)(EEP_START+1+i), eeprom[i]); - } - - // save the marker last, to indicate the transaction is complete - eeprom_update_byte((uint8_t *)EEP_START, EEP_MARKER); - sei(); -} -#endif - -#ifdef USE_EEPROM_WL -uint8_t eeprom_wl[EEPROM_WL_BYTES]; -uint8_t * eep_wl_prev_offset; - -uint8_t load_eeprom_wl() { - #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) - delay_4ms(2); // wait for power to stabilize - #endif - - cli(); - // check if eeprom has been initialized; abort if it hasn't - uint8_t found = 0; - uint8_t * offset; - for(offset = 0; - offset < (uint8_t *)(EEP_WL_SIZE - EEPROM_WL_BYTES - 1); - offset += (EEPROM_WL_BYTES + 1)) { - if (eeprom_read_byte(offset) == EEP_MARKER) { - found = 1; - eep_wl_prev_offset = offset; - break; - } - } - - if (found) { - // load the actual data - for(uint8_t i=0; i<EEPROM_WL_BYTES; i++) { - eeprom_wl[i] = eeprom_read_byte(offset+1+i); - } - } - sei(); - return found; -} - -void save_eeprom_wl() { - #if defined(LED_ENABLE_PIN) || defined(LED2_ENABLE_PIN) - delay_4ms(2); // wait for power to stabilize - #endif - - cli(); - // erase old state - uint8_t * offset = eep_wl_prev_offset; - for (uint8_t i = 0; i < EEPROM_WL_BYTES+1; i ++) { - eeprom_update_byte(offset+i, 0xFF); - } - - // save new state - offset += EEPROM_WL_BYTES+1; - if (offset > (uint8_t *)(EEP_WL_SIZE-EEPROM_WL_BYTES-1)) offset = 0; - eep_wl_prev_offset = offset; - // marker byte - // FIXME: write the marker last, to signal completed transaction - eeprom_update_byte(offset, EEP_MARKER); - offset ++; - // user data - for(uint8_t i=0; i<EEPROM_WL_BYTES; i++, offset++) { - eeprom_update_byte(offset, eeprom_wl[i]); - } - sei(); -} -#endif - diff --git a/spaghetti-monster/fsm-eeprom.h b/spaghetti-monster/fsm-eeprom.h deleted file mode 100644 index 440d2b3..0000000 --- a/spaghetti-monster/fsm-eeprom.h +++ /dev/null @@ -1,52 +0,0 @@ -// fsm-eeprom.h: EEPROM API for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <avr/eeprom.h> - -// set this higher to enable normal eeprom functions -#ifndef EEPROM_BYTES -#define EEPROM_BYTES 0 -#endif - -// set this higher to enable wear-levelled eeprom functions -#ifndef EEPROM_WL_BYTES -#define EEPROM_WL_BYTES 0 -#endif - -#ifdef USE_EEPROM -// this fails when EEPROM_BYTES is a sizeof() -//#if EEPROM_BYTES >= (EEPSIZE/2) -//#error Requested EEPROM_BYTES too big. -//#endif -#ifdef EEPROM_OVERRIDE -uint8_t *eeprom; -#else -uint8_t eeprom[EEPROM_BYTES]; -#endif -uint8_t load_eeprom(); // returns 1 for success, 0 for no data found -void save_eeprom(); -#define EEP_START (EEPSIZE/2) -#endif - -#ifdef USE_EEPROM_WL -#if EEPROM_WL_BYTES >= (EEPSIZE/4) -#error Requested EEPROM_WL_BYTES too big. -#endif -uint8_t eeprom_wl[EEPROM_WL_BYTES]; -uint8_t load_eeprom_wl(); // returns 1 for success, 0 for no data found -void save_eeprom_wl(); -#define EEP_WL_SIZE (EEPSIZE/2) -#endif - -#if EEPSIZE > 256 -#define EEP_OFFSET_T uint16_t -#else -#define EEP_OFFSET_T uint8_t -#endif - -// if this marker isn't found, the eeprom is assumed to be blank -#define EEP_MARKER 0b10100101 - diff --git a/spaghetti-monster/fsm-events.c b/spaghetti-monster/fsm-events.c deleted file mode 100644 index 6987ae2..0000000 --- a/spaghetti-monster/fsm-events.c +++ /dev/null @@ -1,198 +0,0 @@ -// fsm-events.c: Event-handling functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <util/delay_basic.h> - - -void append_emission(Event event, uint16_t arg) { - uint8_t i; - // find last entry - for(i=0; - (i<EMISSION_QUEUE_LEN) && (emissions[i].event != EV_none); - i++) { } - // add new entry - if (i < EMISSION_QUEUE_LEN) { - emissions[i].event = event; - emissions[i].arg = arg; - } else { - // TODO: if queue full, what should we do? - } -} - -void delete_first_emission() { - uint8_t i; - for(i=0; i<EMISSION_QUEUE_LEN-1; i++) { - emissions[i].event = emissions[i+1].event; - emissions[i].arg = emissions[i+1].arg; - } - emissions[i].event = EV_none; - emissions[i].arg = 0; -} - -void process_emissions() { - while (emissions[0].event != EV_none) { - emit_now(emissions[0].event, emissions[0].arg); - delete_first_emission(); - } -} - -// Call stacked callbacks for the given event until one handles it. -uint8_t emit_now(Event event, uint16_t arg) { - for(int8_t i=state_stack_len-1; i>=0; i--) { - uint8_t err = state_stack[i](event, arg); - if (! err) return 0; - } - return 1; // event not handled -} - -void emit(Event event, uint16_t arg) { - // add this event to the queue for later, - // so we won't use too much time during an interrupt - append_emission(event, arg); -} - -void emit_current_event(uint16_t arg) { - emit(current_event, arg); -} - -void empty_event_sequence() { - current_event = EV_none; - ticks_since_last_event = 0; - // when the user completes an input sequence, interrupt any running timers - // to cancel any delays currently in progress - // This eliminates a whole bunch of extra code: - // before: if (! nice_delay_ms(ms)) {break;} - // after: nice_delay_ms(ms); - interrupt_nice_delays(); -} - -uint8_t push_event(uint8_t ev_type) { // only for use by PCINT_inner() - // don't do this here; do it in PCINT_inner() instead - //ticks_since_last_event = 0; // something happened - - // only click events are sent to this function - current_event |= B_CLICK; - - // handle button presses - if (ev_type == B_PRESS) { - // set press flag - current_event |= B_PRESS; - // increase click counter - if ((current_event & B_COUNT) < (B_COUNT)) { - current_event ++; - } - return 1; // event pushed, even if max clicks already reached - // (will just repeat the max over and over) - } - // handle button releases - else if (ev_type == B_RELEASE) { - // clear the press flag - current_event &= (~B_PRESS); - // if a "hold" event just ended, set the timeout flag - // to indicate that the event is done and can be cleared - if (current_event & B_HOLD) { current_event |= B_TIMEOUT; } - return 1; // event pushed - } - - return 0; // unexpected event type -} - - -// explicitly interrupt these "nice" delays -volatile uint8_t nice_delay_interrupt = 0; -inline void interrupt_nice_delays() { nice_delay_interrupt = 1; } - -// like delay_ms, except it aborts on state change -// return value: -// 0: state changed -// 1: normal completion -uint8_t nice_delay_ms(uint16_t ms) { - /* // delay_zero() implementation - if (ms == 0) { - CLKPR = 1<<CLKPCE; CLKPR = 0; // full speed - _delay_loop_2(BOGOMIPS*95/100/3); - return 1; - } - */ - while(ms-- > 0) { - if (nice_delay_interrupt) { - return 0; - } - - #ifdef USE_DYNAMIC_UNDERCLOCKING - #ifdef USE_RAMPING - uint8_t level = actual_level; // volatile, avoid repeat access - if (level < QUARTERSPEED_LEVEL) { - clock_prescale_set(clock_div_4); - _delay_loop_2(BOGOMIPS*DELAY_FACTOR/100/4); - } - //else if (level < HALFSPEED_LEVEL) { - // clock_prescale_set(clock_div_2); - // _delay_loop_2(BOGOMIPS*95/100/2); - //} - else { - clock_prescale_set(clock_div_1); - _delay_loop_2(BOGOMIPS*DELAY_FACTOR/100); - } - // restore regular clock speed - clock_prescale_set(clock_div_1); - #else - // underclock MCU to save power - clock_prescale_set(clock_div_4); - // wait - _delay_loop_2(BOGOMIPS*DELAY_FACTOR/100/4); - // restore regular clock speed - clock_prescale_set(clock_div_1); - #endif // ifdef USE_RAMPING - #else - // wait - _delay_loop_2(BOGOMIPS*DELAY_FACTOR/100); - #endif // ifdef USE_DYNAMIC_UNDERCLOCKING - - // run pending system processes while we wait - handle_deferred_interrupts(); - - // handle events only afterward, so that any collapsed delays will - // finish running the UI's loop() code before taking any further actions - // (this helps make sure code runs in the correct order) - // (otherwise, a new state's EV_enter runs before the old state's - // loop() has finished, and things can get weird) - process_emissions(); - } - return 1; -} - -#ifdef USE_DYNAMIC_UNDERCLOCKING -void delay_4ms(uint8_t ms) { - while(ms-- > 0) { - // underclock MCU to save power - clock_prescale_set(clock_div_4); - // wait - _delay_loop_2(BOGOMIPS*98/100); - // restore regular clock speed - clock_prescale_set(clock_div_1); - } -} -#else -void delay_4ms(uint8_t ms) { - while(ms-- > 0) { - // wait - _delay_loop_2(BOGOMIPS*398/100); - } -} -#endif -/* -uint8_t nice_delay_4ms(uint8_t ms) { - return nice_delay_ms((uint16_t)ms << 2); -} -*/ - -/* -uint8_t nice_delay_s() { - return nice_delay_4ms(250); -} -*/ - diff --git a/spaghetti-monster/fsm-events.h b/spaghetti-monster/fsm-events.h deleted file mode 100644 index 575af1b..0000000 --- a/spaghetti-monster/fsm-events.h +++ /dev/null @@ -1,221 +0,0 @@ -// fsm-events.h: Event-handling functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <avr/pgmspace.h> - - -// timeout durations in ticks (each tick 1/62th s) -#ifndef HOLD_TIMEOUT -#define HOLD_TIMEOUT 24 -#endif -#ifndef RELEASE_TIMEOUT -#define RELEASE_TIMEOUT 18 -#endif - -// return codes for Event handlers -// Indicates whether this handler consumed (handled) the Event, or -// if the Event should be sent to the next handler in the stack. -#define EVENT_HANDLED 0 -#define EVENT_NOT_HANDLED 1 -#define MISCHIEF_MANAGED EVENT_HANDLED -#define MISCHIEF_NOT_MANAGED EVENT_NOT_HANDLED - -// typedefs -typedef uint8_t Event; -typedef struct Emission { - Event event; - uint16_t arg; -} Emission; - -Event current_event; -// at 0.016 ms per tick, 255 ticks = 4.08 s -static volatile uint16_t ticks_since_last_event = 0; - -// maximum number of events which can be waiting at one time -// (would probably be okay to reduce this to 4, but it's higher to be safe) -#define EMISSION_QUEUE_LEN 16 -// was "volatile" before, changed to regular var since IRQ rewrites seem -// to have removed the need for it to be volatile -// no comment about "volatile emissions" -Emission emissions[EMISSION_QUEUE_LEN]; - -void append_emission(Event event, uint16_t arg); -void delete_first_emission(); -void process_emissions(); -uint8_t emit_now(Event event, uint16_t arg); -void emit(Event event, uint16_t arg); -void emit_current_event(uint16_t arg); -void empty_event_sequence(); -uint8_t push_event(uint8_t ev_type); // only for use by PCINT_inner() - - -// TODO: Maybe move these to their own file... -// ... this probably isn't the right place for delays. -#ifndef DELAY_FACTOR - // adjust the timing of delays, lower = shorter delays - // 90 = 90% delay, 10% for other things - #define DELAY_FACTOR 92 -#endif -inline void interrupt_nice_delays(); -uint8_t nice_delay_ms(uint16_t ms); -//uint8_t nice_delay_s(); -void delay_4ms(uint8_t ms); - - -/* Event structure - * Bit 7: 1 for a button input event, 0 for all others. - * If bit 7 is 1: - * Bits 0,1,2,3: Click counter. Up to 15 clicks. - * Bit 4: 1 for a "press" event, 0 for a "release" event. - * Bit 5: 1 for a "hold" event, 0 otherwise. - * Bit 6: 1 for a "timeout" event, 0 otherwise. - * If bit 7 is 0: - * Sort of ad-hoc, shown in #defines below. - */ - -// event masks / bits -#define B_SYSTEM 0b00000000 -#define B_CLICK 0b10000000 -#define B_TIMEOUT 0b01000000 -#define B_HOLD 0b00100000 -#define B_PRESS 0b00010000 -#define B_RELEASE 0b00000000 -#define B_COUNT 0b00001111 -#define B_FLAGS 0b11110000 - -// Event types -#define EV_none 0 - -// Events which aren't button presses -#define EV_debug (B_SYSTEM|0b01111111) -#define EV_enter_state (B_SYSTEM|0b00001000) -#define EV_leave_state (B_SYSTEM|0b00001001) -#define EV_reenter_state (B_SYSTEM|0b00001010) -#define EV_tick (B_SYSTEM|0b00000001) -#ifdef TICK_DURING_STANDBY -#define EV_sleep_tick (B_SYSTEM|0b00000011) -#endif -#ifdef USE_LVP -#define EV_voltage_low (B_SYSTEM|0b00000100) -#endif -#ifdef USE_THERMAL_REGULATION -#define EV_temperature_high (B_SYSTEM|0b00000101) -#define EV_temperature_low (B_SYSTEM|0b00000110) -#define EV_temperature_okay (B_SYSTEM|0b00000111) -#endif - -// Button press events - -// shouldn't normally happen, but UI might empty_event_sequence() while button -// is down so a release with no recorded prior hold could be possible -#define EV_release (B_CLICK|B_RELEASE|0) - -#define EV_click1_press (B_CLICK|B_PRESS|1) -#define EV_click1_release (B_CLICK|B_RELEASE|1) -#define EV_click1_complete (B_CLICK|B_TIMEOUT|1) -#define EV_1click EV_click1_complete -#define EV_click1_hold (B_CLICK|B_HOLD|B_PRESS|1) -#define EV_click1_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|1) -#define EV_hold EV_click1_hold - -#define EV_click2_press (B_CLICK|B_PRESS|2) -#define EV_click2_release (B_CLICK|B_RELEASE|2) -#define EV_click2_complete (B_CLICK|B_TIMEOUT|2) -#define EV_2clicks EV_click2_complete -#define EV_click2_hold (B_CLICK|B_HOLD|B_PRESS|2) -#define EV_click2_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|2) - -#define EV_click3_press (B_CLICK|B_PRESS|3) -#define EV_click3_release (B_CLICK|B_RELEASE|3) -#define EV_click3_complete (B_CLICK|B_TIMEOUT|3) -#define EV_3clicks EV_click3_complete -#define EV_click3_hold (B_CLICK|B_HOLD|B_PRESS|3) -#define EV_click3_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|3) - -#define EV_click4_press (B_CLICK|B_PRESS|4) -#define EV_click4_release (B_CLICK|B_RELEASE|4) -#define EV_click4_complete (B_CLICK|B_TIMEOUT|4) -#define EV_4clicks EV_click4_complete -#define EV_click4_hold (B_CLICK|B_HOLD|B_PRESS|4) -#define EV_click4_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|4) - -#define EV_click5_press (B_CLICK|B_PRESS|5) -#define EV_click5_release (B_CLICK|B_RELEASE|5) -#define EV_click5_complete (B_CLICK|B_TIMEOUT|5) -#define EV_5clicks EV_click5_complete -#define EV_click5_hold (B_CLICK|B_HOLD|B_PRESS|5) -#define EV_click5_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|5) - -#define EV_click6_press (B_CLICK|B_PRESS|6) -#define EV_click6_release (B_CLICK|B_RELEASE|6) -#define EV_click6_complete (B_CLICK|B_TIMEOUT|6) -#define EV_6clicks EV_click6_complete -#define EV_click6_hold (B_CLICK|B_HOLD|B_PRESS|6) -#define EV_click6_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|6) - -#define EV_click7_press (B_CLICK|B_PRESS|7) -#define EV_click7_release (B_CLICK|B_RELEASE|7) -#define EV_click7_complete (B_CLICK|B_TIMEOUT|7) -#define EV_7clicks EV_click7_complete -#define EV_click7_hold (B_CLICK|B_HOLD|B_PRESS|7) -#define EV_click7_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|7) - -#define EV_click8_press (B_CLICK|B_PRESS|8) -#define EV_click8_release (B_CLICK|B_RELEASE|8) -#define EV_click8_complete (B_CLICK|B_TIMEOUT|8) -#define EV_8clicks EV_click8_complete -#define EV_click8_hold (B_CLICK|B_HOLD|B_PRESS|8) -#define EV_click8_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|8) - -#define EV_click9_press (B_CLICK|B_PRESS|9) -#define EV_click9_release (B_CLICK|B_RELEASE|9) -#define EV_click9_complete (B_CLICK|B_TIMEOUT|9) -#define EV_9clicks EV_click9_complete -#define EV_click9_hold (B_CLICK|B_HOLD|B_PRESS|9) -#define EV_click9_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|9) - -#define EV_click10_press (B_CLICK|B_PRESS|10) -#define EV_click10_release (B_CLICK|B_RELEASE|10) -#define EV_click10_complete (B_CLICK|B_TIMEOUT|10) -#define EV_10clicks EV_click10_complete -#define EV_click10_hold (B_CLICK|B_HOLD|B_PRESS|10) -#define EV_click10_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|10) - -#define EV_click11_press (B_CLICK|B_PRESS|11) -#define EV_click11_release (B_CLICK|B_RELEASE|11) -#define EV_click11_complete (B_CLICK|B_TIMEOUT|11) -#define EV_11clicks EV_click11_complete -#define EV_click11_hold (B_CLICK|B_HOLD|B_PRESS|11) -#define EV_click11_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|11) - -#define EV_click12_press (B_CLICK|B_PRESS|12) -#define EV_click12_release (B_CLICK|B_RELEASE|12) -#define EV_click12_complete (B_CLICK|B_TIMEOUT|12) -#define EV_12clicks EV_click12_complete -#define EV_click12_hold (B_CLICK|B_HOLD|B_PRESS|12) -#define EV_click12_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|12) - -#define EV_click13_press (B_CLICK|B_PRESS|13) -#define EV_click13_release (B_CLICK|B_RELEASE|13) -#define EV_click13_complete (B_CLICK|B_TIMEOUT|13) -#define EV_13clicks EV_click13_complete -#define EV_click13_hold (B_CLICK|B_HOLD|B_PRESS|13) -#define EV_click13_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|13) - -#define EV_click14_press (B_CLICK|B_PRESS|14) -#define EV_click14_release (B_CLICK|B_RELEASE|14) -#define EV_click14_complete (B_CLICK|B_TIMEOUT|14) -#define EV_14clicks EV_click14_complete -#define EV_click14_hold (B_CLICK|B_HOLD|B_PRESS|14) -#define EV_click14_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|14) - -#define EV_click15_press (B_CLICK|B_PRESS|15) -#define EV_click15_release (B_CLICK|B_RELEASE|15) -#define EV_click15_complete (B_CLICK|B_TIMEOUT|15) -#define EV_15clicks EV_click15_complete -#define EV_click15_hold (B_CLICK|B_HOLD|B_PRESS|15) -#define EV_click15_hold_release (B_CLICK|B_HOLD|B_RELEASE|B_TIMEOUT|15) - diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c deleted file mode 100644 index 066188c..0000000 --- a/spaghetti-monster/fsm-main.c +++ /dev/null @@ -1,211 +0,0 @@ -// fsm-main.c: main() function for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "fsm-main.h" - -#if PWM_CHANNELS == 4 -#ifdef AVRXMEGA3 // ATTINY816, 817, etc -#error 4-channel PWM not currently set up for the AVR 1-Series -#endif -// 4th PWM channel requires manually turning the pin on/off via interrupt :( -ISR(TIMER1_OVF_vect) { - //bitClear(PORTB, 3); - PORTB &= 0b11110111; - //PORTB |= 0b00001000; -} -ISR(TIMER1_COMPA_vect) { - //if (!bitRead(TIFR,TOV1)) bitSet(PORTB, 3); - if (! (TIFR & (1<<TOV1))) PORTB |= 0b00001000; - //if (! (TIFR & (1<<TOV1))) PORTB &= 0b11110111; -} -#endif - -// FIXME: hw_setup() shouldn't be here ... move it entirely to hwdef files -#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) -static inline void hw_setup() { - #if !defined(USE_GENERIC_HWDEF_SETUP) - hwdef_setup(); - #else - // configure PWM channels - #if PWM_CHANNELS >= 1 - DDRB |= (1 << PWM1_PIN); - TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) - TCCR0A = PHASE; - #if (PWM1_PIN == PB4) // Second PWM counter is ... weird - TCCR1 = _BV (CS10); - GTCCR = _BV (COM1B1) | _BV (PWM1B); - OCR1C = 255; // Set ceiling value to maximum - #endif - #endif - // tint ramping needs second channel enabled, - // despite PWM_CHANNELS being only 1 - #if (PWM_CHANNELS >= 2) || defined(USE_TINT_RAMPING) - DDRB |= (1 << PWM2_PIN); - #if (PWM2_PIN == PB4) // Second PWM counter is ... weird - TCCR1 = _BV (CS10); - GTCCR = _BV (COM1B1) | _BV (PWM1B); - OCR1C = 255; // Set ceiling value to maximum - #endif - #endif - #if PWM_CHANNELS >= 3 - DDRB |= (1 << PWM3_PIN); - #if (PWM3_PIN == PB4) // Second PWM counter is ... weird - TCCR1 = _BV (CS10); - GTCCR = _BV (COM1B1) | _BV (PWM1B); - OCR1C = 255; // Set ceiling value to maximum - #endif - #endif - #if PWM_CHANNELS >= 4 - // 4th PWM channel is ... not actually supported in hardware :( - DDRB |= (1 << PWM4_PIN); - //OCR1C = 255; // Set ceiling value to maximum - TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10; - GTCCR = (2<<COM1B0) | (1<<PWM1B); - // set up an interrupt to control PWM4 pin - TIMSK |= (1<<OCIE1A) | (1<<TOIE1); - #endif - - // configure e-switch - PORTB = (1 << SWITCH_PIN); // e-switch is the only input - PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin - #endif // ifdef USE_GENERIC_HWDEF_SETUP -} -#elif (ATTINY == 1634) || defined(AVRXMEGA3) // ATTINY816, 817, etc -static inline void hw_setup() { - // this gets tricky with so many pins... - // ... so punt it to the hwdef file - hwdef_setup(); -} -#else - #error Unrecognized MCU type -#endif - - -//#ifdef USE_REBOOT -static inline void prevent_reboot_loop() { - // prevent WDT from rebooting MCU again - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - RSTCTRL.RSTFR &= ~(RSTCTRL_WDRF_bm); // reset status flag - #else - MCUSR &= ~(1<<WDRF); // reset status flag - #endif - wdt_disable(); -} -//#endif - - -int main() { - // Don't allow interrupts while booting - cli(); - - //#ifdef USE_REBOOT - // prevents cycling after a crash, - // whether intentional (like factory reset) or not (bugs) - prevent_reboot_loop(); - //#endif - - hw_setup(); - - #if 0 - #ifdef HALFSPEED - // run at half speed - // FIXME: not portable (also not needed) - CLKPR = 1<<CLKPCE; - CLKPR = 1; - #endif - #endif - - #ifdef USE_DEBUG_BLINK - //debug_blink(1); - #endif - - // all booted -- turn interrupts back on - PCINT_on(); - WDT_on(); - ADC_on(); - sei(); - - // in case any spurious button presses were detected at boot - #ifdef USE_DELAY_MS - delay_ms(1); - #else - delay_4ms(1); - #endif - - // fallback for handling a few things - #ifndef DONT_USE_DEFAULT_STATE - push_state(default_state, 0); - nice_delay_interrupt = 0; - #endif - - // call recipe's setup - setup(); - - // main loop - while (1) { - // if event queue not empty, empty it - process_emissions(); - - // if loop() tried to change state, process that now - StatePtr df = deferred_state; - if (df) { - set_state(df, deferred_state_arg); - deferred_state = NULL; - //deferred_state_arg = 0; // unnecessary - } - - // enter standby mode if requested - // (works better if deferred like this) - if (go_to_standby) { - #ifdef USE_RAMPING - set_level(0); - #else - #if PWM_CHANNELS >= 1 - PWM1_LVL = 0; - #endif - #if PWM_CHANNELS >= 2 - PWM2_LVL = 0; - #endif - #if PWM_CHANNELS >= 3 - PWM3_LVL = 0; - #endif - #if PWM_CHANNELS >= 4 - PWM4_LVL = 255; // inverted :( - #endif - #endif - standby_mode(); - } - - // catch up on interrupts - handle_deferred_interrupts(); - - // turn delays back on, if they were off - nice_delay_interrupt = 0; - - // give the recipe some time slices - loop(); - - } -} - - -void handle_deferred_interrupts() { - /* - if (irq_pcint) { // button pressed or released - // nothing to do here - // (PCINT only matters during standby) - } - */ - if (irq_adc) { // ADC done measuring - adc_deferred(); - // irq_adc = 0; // takes care of itself - } - if (irq_wdt) { // the clock ticked - WDT_inner(); - // irq_wdt = 0; // takes care of itself - } -} - diff --git a/spaghetti-monster/fsm-main.h b/spaghetti-monster/fsm-main.h deleted file mode 100644 index 2e2a111..0000000 --- a/spaghetti-monster/fsm-main.h +++ /dev/null @@ -1,10 +0,0 @@ -// fsm-main.h: main() function for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -int main(); -// needs to run frequently to execute the logic for WDT and ADC and stuff -void handle_deferred_interrupts(); - diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c deleted file mode 100644 index bc10ea1..0000000 --- a/spaghetti-monster/fsm-misc.c +++ /dev/null @@ -1,312 +0,0 @@ -// fsm-misc.c: Miscellaneous function for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_DYNAMIC_UNDERCLOCKING -void auto_clock_speed() { - uint8_t level = actual_level; // volatile, avoid repeat access - if (level < QUARTERSPEED_LEVEL) { - // run at quarter speed - // note: this only works when executed as two consecutive instructions - // (don't try to combine them or put other stuff between) - clock_prescale_set(clock_div_4); - } - else if (level < HALFSPEED_LEVEL) { - // run at half speed - clock_prescale_set(clock_div_2); - } else { - // run at full speed - clock_prescale_set(clock_div_1); - } -} -#endif - -#if defined(USE_BLINK_NUM) || defined(USE_BLINK_DIGIT) -#define BLINK_SPEED 1000 -uint8_t blink_digit(uint8_t num) { - //StatePtr old_state = current_state; - - // "zero" digit gets a single short blink - uint8_t ontime = BLINK_SPEED * 2 / 12; - if (!num) { ontime = BLINK_ONCE_TIME; num ++; } - - #ifdef BLINK_CHANNEL - // channel is set per blink, to prevent issues - // if another mode interrupts us (like a config menu) - uint8_t old_channel = channel_mode; - #endif - - for (; num>0; num--) { - // TODO: allow setting a blink channel mode per build target - #ifdef BLINK_CHANNEL - set_channel_mode(BLINK_CHANNEL); - #endif - set_level(BLINK_BRIGHTNESS); - #ifdef BLINK_CHANNEL - channel_mode = old_channel; - #endif - nice_delay_ms(ontime); - - #ifdef BLINK_CHANNEL - set_channel_mode(BLINK_CHANNEL); - #endif - set_level(0); - #ifdef BLINK_CHANNEL - channel_mode = old_channel; - #endif - nice_delay_ms(BLINK_SPEED * 3 / 12); - } - - #ifdef BLINK_CHANNEL - set_channel_mode(old_channel); - #endif - - return nice_delay_ms(BLINK_SPEED * 8 / 12); -} -#endif - -#ifdef USE_BLINK_BIG_NUM -uint8_t blink_big_num(uint16_t num) { - uint16_t digits[] = { 10000, 1000, 100, 10, 1 }; - uint8_t started = 0; - for (uint8_t digit=0; digit<sizeof(digits)/sizeof(uint16_t); digit++) { - uint16_t scale = digits[digit]; - if (num >= scale) { - started = 1; - } - if (started) { - uint8_t digit = 0; - while (num >= scale) { - num -= scale; - digit ++; - } - if (! blink_digit(digit)) return 0; - } - } - - return nice_delay_ms(1000); -} -#endif -#ifdef USE_BLINK_NUM -uint8_t blink_num(uint8_t num) { - #if 1 - uint8_t hundreds = num / 100; - num = num % 100; - uint8_t tens = num / 10; - num = num % 10; - #else // can be smaller or larger, depending on whether divmod is used elsewhere - uint8_t hundreds = 0; - uint8_t tens = 0; - for(; num >= 100; hundreds ++, num -= 100); - for(; num >= 10; tens ++, num -= 10); - #endif - - #if 0 - // wait a moment in the dark before starting - set_level(0); - nice_delay_ms(200); - #endif - - if (hundreds) blink_digit(hundreds); - if (hundreds || tens) blink_digit(tens); - return blink_digit(num); -} -#endif - -#ifdef USE_INDICATOR_LED -void indicator_led(uint8_t lvl) { - switch (lvl) { - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - - case 0: // indicator off - AUXLED_PORT.DIRSET = (1 << AUXLED_PIN); // set as output - AUXLED_PORT.OUTCLR = (1 << AUXLED_PIN); // set output low - #ifdef AUXLED2_PIN // second LED mirrors the first - AUXLED2_PORT.DIRSET = (1 << AUXLED2_PIN); // set as output - AUXLED2_PORT.OUTCLR = (1 << AUXLED2_PIN); // set output low - #endif - break; - case 1: // indicator low - AUXLED_PORT.DIRCLR = (1 << AUXLED_PIN); // set as input - // this resolves to PORTx.PINxCTRL = PORT_PULLUPEN_bm; - *((uint8_t *)&AUXLED_PORT + 0x10 + AUXLED_PIN) = PORT_PULLUPEN_bm; // enable internal pull-up - #ifdef AUXLED2_PIN // second LED mirrors the first - AUXLED2_PORT.DIRCLR = (1 << AUXLED2_PIN); // set as input - // this resolves to PORTx.PINxCTRL = PORT_PULLUPEN_bm; - *((uint8_t *)&AUXLED2_PORT + 0x10 + AUXLED2_PIN) = PORT_PULLUPEN_bm; // enable internal pull-up - #endif - break; - default: // indicator high - AUXLED_PORT.DIRSET = (1 << AUXLED_PIN); // set as output - AUXLED_PORT.OUTSET = (1 << AUXLED_PIN); // set as high - #ifdef AUXLED2_PIN // second LED mirrors the first - AUXLED2_PORT.DIRSET = (1 << AUXLED2_PIN); // set as output - AUXLED2_PORT.OUTSET = (1 << AUXLED2_PIN); // set as high - #endif - break; - - #else // MCU is old tiny style, not newer mega style - - case 0: // indicator off - DDRB &= 0xff ^ (1 << AUXLED_PIN); - PORTB &= 0xff ^ (1 << AUXLED_PIN); - #ifdef AUXLED2_PIN // second LED mirrors the first - DDRB &= 0xff ^ (1 << AUXLED2_PIN); - PORTB &= 0xff ^ (1 << AUXLED2_PIN); - #endif - break; - case 1: // indicator low - DDRB &= 0xff ^ (1 << AUXLED_PIN); - PORTB |= (1 << AUXLED_PIN); - #ifdef AUXLED2_PIN // second LED mirrors the first - DDRB &= 0xff ^ (1 << AUXLED2_PIN); - PORTB |= (1 << AUXLED2_PIN); - #endif - break; - default: // indicator high - DDRB |= (1 << AUXLED_PIN); - PORTB |= (1 << AUXLED_PIN); - #ifdef AUXLED2_PIN // second LED mirrors the first - DDRB |= (1 << AUXLED2_PIN); - PORTB |= (1 << AUXLED2_PIN); - #endif - break; - - #endif // MCU type - } -} - -/* -void indicator_led_auto() { - if (actual_level > MAX_1x7135) indicator_led(2); - else if (actual_level > 0) indicator_led(1); - else indicator_led(0); -} -*/ -#endif // USE_INDICATOR_LED - -#ifdef USE_BUTTON_LED -// TODO: Refactor this and RGB LED function to merge code and save space -void button_led_set(uint8_t lvl) { - switch (lvl) { - - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - - case 0: // LED off - BUTTON_LED_PORT.DIRSET = (1 << BUTTON_LED_PIN); // set as output - BUTTON_LED_PORT.OUTCLR = (1 << BUTTON_LED_PIN); // set output low - break; - case 1: // LED low - BUTTON_LED_PORT.DIRCLR = (1 << BUTTON_LED_PIN); // set as input - // this resolves to PORTx.PINxCTRL = PORT_PULLUPEN_bm; - *((uint8_t *)&BUTTON_LED_PORT + 0x10 + BUTTON_LED_PIN) = PORT_PULLUPEN_bm; // enable internal pull-up - break; - default: // LED high - BUTTON_LED_PORT.DIRSET = (1 << BUTTON_LED_PIN); // set as output - BUTTON_LED_PORT.OUTSET = (1 << BUTTON_LED_PIN); // set as high - break; - - #else - - case 0: // LED off - BUTTON_LED_DDR &= 0xff ^ (1 << BUTTON_LED_PIN); - BUTTON_LED_PUE &= 0xff ^ (1 << BUTTON_LED_PIN); - BUTTON_LED_PORT &= 0xff ^ (1 << BUTTON_LED_PIN); - break; - case 1: // LED low - BUTTON_LED_DDR &= 0xff ^ (1 << BUTTON_LED_PIN); - BUTTON_LED_PUE |= (1 << BUTTON_LED_PIN); - BUTTON_LED_PORT |= (1 << BUTTON_LED_PIN); - break; - default: // LED high - BUTTON_LED_DDR |= (1 << BUTTON_LED_PIN); - BUTTON_LED_PUE |= (1 << BUTTON_LED_PIN); - BUTTON_LED_PORT |= (1 << BUTTON_LED_PIN); - break; - - #endif // MCU type - } -} -#endif - -#ifdef USE_AUX_RGB_LEDS -void rgb_led_set(uint8_t value) { - // value: 0b00BBGGRR - uint8_t pins[] = { AUXLED_R_PIN, AUXLED_G_PIN, AUXLED_B_PIN }; - for (uint8_t i=0; i<3; i++) { - uint8_t lvl = (value >> (i<<1)) & 0x03; - uint8_t pin = pins[i]; - switch (lvl) { - - #ifdef AVRXMEGA3 // ATTINY816, 817, etc - - case 0: // LED off - AUXLED_RGB_PORT.DIRSET = (1 << pin); // set as output - AUXLED_RGB_PORT.OUTCLR = (1 << pin); // set output low - break; - case 1: // LED low - AUXLED_RGB_PORT.DIRCLR = (1 << pin); // set as input - // this resolves to PORTx.PINxCTRL = PORT_PULLUPEN_bm; - *((uint8_t *)&AUXLED_RGB_PORT + 0x10 + pin) = PORT_PULLUPEN_bm; // enable internal pull-up - break; - default: // LED high - AUXLED_RGB_PORT.DIRSET = (1 << pin); // set as output - AUXLED_RGB_PORT.OUTSET = (1 << pin); // set as high - break; - - #else - - case 0: // LED off - AUXLED_RGB_DDR &= 0xff ^ (1 << pin); - AUXLED_RGB_PUE &= 0xff ^ (1 << pin); - AUXLED_RGB_PORT &= 0xff ^ (1 << pin); - break; - case 1: // LED low - AUXLED_RGB_DDR &= 0xff ^ (1 << pin); - AUXLED_RGB_PUE |= (1 << pin); - AUXLED_RGB_PORT |= (1 << pin); - break; - default: // LED high - AUXLED_RGB_DDR |= (1 << pin); - AUXLED_RGB_PUE |= (1 << pin); - AUXLED_RGB_PORT |= (1 << pin); - break; - - #endif // MCU type - } - } -} -#endif // ifdef USE_AUX_RGB_LEDS - -#ifdef USE_TRIANGLE_WAVE -uint8_t triangle_wave(uint8_t phase) { - uint8_t result = phase << 1; - if (phase > 127) result = 255 - result; - return result; -} -#endif - -#ifdef USE_REBOOT -void reboot() { - // put the WDT in hard reset mode, then trigger it - cli(); - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - WDTCR = 0xD8 | WDTO_15MS; - #elif (ATTINY == 1634) - // allow protected configuration changes for next 4 clock cycles - CCP = 0xD8; // magic number - // reset (WDIF + WDE), no WDIE, fastest (16ms) timing (0000) - // (DS section 8.5.2 and table 8-4) - WDTCSR = 0b10001000; - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - CCP = CCP_IOREG_gc; // temporarily disable change protection - WDT.CTRLA = WDT_PERIOD_8CLK_gc; // Enable, timeout 8ms - #endif - sei(); - wdt_reset(); - while (1) {} -} -#endif - diff --git a/spaghetti-monster/fsm-misc.h b/spaghetti-monster/fsm-misc.h deleted file mode 100644 index 8de6b29..0000000 --- a/spaghetti-monster/fsm-misc.h +++ /dev/null @@ -1,68 +0,0 @@ -// fsm-misc.h: Miscellaneous function for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_DYNAMIC_UNDERCLOCKING -void auto_clock_speed(); -#endif - -// shortest time (in ms) the light should blink for to indicate a zero -#ifndef BLINK_ONCE_TIME - #define BLINK_ONCE_TIME 10 -#endif - -#if defined(USE_BLINK_NUM) || defined(USE_BLINK_DIGIT) - #ifndef BLINK_BRIGHTNESS - #define BLINK_BRIGHTNESS (MAX_LEVEL/6) - #endif - #if defined(USE_CFG) && defined(DEFAULT_BLINK_CHANNEL) - #define BLINK_CHANNEL cfg.blink_channel - #elif defined(DEFAULT_BLINK_CHANNEL) - #define BLINK_CHANNEL DEFAULT_BLINK_CHANNEL - #endif - uint8_t blink_digit(uint8_t num); -#endif - -#ifdef USE_BLINK_NUM -//#define USE_BLINK -uint8_t blink_num(uint8_t num); -#endif - -/* -#ifdef USE_BLINK -uint8_t blink(uint8_t num, uint8_t speed); -#endif -*/ - -#ifdef USE_INDICATOR_LED -// FIXME: Remove this, replace with button_led() -// lvl: 0=off, 1=low, 2=high -void indicator_led(uint8_t lvl); -#endif - -#ifdef USE_BUTTON_LED -// lvl: 0=off, 1=low, 2=high -void button_led_set(uint8_t lvl); -#endif - -// if any type of aux LEDs exist, define a shorthand flag for it -#if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS) || defined(USE_BUTTON_LED) -#define HAS_AUX_LEDS -#endif - -#ifdef USE_AUX_RGB_LEDS -// value: 0b00BBGGRR -// each pair of bits: 0=off, 1=low, 2=high -void rgb_led_set(uint8_t value); -#endif - -#ifdef USE_TRIANGLE_WAVE -uint8_t triangle_wave(uint8_t phase); -#endif - -#ifdef USE_REBOOT -void reboot(); -#endif - diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c deleted file mode 100644 index 131d0c3..0000000 --- a/spaghetti-monster/fsm-pcint.c +++ /dev/null @@ -1,96 +0,0 @@ -// fsm-pcint.c: PCINT (Pin Change Interrupt) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <avr/interrupt.h> -#include <util/delay_basic.h> - -uint8_t button_is_pressed() { - uint8_t value = ((SWITCH_PORT & (1<<SWITCH_PIN)) == 0); - button_last_state = value; - return value; -} - -inline void PCINT_on() { - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - // enable pin change interrupt - GIMSK |= (1 << PCIE); - // only pay attention to the e-switch pin - #if 0 // this is redundant; was already done in main() - PCMSK = (1 << SWITCH_PCINT); - #endif - // set bits 1:0 to 0b01 (interrupt on rising *and* falling edge) (default) - // MCUCR &= 0b11111101; MCUCR |= 0b00000001; - #elif (ATTINY == 1634) - // enable pin change interrupt - #ifdef SWITCH2_PCIE - GIMSK |= ((1 << SWITCH_PCIE) | (1 << SWITCH2_PCIE)); - #else - GIMSK |= (1 << SWITCH_PCIE); - #endif - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc) - SWITCH_ISC_REG |= PORT_ISC_BOTHEDGES_gc; - #else - #error Unrecognized MCU type - #endif -} - -inline void PCINT_off() { - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - // disable all pin-change interrupts - GIMSK &= ~(1 << PCIE); - #elif (ATTINY == 1634) - // disable all pin-change interrupts - GIMSK &= ~(1 << SWITCH_PCIE); - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc) - SWITCH_ISC_REG &= ~(PORT_ISC_gm); - #else - #error Unrecognized MCU type - #endif -} - -//void button_change_interrupt() { -#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 1634) - #ifdef PCINT_vect - ISR(PCINT_vect) { - #else - ISR(PCINT0_vect) { - #endif -#elif defined(AVRXMEGA3) // ATTINY816, 817, etc) - ISR(SWITCH_VECT) { - // Write a '1' to clear the interrupt flag - SWITCH_INTFLG |= (1 << SWITCH_PIN); -#else - #error Unrecognized MCU type -#endif - - irq_pcint = 1; // let deferred code know an interrupt happened - - //DEBUG_FLASH; - - // as it turns out, it's more reliable to detect pin changes from WDT - // because PCINT itself tends to double-tap when connected to a - // noisy / bouncy switch (so the content of this function has been - // moved to a separate function, called from WDT only) - // PCINT_inner(button_is_pressed()); -} - -// should only be called from PCINT and/or WDT -// (is a separate function to reduce code duplication) -void PCINT_inner(uint8_t pressed) { - button_last_state = pressed; - - // register the change, and send event to the current state callback - if (pressed) { // user pressed button - push_event(B_PRESS); - emit_current_event(0); - } else { // user released button - // how long was the button held? - push_event(B_RELEASE); - emit_current_event(ticks_since_last_event); - } - ticks_since_last_event = 0; -} - diff --git a/spaghetti-monster/fsm-pcint.h b/spaghetti-monster/fsm-pcint.h deleted file mode 100644 index cd7ba02..0000000 --- a/spaghetti-monster/fsm-pcint.h +++ /dev/null @@ -1,15 +0,0 @@ -// fsm-pcint.h: PCINT (Pin Change Interrupt) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -volatile uint8_t irq_pcint = 0; // pin change interrupt happened? -//static volatile uint8_t button_was_pressed; -#define BP_SAMPLES 32 -volatile uint8_t button_last_state; -uint8_t button_is_pressed(); -inline void PCINT_on(); -inline void PCINT_off(); -void PCINT_inner(uint8_t pressed); - diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c deleted file mode 100644 index adc8acb..0000000 --- a/spaghetti-monster/fsm-ramping.c +++ /dev/null @@ -1,259 +0,0 @@ -// fsm-ramping.c: Ramping functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_RAMPING - -#ifdef HAS_AUX_LEDS -inline void set_level_aux_leds(uint8_t level) { - #ifdef USE_INDICATOR_LED_WHILE_RAMPING - // use side-facing aux LEDs while main LEDs are on - if (! go_to_standby) { - #ifdef USE_INDICATOR_LED - indicator_led((level > 0) + (level > DEFAULT_LEVEL)); - #endif - #ifdef USE_BUTTON_LED - button_led_set((level > 0) + (level > DEFAULT_LEVEL)); - #endif - } - #else // turn off front-facing aux LEDs while main LEDs are on - #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS) - if (! go_to_standby) { - #ifdef USE_INDICATOR_LED - indicator_led(0); - #endif - #ifdef USE_AUX_RGB_LEDS - rgb_led_set(0); - #ifdef USE_BUTTON_LED - button_led_set((level > 0) + (level > DEFAULT_LEVEL)); - #endif - #endif - } - #endif - #endif -} -#endif // ifdef HAS_AUX_LEDS - -#ifdef USE_AUX_RGB_LEDS_WHILE_ON -// TODO: maybe move this stuff into FSM -#include "anduril/aux-leds.h" // for rgb_led_voltage_readout() -inline void set_level_aux_rgb_leds(uint8_t level) { - if (! go_to_standby) { - if (level > 0) { - rgb_led_voltage_readout(level > USE_AUX_RGB_LEDS_WHILE_ON); - } else { - rgb_led_set(0); - } - // some drivers can be wired with RGB or single color to button - // ... so support both even though only one is connected - #ifdef USE_BUTTON_LED - button_led_set((level > 0) + (level > DEFAULT_LEVEL)); - #endif - } -} -#endif // ifdef USE_AUX_RGB_LEDS_WHILE_ON - - -void set_level(uint8_t level) { - #ifdef USE_JUMP_START - // maybe "jump start" the engine, if it's prone to slow starts - // (pulse the output high for a moment to wake up the power regulator) - // (only do this when starting from off and going to a low level) - // TODO: allow different jump start behavior per channel mode - // FIXME: don't jump-start during factory reset - // (it seems to cause some eeprom issues on KR4 - // when doing a click with a loose tailcap) - if ((! actual_level) - && level - && (level < JUMP_START_LEVEL)) { - set_level(JUMP_START_LEVEL); - delay_4ms(JUMP_START_TIME/4); - } - #endif - - #ifdef HAS_AUX_LEDS - set_level_aux_leds(level); - #endif - - #ifdef USE_AUX_RGB_LEDS_WHILE_ON - set_level_aux_rgb_leds(level); - #endif - - if (0 == level) { - set_level_zero(); - } else { - // call the relevant hardware-specific set_level_*() - SetLevelFuncPtr set_level_func = channels[channel_mode].set_level; - set_level_func(level - 1); - } - - if (actual_level != level) prev_level = actual_level; - actual_level = level; - - #ifdef USE_SET_LEVEL_GRADUALLY - gradual_target = level; - #endif - - #ifdef USE_DYNAMIC_UNDERCLOCKING - auto_clock_speed(); - #endif -} - -#ifdef USE_LEGACY_SET_LEVEL -// (this is mostly just here for reference, temporarily) -// single set of LEDs with 1 to 3 stacked power channels, -// like linear, FET+1, and FET+N+1 -// (default set_level_*() function for most lights) -void set_level_legacy(uint8_t level) { - if (level == 0) { - #if PWM_CHANNELS >= 1 - PWM1_LVL = 0; - #endif - #if PWM_CHANNELS >= 2 - PWM2_LVL = 0; - #endif - #if PWM_CHANNELS >= 3 - PWM3_LVL = 0; - #endif - #if defined(PWM1_CNT) && defined(PWM1_PHASE_RESET_OFF) - PWM1_CNT = 0; - #endif - #if defined(PWM2_CNT) && defined(PWM2_PHASE_RESET_OFF) - PWM2_CNT = 0; - #endif - #if defined(PWM3_CNT) && defined(PWM3_PHASE_RESET_OFF) - PWM3_CNT = 0; - #endif - #ifdef LED_OFF_DELAY - // for drivers with a slow regulator chip (eg, boost converter), - // delay before turning off to prevent flashes - delay_4ms(LED_OFF_DELAY/4); - #endif - // disable the power channel, if relevant - #ifdef LED_ENABLE_PIN - LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); - #endif - #ifdef LED2_ENABLE_PIN - LED2_ENABLE_PORT &= ~(1 << LED2_ENABLE_PIN); - #endif - } else { - // enable the power channel, if relevant - #ifdef LED_ENABLE_PIN - #ifdef LED_ON_DELAY - uint8_t led_enable_port_save = LED_ENABLE_PORT; - #endif - - #ifndef LED_ENABLE_PIN_LEVEL_MIN - LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); - #else - // only enable during part of the ramp - if ((level >= LED_ENABLE_PIN_LEVEL_MIN) - && (level <= LED_ENABLE_PIN_LEVEL_MAX)) - LED_ENABLE_PORT |= (1 << LED_ENABLE_PIN); - else // disable during other parts of the ramp - LED_ENABLE_PORT &= ~(1 << LED_ENABLE_PIN); - #endif - - // for drivers with a slow regulator chip (eg, boost converter), - // delay before lighting up to prevent flashes - #ifdef LED_ON_DELAY - // only delay if the pin status changed - if (LED_ENABLE_PORT != led_enable_port_save) - delay_4ms(LED_ON_DELAY/4); - #endif - #endif - #ifdef LED2_ENABLE_PIN - #ifdef LED2_ON_DELAY - uint8_t led2_enable_port_save = LED2_ENABLE_PORT; - #endif - - LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN); - - // for drivers with a slow regulator chip (eg, boost converter), - // delay before lighting up to prevent flashes - #ifdef LED2_ON_DELAY - // only delay if the pin status changed - if (LED2_ENABLE_PORT != led2_enable_port_save) - delay_4ms(LED2_ON_DELAY/4); - #endif - #endif - - // PWM array index = level - 1 - level --; - - #if PWM_CHANNELS >= 1 - PWM1_LVL = PWM_GET(pwm1_levels, level); - #endif - #if PWM_CHANNELS >= 2 - PWM2_LVL = PWM_GET(pwm2_levels, level); - #endif - #if PWM_CHANNELS >= 3 - PWM3_LVL = PWM_GET(pwm3_levels, level); - #endif - - #ifdef USE_DYN_PWM - uint16_t top = PWM_GET(pwm_tops, level); - #if defined(PWM1_CNT) && defined(PWM1_PHASE_SYNC) - // wait to ensure compare match won't be missed - // (causes visible flickering when missed, because the counter - // goes all the way to 65535 before returning) - // (see attiny1634 reference manual page 103 for a warning about - // the timing of changing the TOP value (section 12.8.4)) - // (but don't wait when turning on from zero, because - // it'll reset the phase below anyway) - // to be safe, allow at least 32 cycles to update TOP - while(actual_level && (PWM1_CNT > (top - 32))) {} - #endif - // pulse frequency modulation, a.k.a. dynamic PWM - PWM1_TOP = top; - #endif // ifdef USE_DYN_PWM - #if defined(PWM1_CNT) && defined(PWM1_PHASE_RESET_ON) - // force reset phase when turning on from zero - // (because otherwise the initial response is inconsistent) - if (! actual_level) { - PWM1_CNT = 0; - #if defined(PWM2_CNT) && defined(PWM2_PHASE_RESET_ON) - PWM2_CNT = 0; - #endif - #if defined(PWM3_CNT) && defined(PWM3_PHASE_RESET_ON) - PWM3_CNT = 0; - #endif - } - #endif - } - #ifdef USE_DYNAMIC_UNDERCLOCKING - auto_clock_speed(); - #endif -} -#endif - - -#ifdef USE_SET_LEVEL_GRADUALLY -inline void set_level_gradually(uint8_t lvl) { - gradual_target = lvl; -} - - -// call this every frame or every few frames to change brightness very smoothly -void gradual_tick() { - uint8_t gt = gradual_target; - if (gt < actual_level) gt = actual_level - 1; - else if (gt > actual_level) gt = actual_level + 1; - - // call the relevant hardware-specific function - GradualTickFuncPtr gradual_tick_func = channels[channel_mode].gradual_tick; - bool done = gradual_tick_func(gt - 1); - - if (done) { - uint8_t orig = gradual_target; - set_level(gt); - gradual_target = orig; - } -} -#endif // ifdef USE_SET_LEVEL_GRADUALLY - - -#endif // ifdef USE_RAMPING - diff --git a/spaghetti-monster/fsm-ramping.h b/spaghetti-monster/fsm-ramping.h deleted file mode 100644 index c4b7d48..0000000 --- a/spaghetti-monster/fsm-ramping.h +++ /dev/null @@ -1,167 +0,0 @@ -// fsm-ramping.h: Ramping functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_RAMPING - -// actual_level: last ramp level set by set_level() -uint8_t actual_level = 0; -// the level used before actual -uint8_t prev_level = 0; - -void set_level(uint8_t level); -//void set_level_smooth(uint8_t level); -void set_level_zero(); // implement this in a hwdef - -#ifdef USE_SET_LEVEL_GRADUALLY -// adjust brightness very smoothly -uint8_t gradual_target; -inline void set_level_gradually(uint8_t lvl); -void gradual_tick(); - -// reduce repetition with macros -#define GRADUAL_TICK_SETUP() \ - PWM_DATATYPE target; - -// tick to a specific value -#define GRADUAL_ADJUST_SIMPLE(TARGET,PWM) \ - if (PWM < TARGET) PWM ++; \ - else if (PWM > TARGET) PWM --; - -// tick to a specific value, except when immediate 0 to 255 is needed -#define GRADUAL_ADJUST_STACKED(TARGET,PWM,TOP) \ - if ( ((PWM == 0) && (TARGET == TOP)) \ - || ((PWM == TOP) && (TARGET == 0))) \ - PWM = TARGET; \ - else GRADUAL_ADJUST_SIMPLE(TARGET,PWM) - -// tick the top layer of the stack -#define GRADUAL_ADJUST_1CH(TABLE,PWM) \ - target = PWM_GET(TABLE, gt); \ - if (PWM < target) PWM ++; \ - else if (PWM > target) PWM --; - -// tick a base level of the stack -// (with support for special DD FET behavior -// like "low=0, high=255" --> "low=255, high=254") -#define GRADUAL_ADJUST(TABLE,PWM,TOP) \ - target = PWM_GET(TABLE, gt); \ - if ((gt < actual_level) \ - && (PWM == 0) \ - && (target == TOP)) PWM = TOP; \ - else \ - if (PWM < target) PWM ++; \ - else if (PWM > target) PWM --; - -#endif // ifdef USE_SET_LEVEL_GRADUALLY - -// auto-detect the data type for PWM tables -// FIXME: PWM bits and data type should be per PWM table -// FIXME: this whole thing is a mess and should be removed -#ifndef PWM1_BITS - #define PWM1_BITS 8 - #define PWM1_TOP 255 - #define STACKED_PWM_TOP 255 -#endif -#if PWM_BITS <= 8 - #define STACKED_PWM_DATATYPE uint8_t - #define PWM_DATATYPE uint8_t - #define PWM_DATATYPE2 uint16_t - #ifndef PWM_TOP - #define PWM_TOP 255 - #endif - #define STACKED_PWM_TOP 255 - #ifndef PWM_GET - #define PWM_GET(x,y) pgm_read_byte(x+y) - #endif -#else - #define STACKED_PWM_DATATYPE uint16_t - #define PWM_DATATYPE uint16_t - #ifndef PWM_DATATYPE2 - #define PWM_DATATYPE2 uint32_t - #endif - #ifndef PWM_TOP - #define PWM_TOP 1023 // 10 bits by default - #endif - #ifndef STACKED_PWM_TOP - #define STACKED_PWM_TOP 1023 - #endif - // pointer plus 2*y bytes - //#define PWM_GET(x,y) pgm_read_word(x+(2*y)) - // nope, the compiler was already doing the math correctly - #ifndef PWM_GET - #define PWM_GET(x,y) pgm_read_word(x+y) - #endif -#endif -#define PWM_GET8(x,y) pgm_read_byte(x+y) -#define PWM_GET16(x,y) pgm_read_word(x+y) - -// use UI-defined ramp tables if they exist -#ifdef PWM1_LEVELS -PROGMEM const PWM1_DATATYPE pwm1_levels[] = { PWM1_LEVELS }; -#endif -#ifdef PWM2_LEVELS -PROGMEM const PWM2_DATATYPE pwm2_levels[] = { PWM2_LEVELS }; -#endif -#ifdef PWM3_LEVELS -PROGMEM const PWM3_DATATYPE pwm3_levels[] = { PWM3_LEVELS }; -#endif -#ifdef PWM4_LEVELS -PROGMEM const PWM4_DATATYPE pwm4_levels[] = { PWM4_LEVELS }; -#endif -#ifdef PWM5_LEVELS -PROGMEM const PWM5_DATATYPE pwm5_levels[] = { PWM5_LEVELS }; -#endif - -// convenience defs for 1 LED with stacked channels -// FIXME: remove this, use pwm1/2/3 instead -#ifdef LOW_PWM_LEVELS -PROGMEM const PWM_DATATYPE low_pwm_levels[] = { LOW_PWM_LEVELS }; -#endif -#ifdef MED_PWM_LEVELS -PROGMEM const PWM_DATATYPE med_pwm_levels[] = { MED_PWM_LEVELS }; -#endif -#ifdef HIGH_PWM_LEVELS -PROGMEM const PWM_DATATYPE high_pwm_levels[] = { HIGH_PWM_LEVELS }; -#endif - -// 2 channel CCT blending ramp -#ifdef BLEND_PWM_LEVELS -// FIXME: remove this, use pwm1/2/3 instead -PROGMEM const PWM_DATATYPE blend_pwm_levels[] = { BLEND_PWM_LEVELS }; -#endif - - -// pulse frequency modulation, a.k.a. dynamic PWM -// (different ceiling / frequency at each ramp level) -// FIXME: dynamic PWM should be a per-channel option, not global -#ifdef PWM_TOPS -PROGMEM const PWM_DATATYPE pwm_tops[] = { PWM_TOPS }; -#endif - -// FIXME: jump start should be per channel / channel mode -#ifdef USE_JUMP_START - #ifndef JUMP_START_TIME - #define JUMP_START_TIME 8 // in ms, should be 4, 8, or 12 - #endif - #ifndef DEFAULT_JUMP_START_LEVEL - #define DEFAULT_JUMP_START_LEVEL 10 - #endif - #ifdef USE_CFG - #define JUMP_START_LEVEL cfg.jump_start_level - #else - #define JUMP_START_LEVEL jump_start_level - uint8_t jump_start_level = DEFAULT_JUMP_START_LEVEL; - #endif -#endif - -// RAMP_SIZE / MAX_LVL -// cfg-*.h should define RAMP_SIZE -//#define RAMP_SIZE (sizeof(stacked_pwm1_levels)/sizeof(STACKED_PWM_DATATYPE)) -#define MAX_LEVEL RAMP_SIZE - - -#endif // ifdef USE_RAMPING - diff --git a/spaghetti-monster/fsm-random.c b/spaghetti-monster/fsm-random.c deleted file mode 100644 index 91fd929..0000000 --- a/spaghetti-monster/fsm-random.c +++ /dev/null @@ -1,16 +0,0 @@ -// fsm-random.c: Random number generator for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_PSEUDO_RAND -uint8_t pseudo_rand() { - static uint16_t offset = 1024; - // loop from 1024 to 4095 - offset = ((offset + 1) & 0x0fff) | 0x0400; - pseudo_rand_seed += 0b01010101; // 85 - return pgm_read_byte(offset) + pseudo_rand_seed; -} -#endif - diff --git a/spaghetti-monster/fsm-random.h b/spaghetti-monster/fsm-random.h deleted file mode 100644 index 49aa0cf..0000000 --- a/spaghetti-monster/fsm-random.h +++ /dev/null @@ -1,12 +0,0 @@ -// fsm-random.h: Random number generator for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#ifdef USE_PSEUDO_RAND -uint8_t pseudo_rand(); -// TODO: test without "volatile", in case it's not needed -volatile uint8_t pseudo_rand_seed = 0; -#endif - diff --git a/spaghetti-monster/fsm-standby.c b/spaghetti-monster/fsm-standby.c deleted file mode 100644 index 5def07c..0000000 --- a/spaghetti-monster/fsm-standby.c +++ /dev/null @@ -1,105 +0,0 @@ -// fsm-standby.c: standby mode functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <avr/interrupt.h> -#include <avr/sleep.h> - -#include "fsm-adc.h" -#include "fsm-wdt.h" -#include "fsm-pcint.h" - -// low-power standby mode used while off but power still connected -#define standby_mode sleep_until_eswitch_pressed -void sleep_until_eswitch_pressed() -{ - #ifdef TICK_DURING_STANDBY - WDT_slow(); - #else - WDT_off(); - #endif - - ADC_off(); - - // make sure switch isn't currently pressed - while (button_is_pressed()) {} - empty_event_sequence(); // cancel pending input on suspend - - PCINT_on(); // wake on e-switch event - - #ifdef TICK_DURING_STANDBY - // detect which type of event caused a wake-up - irq_adc = 0; - irq_wdt = 0; - irq_pcint = 0; - while (go_to_standby) { - #else - go_to_standby = 0; - #endif - - // configure sleep mode - #ifdef TICK_DURING_STANDBY - // needs a special sleep mode during measurements - if (adc_active_now) adc_sleep_mode(); - else - #endif - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - - sleep_enable(); - #ifdef BODCR // only do this on MCUs which support it - sleep_bod_disable(); - #endif - sleep_cpu(); // wait here - - // something happened; wake up - sleep_disable(); - - #ifdef TICK_DURING_STANDBY - // determine what woke us up... - if (irq_pcint) { // button pressed; wake up - go_to_standby = 0; - } - if (irq_adc) { // ADC done measuring - #ifndef USE_LOWPASS_WHILE_ASLEEP - adc_reset = 1; // don't lowpass while asleep - #endif - adc_deferred_enable = 1; - adc_deferred(); - //ADC_off(); // takes care of itself - //irq_adc = 0; // takes care of itself - } - if (irq_wdt) { // generate a sleep tick - WDT_inner(); - } - } - #endif - - // don't lowpass immediately after waking - // also, reset thermal history - adc_reset = 2; - - // go back to normal running mode - // PCINT not needed any more, and can cause problems if on - // (occasional reboots on wakeup-by-button-press) - PCINT_off(); - // restore normal awake-mode interrupts - ADC_on(); - WDT_on(); -} - -#ifdef USE_IDLE_MODE -void idle_mode() -{ - // configure sleep mode - set_sleep_mode(SLEEP_MODE_IDLE); - - sleep_enable(); - sleep_cpu(); // wait here - - // something happened; wake up - sleep_disable(); -} -#endif - diff --git a/spaghetti-monster/fsm-standby.h b/spaghetti-monster/fsm-standby.h deleted file mode 100644 index 957e2e1..0000000 --- a/spaghetti-monster/fsm-standby.h +++ /dev/null @@ -1,68 +0,0 @@ -// fsm-standby.h: standby mode functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -// deferred "off" so we won't suspend in a weird state -// (like... during the middle of a strobe pulse) -// set this to nonzero to enter standby mode next time the system is idle -volatile uint8_t go_to_standby = 0; - -#ifdef TICK_DURING_STANDBY -#ifndef STANDBY_TICK_SPEED -#define STANDBY_TICK_SPEED 3 // every 0.128 s -/* - * From the Attiny85 manual: - * 0: 16 ms - * 1: 32 ms - * 2: 64 ms - * 3: 0.128 s - * 4: 0.256 s - * 5: 0.512 s - * 6: 1.0 s - * 7: 2.0 s - * 32: 4.0 s - * 33: 8.0 s - * (other values may have unexpected effects; not sure why the final bit is - * separated from the others, in the "32" position instead of "8", but that's - * how it is) - */ -#endif - -#if (STANDBY_TICK_SPEED == 1) -#define SLEEP_TICKS_PER_SECOND 31 -#define SLEEP_TICKS_PER_MINUTE 1800 - -#elif (STANDBY_TICK_SPEED == 2) -#define SLEEP_TICKS_PER_SECOND 16 -#define SLEEP_TICKS_PER_MINUTE 900 - -#elif (STANDBY_TICK_SPEED == 3) -#define SLEEP_TICKS_PER_SECOND 8 -#define SLEEP_TICKS_PER_MINUTE 450 - -#elif (STANDBY_TICK_SPEED == 4) -#define SLEEP_TICKS_PER_SECOND 4 -#define SLEEP_TICKS_PER_MINUTE 225 - -#elif (STANDBY_TICK_SPEED == 5) -#define SLEEP_TICKS_PER_SECOND 2 -#define SLEEP_TICKS_PER_MINUTE 113 - -#elif (STANDBY_TICK_SPEED == 6) -#define SLEEP_TICKS_PER_SECOND 1 -#define SLEEP_TICKS_PER_MINUTE 57 - -#endif -#endif - -#define standby_mode sleep_until_eswitch_pressed -void sleep_until_eswitch_pressed(); - -#ifdef USE_IDLE_MODE -// stops processing until next click or timer tick -// (I think) -void idle_mode(); -#endif - diff --git a/spaghetti-monster/fsm-states.c b/spaghetti-monster/fsm-states.c deleted file mode 100644 index 4b94ce9..0000000 --- a/spaghetti-monster/fsm-states.c +++ /dev/null @@ -1,105 +0,0 @@ -// fsm-states.c: State-handling functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "fsm-states.h" -#include "fsm-adc.h" - -// TODO: if callback doesn't handle current event, -// pass event to next state on stack? -// Callback return values: -// 0: event handled normally -// 1: event not handled -// 255: error (not sure what this would even mean though, or what difference it would make) -// TODO: function to call stacked callbacks until one returns "handled" - -void _set_state(StatePtr new_state, uint16_t arg, - Event exit_event, Event enter_event) { - // call old state-exit hook (don't use stack) - if (current_state != NULL) current_state(exit_event, arg); - // set new state - current_state = new_state; - // call new state-enter hook (don't use stack) - if (new_state != NULL) current_state(enter_event, arg); - - // since state changed, stop any animation in progress - interrupt_nice_delays(); -} - -int8_t push_state(StatePtr new_state, uint16_t arg) { - if (state_stack_len < STATE_STACK_SIZE) { - // TODO: call old state's exit hook? - // new hook for non-exit recursion into child? - state_stack[state_stack_len] = new_state; - state_stack_len ++; - // FIXME: use EV_stacked_state? - _set_state(new_state, arg, EV_leave_state, EV_enter_state); - return state_stack_len; - } else { - // TODO: um... how is a flashlight supposed to handle a recursion depth error? - return -1; - } -} - -StatePtr pop_state() { - // TODO: how to handle pop from empty stack? - StatePtr old_state = NULL; - StatePtr new_state = NULL; - if (state_stack_len > 0) { - state_stack_len --; - old_state = state_stack[state_stack_len]; - } - if (state_stack_len > 0) { - new_state = state_stack[state_stack_len-1]; - } - // FIXME: what should 'arg' be? (maybe re-entry should be entry with arg+1?) - _set_state(new_state, 0, EV_leave_state, EV_reenter_state); - return old_state; -} - -uint8_t set_state(StatePtr new_state, uint16_t arg) { - // FIXME: this calls exit/enter hooks it shouldn't - // (for the layer underneath the top) - pop_state(); - return push_state(new_state, arg); -} - -void set_state_deferred(StatePtr new_state, uint16_t arg) { - deferred_state = new_state; - deferred_state_arg = arg; -} - -#ifndef DONT_USE_DEFAULT_STATE -// bottom state on stack -// handles default actions for LVP, thermal regulation, etc -uint8_t default_state(Event event, uint16_t arg) { - if (0) {} // this should get compiled out - - #ifdef USE_LVP - else if (event == EV_voltage_low) { - low_voltage(); - return EVENT_HANDLED; - } - #endif - - #if 0 - #ifdef USE_THERMAL_REGULATION - else if (event == EV_temperature_high) { - high_temperature(); - return 0; - } - - else if (event == EV_temperature_low) { - low_temperature(); - return 0; - } - #endif - #endif - - // event not handled - return EVENT_NOT_HANDLED; -} -#endif - diff --git a/spaghetti-monster/fsm-states.h b/spaghetti-monster/fsm-states.h deleted file mode 100644 index 156e6cf..0000000 --- a/spaghetti-monster/fsm-states.h +++ /dev/null @@ -1,37 +0,0 @@ -// fsm-states.h: State-handling functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "fsm-adc.h" - -// typedefs -typedef uint8_t State(Event event, uint16_t arg); -typedef State * StatePtr; - -// top of the stack -volatile StatePtr current_state; - -// stack for states, to allow shared utility states like "input a number" -// and such, which return to the previous state after finishing -#define STATE_STACK_SIZE 8 -StatePtr state_stack[STATE_STACK_SIZE]; -uint8_t state_stack_len = 0; - -void _set_state(StatePtr new_state, uint16_t arg, - Event exit_event, Event enter_event); -int8_t push_state(StatePtr new_state, uint16_t arg); -StatePtr pop_state(); -uint8_t set_state(StatePtr new_state, uint16_t arg); - -// if loop() needs to change state, use this instead of set_state() -// (because this avoids race conditions) -volatile StatePtr deferred_state; -volatile uint16_t deferred_state_arg; -void set_state_deferred(StatePtr new_state, uint16_t arg); - -#ifndef DONT_USE_DEFAULT_STATE -uint8_t default_state(Event event, uint16_t arg); -#endif - diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c deleted file mode 100644 index 64f006e..0000000 --- a/spaghetti-monster/fsm-wdt.c +++ /dev/null @@ -1,197 +0,0 @@ -// fsm-wdt.c: WDT (Watch Dog Timer) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <avr/interrupt.h> -#include <avr/wdt.h> - -// *** Note for the AVRXMEGA3 (1-Series, eg 816 and 817), the WDT -// is not used for time-based interrupts. A new peripheral, the -// Periodic Interrupt Timer ("PIT") is used for this purpose. - -void WDT_on() -{ - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - // interrupt every 16ms - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = (1<<WDIE); // Enable interrupt every 16ms - //sei(); // Enable interrupts - #elif (ATTINY == 1634) - wdt_reset(); // Reset the WDT - WDTCSR = (1<<WDIE); // Enable interrupt every 16ms - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - RTC.PITINTCTRL = RTC_PI_bm; // enable the Periodic Interrupt - while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated - RTC.PITCTRLA = RTC_PERIOD_CYC512_gc | RTC_PITEN_bm; // Period = 16ms, enable the PI Timer - #else - #error Unrecognized MCU type - #endif -} - -#ifdef TICK_DURING_STANDBY -inline void WDT_slow() -{ - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - // interrupt slower - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = (1<<WDIE) | STANDBY_TICK_SPEED; // Enable interrupt every so often - //sei(); // Enable interrupts - #elif (ATTINY == 1634) - wdt_reset(); // Reset the WDT - WDTCSR = (1<<WDIE) | STANDBY_TICK_SPEED; - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - RTC.PITINTCTRL = RTC_PI_bm; // enable the Periodic Interrupt - while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated - RTC.PITCTRLA = (1<<6) | (STANDBY_TICK_SPEED<<3) | RTC_PITEN_bm; // Set period, enable the PI Timer - #else - #error Unrecognized MCU type - #endif -} -#endif - -inline void WDT_off() -{ - #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) - //cli(); // Disable interrupts - wdt_reset(); // Reset the WDT - MCUSR &= ~(1<<WDRF); // Clear Watchdog reset flag - WDTCR |= (1<<WDCE) | (1<<WDE); // Start timed sequence - WDTCR = 0x00; // Disable WDT - //sei(); // Enable interrupts - #elif (ATTINY == 1634) - cli(); // needed because CCP, below - wdt_reset(); // Reset the WDT - MCUSR &= ~(1<<WDRF); // clear watchdog reset flag - CCP = 0xD8; // enable config changes - WDTCSR = 0; // disable and clear all WDT settings - sei(); - #elif defined(AVRXMEGA3) // ATTINY816, 817, etc - while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated - RTC.PITCTRLA = 0; // Disable the PI Timer - #else - #error Unrecognized MCU type - #endif -} - -// clock tick -- this runs every 16ms (62.5 fps) -#ifdef AVRXMEGA3 // ATTINY816, 817, etc -ISR(RTC_PIT_vect) { - RTC.PITINTFLAGS = RTC_PI_bm; // clear the PIT interrupt flag -#else -ISR(WDT_vect) { -#endif - irq_wdt = 1; // WDT event happened -} - -void WDT_inner() { - irq_wdt = 0; // WDT event handled; reset flag - - static uint8_t adc_trigger = 0; - - // cache this here to reduce ROM size, because it's volatile - uint16_t ticks_since_last = ticks_since_last_event; - // increment, but loop from max back to half - ticks_since_last = (ticks_since_last + 1) \ - | (ticks_since_last & 0x8000); - // copy back to the original - ticks_since_last_event = ticks_since_last; - - // detect and emit button change events (even during standby) - uint8_t was_pressed = button_last_state; - uint8_t pressed = button_is_pressed(); - if (was_pressed != pressed) { - go_to_standby = 0; - PCINT_inner(pressed); - } - // cache again, in case the value changed - ticks_since_last = ticks_since_last_event; - - #ifdef TICK_DURING_STANDBY - // handle standby mode specially - if (go_to_standby) { - // emit a sleep tick, and process it - emit(EV_sleep_tick, ticks_since_last); - process_emissions(); - - #ifndef USE_SLEEP_LVP - return; // no sleep LVP needed if nothing drains power while off - #else - // stop here, usually... except during the first few seconds asleep, - // and once in a while afterward for sleep LVP - if ((ticks_since_last > (8 * SLEEP_TICKS_PER_SECOND)) - && (0 != (ticks_since_last & 0x0f))) return; - - adc_trigger = 0; // make sure a measurement will happen - adc_active_now = 1; // use ADC noise reduction sleep mode - ADC_on(); // enable ADC voltage measurement functions temporarily - #endif - } - else { // button handling should only happen while awake - #endif - - // if time since last event exceeds timeout, - // append timeout to current event sequence, then - // send event to current state callback - - // callback on each timer tick - if ((current_event & B_FLAGS) == (B_CLICK | B_HOLD | B_PRESS)) { - emit(EV_tick, 0); // override tick counter while holding button - } - else { - emit(EV_tick, ticks_since_last); - } - - // user held button long enough to count as a long click? - if (current_event & B_PRESS) { - // during a "hold", send a hold event each tick, with a timer - if (current_event & B_HOLD) { - emit_current_event(ticks_since_last); - } - // has button been down long enough to become a "hold"? - // (first frame of a "hold" event) - else { - if (ticks_since_last >= HOLD_TIMEOUT) { - ticks_since_last_event = 0; - current_event |= B_HOLD; - emit_current_event(0); - } - } - } - - // event in progress, but button not currently down - else if (current_event) { - // "hold" event just ended - // no timeout required when releasing a long-press - if (current_event & B_HOLD) { - //emit_current_event(ticks_since_last); // should have been emitted by PCINT_inner() - empty_event_sequence(); - } - // end and clear event after release timeout - else if (ticks_since_last >= RELEASE_TIMEOUT) { - current_event |= B_TIMEOUT; - emit_current_event(0); - empty_event_sequence(); - } - } - - #ifdef TICK_DURING_STANDBY - } - #endif - - #if defined(USE_LVP) || defined(USE_THERMAL_REGULATION) - // enable the deferred ADC handler once in a while - if (! adc_trigger) { - ADC_start_measurement(); - adc_deferred_enable = 1; - } - // timing for the ADC handler is every 32 ticks (~2Hz) - adc_trigger = (adc_trigger + 1) & 31; - #endif -} - diff --git a/spaghetti-monster/fsm-wdt.h b/spaghetti-monster/fsm-wdt.h deleted file mode 100644 index abf34c5..0000000 --- a/spaghetti-monster/fsm-wdt.h +++ /dev/null @@ -1,20 +0,0 @@ -// fsm-wdt.h: WDT (Watch Dog Timer) functions for SpaghettiMonster. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#define TICKS_PER_SECOND 62 - -void WDT_on(); -inline void WDT_off(); - -volatile uint8_t irq_wdt = 0; // WDT interrupt happened? - -#ifdef TICK_DURING_STANDBY - #if defined(USE_INDICATOR_LED) || defined(USE_AUX_RGB_LEDS) - // measure battery charge while asleep - #define USE_SLEEP_LVP - #endif -#endif - diff --git a/spaghetti-monster/meteor/meteor.c b/spaghetti-monster/meteor/meteor.c deleted file mode 100644 index 9c1c000..0000000 --- a/spaghetti-monster/meteor/meteor.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Meteor: Meteor M43 clone UI for SpaghettiMonster. - * (in progress, not really in a usable state yet) - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "hwdef-Emisar_D4.h" -#define USE_LVP -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 -#define USE_RAMPING -#define RAMP_LENGTH 150 -#define USE_BATTCHECK -#define BATTCHECK_6bars -#define DONT_DELAY_AFTER_BATTCHECK -//#define USE_EEPROM -//#define EEPROM_BYTES 5 -#include "spaghetti-monster.h" - -// FSM states -uint8_t base_off_state(Event event, uint16_t arg); -uint8_t ui1_off_state(Event event, uint16_t arg); -uint8_t ui2_off_state(Event event, uint16_t arg); -uint8_t ui3_off_state(Event event, uint16_t arg); -uint8_t base_on_state(Event event, uint16_t arg, uint8_t *mode, uint8_t *group); -uint8_t ui1_on_state(Event event, uint16_t arg); -uint8_t ui2_on_state(Event event, uint16_t arg); -uint8_t ui3_on_state(Event event, uint16_t arg); -uint8_t beacon_state(Event event, uint16_t arg); -uint8_t battcheck_state(Event event, uint16_t arg); -uint8_t strobe_state(Event event, uint16_t arg); -uint8_t biking_state(Event event, uint16_t arg); -uint8_t lockout_state(Event event, uint16_t arg); -uint8_t momentary_state(Event event, uint16_t arg); -// Not a FSM state, just handles stuff common to all low/med/hi states -uint8_t any_mode_state(Event event, uint16_t arg, uint8_t *primary, uint8_t *secondary, uint8_t *modes); - -#ifdef USE_EEPROM -void load_config(); -void save_config(); -#endif - -// fixed output levels -uint8_t levels[] = {3, 16, 30, 43, 56, 70, 83, 96, 110, 123, 137, MAX_LEVEL}; -// select an interface -uint8_t UI = 1; // 1, 2, or 3 -// UI1 -uint8_t UI1_mode = 0; -uint8_t UI1_mode1 = 1; -uint8_t UI1_mode2 = 1; -uint8_t UI1_group1[] = {0, 2}; -uint8_t UI1_group2[] = {6, 9}; -// UI2 -uint8_t UI2_mode = 0; -uint8_t UI2_mode1 = 1; -uint8_t UI2_mode2 = 0; -uint8_t UI2_mode3 = 0; -uint8_t UI2_mode4 = 0; // doesn't matter, makes other code easier -uint8_t UI2_group1[] = { 0, 2}; // moon, low -uint8_t UI2_group2[] = { 4, 6}; // mid1, mid2 -uint8_t UI2_group3[] = { 8, 10}; // high1, high2 -uint8_t UI2_group4[] = {11, 11}; // turbo only -// UI3 can access all levels, with 3 different mode memory slots -uint8_t UI3_mode = 0; -uint8_t UI3_mode1 = 2; -uint8_t UI3_mode2 = 5; -uint8_t UI3_mode3 = 8; - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - -void set_any_mode(uint8_t mode, uint8_t *group) { - set_level(levels[group[mode]]); - #ifdef USE_THERMAL_REGULATION - target_level = actual_level; - #endif -} - -void blink_fast() { - set_level(MAX_LEVEL/2); - delay_4ms(8/4); - set_level(0); -} - -uint8_t base_off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - set_level(0); - // sleep while off (lower power use) - go_to_standby = 1; - // ensure we're in a real off state, not the base - switch(UI) { - case 1: set_state(ui1_off_state, 0); break; - case 2: set_state(ui2_off_state, 0); break; - default: set_state(ui3_off_state, 0); break; - } - return EVENT_HANDLED; - } - // 3 clicks: strobe mode - else if (event == EV_3clicks) { - set_state(beacon_state, 0); - return EVENT_HANDLED; - } - // 4 clicks: battcheck mode - else if (event == EV_4clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - // 5 clicks: battcheck mode - else if (event == EV_5clicks) { - set_state(biking_state, 0); - return EVENT_HANDLED; - } - // 6 clicks: soft lockout mode - else if (event == EV_6clicks) { - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - // 9 clicks: activate UI1 - else if (event == EV_9clicks) { - blink_fast(); - set_state(ui1_off_state, 0); - return EVENT_HANDLED; - } - // 10 clicks: activate UI2 - else if (event == EV_10clicks) { - blink_fast(); - set_state(ui2_off_state, 0); - return EVENT_HANDLED; - } - // 11 clicks: activate UI3 - else if (event == EV_11clicks) { - blink_fast(); - set_state(ui3_off_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -uint8_t ui1_off_state(Event event, uint16_t arg) { - UI = 1; - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: low modes - if (event == EV_1click) { - set_any_mode(UI1_mode1, UI1_group1); - set_state(ui1_on_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: high modes - else if (event == EV_2clicks) { - set_any_mode(UI1_mode2, UI1_group2); - set_state(ui1_on_state, 1); - return EVENT_HANDLED; - } - // hold: turbo - else if (event == EV_hold) { - if (arg == 0) { - set_level(MAX_LEVEL); - } - //set_state(ui1_on_state, 3); - return EVENT_HANDLED; - } - // release hold: off - else if (event == EV_click1_hold_release) { - set_state(base_off_state, 0); - return EVENT_HANDLED; - } - return base_off_state(event, arg); -} - -uint8_t ui2_off_state(Event event, uint16_t arg) { - UI = 2; - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: low modes - if (event == EV_1click) { - set_any_mode(UI2_mode1, UI2_group1); - set_state(ui2_on_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: high modes - else if (event == EV_2clicks) { - set_any_mode(UI2_mode3, UI2_group3); - set_state(ui2_on_state, 2); - return EVENT_HANDLED; - } - // hold: turbo - else if (event == EV_hold) { - if (arg == 0) { - set_level(MAX_LEVEL); - } - //set_state(ui1_on_state, 3); - return EVENT_HANDLED; - } - // release hold: off - else if (event == EV_click1_hold_release) { - set_state(base_off_state, 0); - return EVENT_HANDLED; - } - return base_off_state(event, arg); -} - -uint8_t ui3_off_state(Event event, uint16_t arg) { - UI = 3; - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: memory slot 1 - if (event == EV_1click) { - set_level(levels[UI3_mode1]); - set_state(ui3_on_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: memory slot 2 - else if (event == EV_2clicks) { - set_level(levels[UI3_mode2]); - set_state(ui3_on_state, 1); - return EVENT_HANDLED; - } - // Click, hold: memory slot 3 - else if (event == EV_click2_hold) { - set_level(levels[UI3_mode3]); - set_state(ui3_on_state, 2); - return EVENT_HANDLED; - } - // hold: turbo - else if (event == EV_hold) { - if (arg == 0) { - set_level(MAX_LEVEL); - } - //set_state(ui1_on_state, 3); - return EVENT_HANDLED; - } - // release hold: off - else if (event == EV_click1_hold_release) { - set_state(base_off_state, 0); - return EVENT_HANDLED; - } - return base_off_state(event, arg); -} - -uint8_t base_on_state(Event event, uint16_t arg, uint8_t *mode, uint8_t *group) { - // 1 click: off - if (event == EV_1click) { - set_state(base_off_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_THERMAL_REGULATION - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - if (actual_level > MAX_LEVEL/4) { - uint8_t stepdown = actual_level - arg; - if (stepdown < MAX_LEVEL/4) stepdown = MAX_LEVEL/4; - set_level(stepdown); - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - if (actual_level < target_level) { - uint8_t stepup = actual_level + (arg>>1); - if (stepup > target_level) stepup = target_level; - set_level(stepup); - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - -uint8_t ui1_on_state(Event event, uint16_t arg) { - // turn on LED when entering the mode - static uint8_t *mode = &UI1_mode1; - static uint8_t *group = UI1_group1; - if (event == EV_enter_state) { - UI1_mode = arg; - } - if (UI1_mode == 0) { - mode = &UI1_mode1; - group = UI1_group1; - } - else { - mode = &UI1_mode2; - group = UI1_group2; - } - - if (event == EV_enter_state) { - set_any_mode(*mode, group); - return EVENT_HANDLED; - } - // 2 clicks: toggle moon/low or mid/high - else if (event == EV_2clicks) { - *mode ^= 1; - set_any_mode(*mode, group); - return EVENT_HANDLED; - } - // hold: turbo - else if (event == EV_hold) { - if (arg == 0) set_level(MAX_LEVEL); - return EVENT_HANDLED; - } - // release: exit turbo - else if (event == EV_click1_hold_release) { - set_any_mode(*mode, group); - return EVENT_HANDLED; - } - return base_on_state(event, arg, mode, group); -} - -uint8_t ui2_on_state(Event event, uint16_t arg) { - // turn on LED when entering the mode - static uint8_t *mode = &UI2_mode1; - static uint8_t *group = UI2_group1; - if (event == EV_enter_state) { - UI2_mode = arg; - } - switch (UI2_mode) { - case 0: - mode = &UI2_mode1; - group = UI2_group1; - break; - case 1: - mode = &UI2_mode2; - group = UI2_group2; - break; - case 2: - mode = &UI2_mode3; - group = UI2_group3; - break; - default: // turbo only - mode = &UI2_mode4; - group = UI2_group4; - break; - } - - if (event == EV_enter_state) { - set_any_mode(*mode, group); - return EVENT_HANDLED; - } - // 2 clicks: toggle moon/low, mid1/mid2, or high1/high2 - else if (event == EV_2clicks) { - *mode ^= 1; - set_any_mode(*mode, group); - return EVENT_HANDLED; - } - // hold: rotate through low/mid/high/turbo - else if (event == EV_hold) { - if (arg % HOLD_TIMEOUT == 0) { - UI2_mode = (UI2_mode + 1) & 3; - } - else if (arg % HOLD_TIMEOUT == 1) { - set_any_mode(*mode, group); - } - return EVENT_HANDLED; - } - return base_on_state(event, arg, mode, group); -} - -uint8_t ui3_on_state(Event event, uint16_t arg) { - // turn on LED when entering the mode - static uint8_t *mode = &UI3_mode1; - if (event == EV_enter_state) { - UI3_mode = arg; - } - // 2 clicks: rotate through mode1/mode2/mode3 - else if (event == EV_2clicks) { - UI3_mode = (UI3_mode + 1) % 3; - } - // short click, long click: rotate through mode3/mode2/mode1 - /* - else if (event == EV_click1_hold) { - if (arg % HOLD_TIMEOUT == 0) - UI3_mode = (UI3_mode + 4) % 3; - } - */ - switch (UI3_mode) { - case 0: - mode = &UI3_mode1; - break; - case 1: - mode = &UI3_mode2; - break; - default: - mode = &UI3_mode3; - break; - } - - if ((event == EV_enter_state) || (event == EV_2clicks)) { - set_level(levels[*mode]); - return EVENT_HANDLED; - } - // short click, long click: rotate through mode3/mode2/mode1 - /* - else if (event == EV_click1_hold) { - set_level(levels[*mode]); - return EVENT_HANDLED; - } - */ - // hold: turbo - // Click, hold: ramp up - // release hold, hold again: ramp in opposite direction - return base_on_state(event, arg, mode, levels); -} - - -uint8_t blinky_base_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(base_off_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -uint8_t beacon_state(Event event, uint16_t arg) { - return blinky_base_state(event, arg); -} - -uint8_t battcheck_state(Event event, uint16_t arg) { - return EVENT_NOT_HANDLED; -} - -uint8_t strobe_state(Event event, uint16_t arg) { - return blinky_base_state(event, arg); -} - -uint8_t biking_state(Event event, uint16_t arg) { - return blinky_base_state(event, arg); -} - -uint8_t lockout_state(Event event, uint16_t arg) { - return blinky_base_state(event, arg); -} - -uint8_t momentary_state(Event event, uint16_t arg) { - return blinky_base_state(event, arg); -} - - -void low_voltage() { - if ((current_state == ui1_on_state) || - (current_state == ui2_on_state) || - (current_state == ui3_on_state)) { - if (actual_level > 5) { - set_level(actual_level >> 1); - } - else { - set_state(base_off_state, 0); - } - } - /* - // "step down" from blinkies to low - else if (current_state == strobe_beacon_state) { - set_state(low_mode_state, 0); - } - */ -} - -void strobe(uint8_t level, uint16_t ontime, uint16_t offtime) { - set_level(level); - if (! nice_delay_ms(ontime)) return; - set_level(0); - nice_delay_ms(offtime); -} - -#ifdef USE_EEPROM -void load_config() { - if (load_eeprom()) { - H1 = !(!(eeprom[0] & 0b00000100)); - M1 = !(!(eeprom[0] & 0b00000010)); - L1 = !(!(eeprom[0] & 0b00000001)); - H2 = eeprom[1]; - M2 = eeprom[2]; - L2 = eeprom[3]; - strobe_beacon_mode = eeprom[4]; - } -} - -void save_config() { - eeprom[0] = (H1<<2) | (M1<<1) | (L1); - eeprom[1] = H2; - eeprom[2] = M2; - eeprom[3] = L2; - eeprom[4] = strobe_beacon_mode; - - save_eeprom(); -} -#endif - -void setup() { - set_level(RAMP_SIZE/8); - delay_4ms(3); - set_level(0); - - #ifdef USE_EEPROM - load_config(); - #endif - - push_state(base_off_state, 0); -} - -void loop() { - if (0) {} - /* - if (current_state == strobe_beacon_state) { - switch(strobe_beacon_mode) { - // 0.2 Hz beacon at L1 - case 0: - strobe(low_modes[0], 500, 4500); - break; - // 0.2 Hz beacon at H1 - case 1: - strobe(hi_modes[0], 500, 4500); - break; - // 4 Hz tactical strobe at H1 - case 2: - strobe(hi_modes[0], 83, 167); - break; - // 19 Hz tactical strobe at H1 - case 3: - strobe(hi_modes[0], 17, 35); - break; - } - } - */ - - #ifdef USE_BATTCHECK - else if (current_state == battcheck_state) { - nice_delay_ms(500); // wait a moment to measure voltage - battcheck(); - set_state(base_off_state, 0); - } - #endif -} - - diff --git a/spaghetti-monster/momentary/momentary.c b/spaghetti-monster/momentary/momentary.c deleted file mode 100644 index c7a8cf1..0000000 --- a/spaghetti-monster/momentary/momentary.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Momentary: Very simple example UI for SpaghettiMonster. - * Is intended to be the simplest possible FSM e-switch UI. - * The light is on while the button is held; off otherwise. - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "hwdef-Emisar_D4.h" -#define USE_LVP -#define USE_DEBUG_BLINK -#include "spaghetti-monster.h" - -volatile uint8_t brightness; -volatile uint8_t on_now; - -void light_on() { - on_now = 1; - PWM1_LVL = brightness; - PWM2_LVL = 0; -} - -void light_off() { - on_now = 0; - PWM1_LVL = 0; - PWM2_LVL = 0; -} - -uint8_t momentary_state(Event event, uint16_t arg) { - - if (event == EV_click1_press) { - brightness = 255; - light_on(); - empty_event_sequence(); // don't attempt to parse multiple clicks - return 0; - } - - else if (event == EV_release) { - light_off(); - empty_event_sequence(); // don't attempt to parse multiple clicks - go_to_standby = 1; // sleep while light is off - return 0; - } - - return 1; // event not handled -} - -// LVP / low-voltage protection -void low_voltage() { - if (brightness > 0) { - debug_blink(3); - brightness >>= 1; - if (on_now) light_on(); - } else { - debug_blink(8); - light_off(); - go_to_standby = 1; - } -} - -void setup() { - debug_blink(2); - push_state(momentary_state, 0); -} - -void loop() { } - diff --git a/spaghetti-monster/ramping-ui/ramping-ui.c b/spaghetti-monster/ramping-ui/ramping-ui.c deleted file mode 100644 index 583498a..0000000 --- a/spaghetti-monster/ramping-ui/ramping-ui.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Ramping-UI: Ramping UI for SpaghettiMonster. - * - * Copyright (C) 2017 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "hwdef-Emisar_D4.h" -#define USE_LVP -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 32 -#define USE_DELAY_MS -#define USE_DELAY_ZERO -#define USE_RAMPING -#define USE_BATTCHECK -#define BATTCHECK_VpT -#define RAMP_LENGTH 150 -#include "spaghetti-monster.h" - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -uint8_t steady_state(Event event, uint16_t arg); -uint8_t strobe_state(Event event, uint16_t arg); -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg); -uint8_t tempcheck_state(Event event, uint16_t arg); -#endif - -// brightness control -uint8_t memorized_level = MAX_1x7135; -// smooth vs discrete ramping -uint8_t ramp_step_size = 1; - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - -// strobe timing -volatile uint8_t strobe_delay = 67; -volatile uint8_t strobe_type = 0; // 0 == party strobe, 1 == tactical strobe - - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - set_level(0); - // sleep while off (lower power use) - go_to_standby = 1; - return EVENT_HANDLED; - } - // hold (initially): go to lowest level, but allow abort for regular click - else if (event == EV_click1_press) { - set_level(1); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - set_level(memorized_level); - return EVENT_HANDLED; - } - // 1 click: regular mode - else if (event == EV_1click) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // 2 clicks (initial press): off, to prep for later events - else if (event == EV_click2_press) { - set_level(0); - return EVENT_HANDLED; - } - // 2 clicks: highest mode - else if (event == EV_2clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 3 clicks: strobe mode - else if (event == EV_3clicks) { - set_state(strobe_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_BATTCHECK - // 4 clicks: battcheck mode - else if (event == EV_4clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // hold: go to lowest level - else if (event == EV_click1_hold) { - // don't start ramping immediately; - // give the user time to release at moon level - if (arg >= HOLD_TIMEOUT) - set_state(steady_state, 1); - return EVENT_HANDLED; - } - // hold, release quickly: go to lowest level - else if (event == EV_click1_hold_release) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - // click, hold: go to highest level (for ramping down) - else if (event == EV_click2_hold) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -uint8_t steady_state(Event event, uint16_t arg) { - // turn LED on when we first enter the mode - if (event == EV_enter_state) { - // remember this level, unless it's moon or turbo - if ((arg > 1) && (arg < MAX_LEVEL)) - memorized_level = arg; - // use the requested level even if not memorized - #ifdef USE_THERMAL_REGULATION - target_level = arg; - #endif - set_level(arg); - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: go to/from highest level - else if (event == EV_2clicks) { - if (actual_level < MAX_LEVEL) { - memorized_level = actual_level; // in case we're on moon - #ifdef USE_THERMAL_REGULATION - target_level = MAX_LEVEL; - #endif - set_level(MAX_LEVEL); - } - else { - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // 3 clicks: go to strobe modes - else if (event == EV_3clicks) { - set_state(strobe_state, 0); - return EVENT_HANDLED; - } - // 4 clicks: toggle smooth vs discrete ramping - else if (event == EV_4clicks) { - if (ramp_step_size == 1) ramp_step_size = MAX_LEVEL/6; - else ramp_step_size = 1; - set_level(0); - delay_4ms(20/4); - set_level(memorized_level); - return EVENT_HANDLED; - } - // hold: change brightness (brighter) - else if (event == EV_click1_hold) { - // ramp slower in discrete mode - if (arg % ramp_step_size != 0) { - return EVENT_HANDLED; - } - // FIXME: make it ramp down instead, if already at max - if (actual_level + ramp_step_size < MAX_LEVEL) - memorized_level = actual_level + ramp_step_size; - else memorized_level = MAX_LEVEL; - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - // only blink once for each threshold - if ((memorized_level != actual_level) - && ((memorized_level == MAX_1x7135) - || (memorized_level == MAX_LEVEL))) { - set_level(0); - delay_4ms(8/4); - } - set_level(memorized_level); - return EVENT_HANDLED; - } - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - // ramp slower in discrete mode - if (arg % ramp_step_size != 0) { - return EVENT_HANDLED; - } - // FIXME: make it ramp up instead, if already at min - if (actual_level > ramp_step_size) - memorized_level = (actual_level-ramp_step_size); - else - memorized_level = 1; - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - // only blink once for each threshold - if ((memorized_level != actual_level) - && ((memorized_level == MAX_1x7135) - || (memorized_level == 1))) { - set_level(0); - delay_4ms(8/4); - } - set_level(memorized_level); - return EVENT_HANDLED; - } - #ifdef USE_THERMAL_REGULATION - // TODO: test this on a real light - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - if (actual_level > MAX_LEVEL/4) { - uint8_t stepdown = actual_level - arg; - if (stepdown < MAX_LEVEL/4) stepdown = MAX_LEVEL/4; - set_level(stepdown); - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - if (actual_level < target_level) { - uint8_t stepup = actual_level + (arg>>1); - if (stepup > target_level) stepup = target_level; - set_level(stepup); - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -uint8_t strobe_state(Event event, uint16_t arg) { - if (event == EV_enter_state) { - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: toggle party strobe vs tactical strobe - else if (event == EV_2clicks) { - strobe_type ^= 1; - return EVENT_HANDLED; - } - // 3 clicks: go back to regular modes - else if (event == EV_3clicks) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // hold: change speed (go faster) - else if (event == EV_click1_hold) { - if ((arg & 1) == 0) { - if (strobe_delay > 8) strobe_delay --; - } - return EVENT_HANDLED; - } - // click, hold: change speed (go slower) - else if (event == EV_click2_hold) { - if ((arg & 1) == 0) { - if (strobe_delay < 255) strobe_delay ++; - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: tempcheck mode - else if (event == EV_2clicks) { - set_state(tempcheck_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - -uint8_t tempcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -void low_voltage() { - // "step down" from strobe to something low - if (current_state == strobe_state) { - set_state(steady_state, RAMP_SIZE/6); - } - // in normal mode, step down by half or turn off - else if (current_state == steady_state) { - if (actual_level > 1) { - set_level(actual_level >> 1); - } - else { - set_state(off_state, 0); - } - } - // all other modes, just turn off when voltage is low - else { - set_state(off_state, 0); - } -} - - -void setup() { - set_level(RAMP_SIZE/8); - delay_4ms(3); - set_level(0); - - push_state(off_state, 0); -} - - -void loop() { - if (current_state == strobe_state) { - set_level(MAX_LEVEL); - if (strobe_type == 0) { // party strobe - if (strobe_delay < 30) delay_zero(); - else delay_ms(1); - } else { //tactical strobe - nice_delay_ms(strobe_delay >> 1); - } - set_level(0); - nice_delay_ms(strobe_delay); - } - #ifdef USE_BATTCHECK - else if (current_state == battcheck_state) { - battcheck(); - } - else if (current_state == tempcheck_state) { - blink_num(temperature); - nice_delay_ms(1000); - } - #endif -} diff --git a/spaghetti-monster/rampingios/Makefile b/spaghetti-monster/rampingios/Makefile deleted file mode 100644 index 8db198e..0000000 --- a/spaghetti-monster/rampingios/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: - ./build-all.sh - -clean: - rm -f *.hex cfg-*.h *~ *.elf *.o - -.phony: clean diff --git a/spaghetti-monster/rampingios/build-all.sh b/spaghetti-monster/rampingios/build-all.sh deleted file mode 100755 index 106dc15..0000000 --- a/spaghetti-monster/rampingios/build-all.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -cp -av ../anduril/cfg-emisar*.h . - -UI=rampingiosv3 - -for TARGET in cfg-*.h ; do - NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";') - echo "===== $NAME =====" - echo ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" - ../../../bin/build.sh 85 "$UI" "-DCONFIGFILE=${TARGET}" - mv -f "$UI".hex "$UI".$NAME.hex -done diff --git a/spaghetti-monster/rampingios/rampingios-v3.html b/spaghetti-monster/rampingios/rampingios-v3.html deleted file mode 100644 index f72d1ec..0000000 --- a/spaghetti-monster/rampingios/rampingios-v3.html +++ /dev/null @@ -1,501 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" -"http://www.w3.org/TR/html4/strict.dtd"> - -<html> -<head> - <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scape=1.0; user-scalable=false;"> - <link rel="apple-touch-icon" href="/phil/avatar-iphone.png"> - <title>RampingIOS V3 Manual :: Phil! Gold</title> - - <meta name="DC.title" content="Phil! Gold"> - - <link rel="openid2.provider" href="https://www.google.com/accounts/o8/ud" /> - <link rel="openid2.local_id" href="https://plus.google.com/116471799767513262335" /> - <!-- Old one preserved, because some sites use the provider as an account key (bad them). --> - <!--link rel="openid.server" href="http://www.livejournal.com/openid/server.bml"--> - <!--link rel="openid.delegate" href="http://phil-g.livejournal.com/"--> - - <link rel="alternate" type="application/rss+xml" title="RSS" href="http://aperiodic.net/phil/archives/index.rss"> - <link rel="stylesheet" type="text/css" href="/phil/default.css"> - <link rel="stylesheet" type="text/css" href="/phil/blog.css"> - -</head> - -<body> - -<div id="header"> - <h1>RampingIOS V3 Manual</h1> -</div> - -<div id="content"> -<h2>Tue, 28 Aug 2018</h2> - -<div class="story-title" id="rampingios-v3"> - <h3>RampingIOS V3 Manual</h3> - <div class="title-links"> - 9:47AM | - <a href="http://aperiodic.net/phil/archives/Geekery" >Geekery</a> | - - <a href="http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html" title="permalink for RampingIOS V3 Manual" rel="bookmark">#</a> - </div> -</div> - -<p><figure style="float: right"> - <a href="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png"> - <!-- img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3.svg-20180807025420-q28902kbav01123w-1/rampingiosv3.svg" --> - <img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png"> - </a> - <figcaption>RampingIOS V3 UI diagram</figcaption> -</figure></p> - -<p>The Emisar <a href="https://intl-outdoor.com/emisar-d4s-26650-high-power-led-flashlight-p-932.html">D4S</a> flashlights use a firmware named RampingIOS -V3. (The Emisar <a href="https://intl-outdoor.com/emisar-d4-high-power-led-flashlight-p-921.html">D4</a>, <a href="https://intl-outdoor.com/emisar-d1-mini-thrower-p-922.html">D1</a>, and <a href="https://intl-outdoor.com/emisar-d1s-thrower-p-926.html">D1S</a> -all use <a href="http://aperiodic.net/phil/archives/Geekery/rampingios-v2.html">RampingIOS V2</a>.) There's not really a manual; the -only thing we get is the diagram on the right. It's reasonably -comprehensive, but there's a fair amount of detail it merely summarizes, -so I thought a textual manual would be nice.</p> - -<p>The Emisar D4S only works when the head and tailcap are tightened fully. -You can physically lock it out--prevent it from turning on -accidentally--by simply loosening the tailcap a small amount. A quarter -turn will do it.</p> - -<p>Emisar lights are known for their ramping interfaces. Rather than have a -small number of distinct brightness levels, they can vary their brightness -anywhere between their lowest and highest levels, like a light on a -dimmer. The D4S is in ramping mode by default, but it also has a stepped -mode that can be configured to be closer to how non-ramping lights work.</p> - -<p>Each mode--ramping and stepped--can have differently-configured brightness -floors and ceilings.</p> - -<p>The driver for the D4S has two different chipsets. At low brightness -levels, a fairly-efficient but low-power chipset (called a <em>7135</em>) is -used. These lowest brightness levels are called the "<em>regulated levels</em>". -Each regulated level will always be the same brightness regardless of how -much charge the battery has. Above a particular brightness level, the -light switches over to a less-efficient but high-power chipset (called a -<em>FET</em>). These levels are called "<em>direct-drive</em>". The brightness of the -direct-drive levels is directly related to the battery's charge level; the -more charged the battery, the brighter the levels. The light is at its -most efficient, in terms of power used for every lumen generated, at the -brightest regulated level. When the light is first powered by tightening -the tailcap, it will default to this level.</p> - -<p>At higher brightness levels, the light's LEDs generate a lot of heat. If -the light exceeds its configured maximum temperature, it will begin -dimming itself automatically until the temperature drops below the allowed -maximum.</p> - -<p>The D4S has a set of cyan-colored auxiliary LEDs that can be on when the -main LEDs are off. You can configure the behavior of the aux LEDs.</p> - -<h4>Basic Usage</h4> - -<p>The default mode for the light is ramping mode. Triple-pressing the -button (<strong>3 clicks</strong>) while the light is on will toggle between ramping -and stepped mode.</p> - -<p>While the light is off, press and release the button (<strong>1 click</strong>) to turn -it on. It will turn on at the last-used brightness level. (This is -called "<em>mode memory</em>".) Immediately after loosening and tightening the -tailcap (or after changing the battery), the memorized level will be the -light's max regulated level.</p> - -<p>When the light is on, 1 click will turn it off. The current brightness -level will be memorized for future use. There's a fraction of a second -delay between pressing the button and the light actually turning off. -That's because of the way the light processes input; it's waiting to make -sure you're only going to press the button once (since multiple presses -will trigger other actions).</p> - -<p>When the light is on, holding the button down will brighten the light. In -ramping mode, the brightness will increase gradually ("<em>ramping up</em>"). In -stepped mode, the light will jump through increasing brightness levels. -If you press, release, and then hold the button, it will begin dimming. -In ramping mode, the brightness will decrease gradually ("<em>ramping -down</em>"). In stepped mode, the light will jump through decreasing -brightness levels. While the light is changing, if you release the button -and immediately hold it again, the direction (dimming or brightening) will -switch.</p> - -<p>In ramping mode, while the light is ramping, it'll briefly blink off and -on again at two different brightness levels: the maximum regulated level -and the brightness ceiling.</p> - -<p>While the light is off, double-pressing the button (<strong>2 clicks</strong>) will -immediately jump to the brightness ceiling.</p> - -<p>While the light is on, <strong>2 clicks</strong> will jump to the maximum brightness -level, regardless of the configured brightness ceiling. Another two -clicks will go back to the previous brightness level.</p> - -<p>While the light is off, if you hold the button the light will turn on at -its lowest level. If you continue holding the button, the light will -begin brightening from there.</p> - -<h5>Configuration Menus</h5> - -<p>The light has several different configuration modes. Each of those modes -works more or less the same way. The mode will have a series of menu -items that it will go through. For each menu item, the light will first -blink a number of times corresponding to the item number (first, second, -etc.) After that, the light will begin fluttering on and off fairly -quickly. While the light is fluttering, you can click the button a number -of times; the light will count the number of button presses and use that -number as its new configuration for that menu item. After a short period -of time, the fluttering will stop and the light will move on to the next -menu item. After the light has gone through all of the menu items, it -will return to whatever mode it was in before entering the configuration -mode.</p> - -<p>If you don't press the button during a particular menu item's fluttering, -that item will remain unchanged.</p> - -<h5>Configuring the Basic Modes</h5> - -<p>While the light is on, <strong>4 clicks</strong> will enter ramping or stepped -configuration mode, depending on which mode the light was in before the 4 -clicks.</p> - -<p>For ramping mode, there are two menu options:</p> - -<ol> -<li>Brightness floor (default 1/150)</li> -<li>Brightness ceiling (default 150/150)</li> -</ol> - -<p>During the floor configuration, press the button equal to the number of -ramping levels (out of 150) at which the floor should be. To set the -lowest possible floor, click the button once.</p> - -<p>The ceiling is configured similarly, but you press the button equal to the -number of steps away from maximum brightness. To set the highest possible -ceiling (at max brightness), click the button once.</p> - -<p>For stepped mode, there are three menu options:</p> - -<ol> -<li>Brightness floor (default 20/150)</li> -<li>Brightness ceiling (default 120/150)</li> -<li>Number of steps (default 7)</li> -</ol> - -<h4>Other Modes</h4> - -<p>The other modes largely involve multiple clicks from off. Most of them -are not generally needed for everyday use, but they supplement the light's -basic operations.</p> - -<h5>BattCheck/TempCheck Modes</h5> - -<p>From off, <strong>3 clicks</strong> will enter "BattCheck" mode, which blinks out the -current battery voltage. First it blinks the number of volts, then it -pauses, then it blinks out the tenths of volts. Thus, if the battery were -at 3.5 volts, the light would blink three times, pause, then five times. -For zeroes, it gives a very short blink.</p> - -<p>A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8 -volts to be an empty battery and won't turn on if the battery is at or -below 2.8 volts.</p> - -<p>The voltage sequence will continue blinking until you turn off the light -with a single click.</p> - -<p>While the light is in BattCheck mode, <strong>2 clicks</strong> will enter TempCheck -mode. Instead of blinking out the battery voltage, the light will start -blinking out its current temperature in degrees Celsius, first the tens -digit then the units digit. Like BattCheck mode, the light will continue -blinking out the temperature until you turn it off with a single click.</p> - -<p>While the light is in TempCheck mode, <strong>4 clicks</strong> will enter thermal -configuration mode. See the thermal configuration mode documentation -below for how that works.</p> - -<h5>Tactical Mode</h5> - -<p>From off, <strong>4 clicks</strong> will enter "tactical" or "momentary" mode. The -light will flash once to show that it's entered the mode. The auxiliary -LEDs will turn off (if they were on). In tactical mode, the light will -turn on at its memorized brightness for as long as the button is being -held down. It will turn off as soon as the button is released.</p> - -<p>There's no button press combination that will exit tactical mode. To exit -it, you will have to partially unscrew and retighten the tailcap.</p> - -<h5>Lockout Mode</h5> - -<p>From off, <strong>6 clicks</strong> will enter lockout mode. The light will flash -twice to show that it's entered the mode. There's a separate aux LED mode -for lockout mode, so you can tell whether the light is in lockout or not.</p> - -<p>In lockout mode, pressing the button will turn on the light at its lowest -brightness ("<em>moonlight mode</em>") for as long as the button is held down.</p> - -<p>Another 6 clicks will exit lockout mode. The light will flash twice to -show that it's left the mode.</p> - -<p>While in lockout mode, <strong>3 clicks</strong> will cycle through the various -settings for the aux LEDs in lockout mode. The four modes are, in order: -low, high, blink (on high), and off. The default mode is blink.</p> - -<p>Remember that loosening the tailcap a quarter turn will also lock out the -light. Using the 6 clicks is called "<em>electronic lockout</em>", while turning -the tailcap is "<em>physical lockout</em>".</p> - -<h5>Aux LED Configuration</h5> - -<p>From off, <strong>7 clicks</strong> will cycle to the next aux LED mode. The four -modes are, in order: low, high, blink (on high), and off. The default -mode is low.</p> - -<h5>Beacon Mode</h5> - -<p>From off, <strong>8 clicks</strong> will enter beacon mode. In beacon mode, the light -will blink on and off every few seconds.</p> - -<p>By default, the light will blink every two seconds. To change the timing, -use <strong>4 clicks</strong> while in beacon mode. The light will enter a one-item -menu. During the flickering for input, press the button a number of times -equal to the number of seconds between blinks.</p> - -<p>1 click will exit beacon mode.</p> - -<h5>Thermal Configuration Mode</h5> - -<p>From off, <strong>10 clicks</strong> will enter thermal configuration mode.</p> - -<p>The menu items here are:</p> - -<ol> -<li>Current temperature (every click is one degree Celsius)</li> -<li>Temperature ceiling (every click is one degree <em>above 30°C</em>)</li> -</ol> - -<p>The "current temperature" item can be used to adjust the calibration of -the light's temperature sensor. To use it, make sure the light has been -off long enough that all of its components have cooled (or warmed) to the -ambient temperature. Check the ambient temperature using a thermometer -you trust. Go to thermal configuration mode, and enter the current -temperature by clicking the button a number of times equal to the -temperature in degrees Celsius. (If it's 22°C, click the button 22 -times.)</p> - -<p>You can check the default calibration by entering TempCheck mode from a -room-temperature light. The D4Ss are supposed to go through a temperature -calibration at the factory, so hopefully most of them won't need manual -thermal calibration.</p> - -<p>The temperature ceiling is simply the highest temperature the light should -be allowed to reach. Once it hits its temperature ceiling, it will -progressively dim itself until the temperature stabilizes below the -ceiling. Note that the number of clicks in that menu option is added to -<em>30</em> to reach the actual ceiling. (Thus, you can't set a ceiling below -31°C.) The maximum allowed ceiling is 70°C.</p> - -<p>The default temperature ceiling is 45°C.</p> - - -</div> - -<div id="sidebar"> - <h2>Static</h2> - <ul> - <li><a href="/phil/prompt/">zsh prompt</a></li> - <li><a href="/phil/pgp/">PGP</a></li> - <li><a href="/phil/ssh/">SSH</a></li> - <li><a href="/phil/MTA/">MTA</a></li> - <li><a href="/phil/tutorials/">tutorials</a></li> - <li><a href="/phil/configs/">config files</a></li> - <li><a href="http://www.flickr.com/photos/phil_g/sets/1671829/">desktop</a></li> - <li><a href="http://www.librarything.com/catalog/asciiphil">books I own</a></li> - <li><a href="/phil/stuff/">stuff I'm giving away</a></li> - <li><a href="/phil/drwho/">Dr. Who eps I have</a></li> - <li><a href="http://del.icio.us/phil_g">bookmarks</a></li> - <li><a href="http://www.flickr.com/photos/phil_g/">photos</a></li> - <li><a href="/phil/about.html">about</a></li> - </ul> - - <h2>Directory</h2> - <ul class="categories"> -<li><a href="http://aperiodic.net/phil/archives/index.html">Root</a> (143) -<ul> -<li><a href="http://aperiodic.net/phil/archives/Books/index.html">Books</a> (32) -</li> -<li><a href="http://aperiodic.net/phil/archives/Events/index.html">Events</a> (7) -<ul> -<li><a href="http://aperiodic.net/phil/archives/Events/Burning_Man/index.html">Burning Man</a> (3) -</li> -<li><a href="http://aperiodic.net/phil/archives/Events/Camping/index.html">Camping</a> (2) -</li> -<li><a href="http://aperiodic.net/phil/archives/Events/PDF/index.html">PDF</a> (2) -</li> -</ul> -</li> -<li class="this-category">Geekery (36) -<ul> -<li><a href="http://aperiodic.net/phil/archives/Geekery/Test/index.html">Test</a> (3) -</li> -</ul> -</li> -<li><a href="http://aperiodic.net/phil/archives/General/index.html">General</a> (24) -</li> -<li><a href="http://aperiodic.net/phil/archives/Links/index.html">Links</a> (12) -<ul> -<li><a href="http://aperiodic.net/phil/archives/Links/Slashdot/index.html">Slashdot</a> (1) -</li> -</ul> -</li> -<li><a href="http://aperiodic.net/phil/archives/MTA/index.html">MTA</a> (22) -</li> -<li><a href="http://aperiodic.net/phil/archives/Recipes/index.html">Recipes</a> (4) -</li> -<li><a href="http://aperiodic.net/phil/archives/Video_Games/index.html">Video Games</a> (6) -<ul> -<li><a href="http://aperiodic.net/phil/archives/Video_Games/FFXI/index.html">FFXI</a> (1) -</li> -</ul> -</li> -</ul> -</li> -</ul> - - - <h2>Archive</h2> - <table class="month-calendar"><caption class="month-calendar-head"><a title="December 2017 (1)" href="http://aperiodic.net/phil/archives/2017/12/">←</a><a title="August 2018 (2)" href="http://aperiodic.net/phil/archives/2018/08/">August</a>→</caption> - <tr> - <th class="month-calendar-day-head Sunday">Sun</th> - <th class="month-calendar-day-head Monday">Mon</th> - <th class="month-calendar-day-head Tuesday">Tue</th> - <th class="month-calendar-day-head Wednesday">Wed</th> - <th class="month-calendar-day-head Thursday">Thu</th> - <th class="month-calendar-day-head Friday">Fri</th> - <th class="month-calendar-day-head Saturday">Sat</th> - </tr> - <tr> - <td class="month-calendar-day-noday Sunday"> </td> - <td class="month-calendar-day-noday Monday"> </td> - <td class="month-calendar-day-noday Tuesday"> </td> -<td class="month-calendar-day-nolink Wednesday">1</td> -<td class="month-calendar-day-nolink Thursday">2</td> -<td class="month-calendar-day-nolink Friday">3</td> -<td class="month-calendar-day-nolink Saturday">4</td> -</tr> - <tr> -<td class="month-calendar-day-nolink Sunday">5</td> -<td class="month-calendar-day-nolink Monday">6</td> -<td class="month-calendar-day-nolink Tuesday">7</td> -<td class="month-calendar-day-nolink Wednesday">8</td> -<td class="month-calendar-day-nolink Thursday">9</td> -<td class="month-calendar-day-nolink Friday">10</td> -<td class="month-calendar-day-nolink Saturday">11</td> -</tr> - <tr> -<td class="month-calendar-day-nolink Sunday">12</td> -<td class="month-calendar-day-nolink Monday">13</td> -<td class="month-calendar-day-nolink Tuesday">14</td> -<td class="month-calendar-day-nolink Wednesday">15</td> -<td class="month-calendar-day-nolink Thursday">16</td> -<td class="month-calendar-day-nolink Friday">17</td> -<td class="month-calendar-day-nolink Saturday">18</td> -</tr> - <tr> -<td class="month-calendar-day-nolink Sunday">19</td> -<td class="month-calendar-day-nolink Monday">20</td> -<td class="month-calendar-day-nolink Tuesday">21</td> -<td class="month-calendar-day-nolink Wednesday">22</td> -<td class="month-calendar-day-nolink Thursday">23</td> -<td class="month-calendar-day-nolink Friday">24</td> -<td class="month-calendar-day-nolink Saturday">25</td> -</tr> - <tr> -<td class="month-calendar-day-link Sunday"><a title="Sunday, 26 August 2018 (1)" href="http://aperiodic.net/phil/archives/2018/08/26/">26</a></td> -<td class="month-calendar-day-nolink Monday">27</td> -<td class="month-calendar-day-this-day Tuesday"><a title="Tuesday, 28 August 2018 (current) (1)" href="http://aperiodic.net/phil/archives/2018/08/28/">28</a></td> -<td class="month-calendar-day-nolink Wednesday">29</td> -<td class="month-calendar-day-nolink Thursday">30</td> -<td class="month-calendar-day-nolink Friday">31</td> - <td class="month-calendar-day-noday Saturday"> </td> -</tr> -</table> - - <table class="year-calendar"><caption class="year-calendar-head"><a title="2017 (3)" href="http://aperiodic.net/phil/archives/2017/">←</a><a title="2018 (2)" href="http://aperiodic.net/phil/archives/2018/">2018</a>→</caption><tr><th class="year-calendar-subhead" colspan="6">Months</th></tr> -<tr> -<td class="year-calendar-month-nolink">Jan</td> -<td class="year-calendar-month-nolink">Feb</td> -<td class="year-calendar-month-nolink">Mar</td> -<td class="year-calendar-month-nolink">Apr</td> -<td class="year-calendar-month-nolink">May</td> -<td class="year-calendar-month-nolink">Jun</td> -</tr> -<tr> -<td class="year-calendar-month-nolink">Jul</td> -<td class="year-calendar-this-month"><a title="August 2018 (2)" href="http://aperiodic.net/phil/archives/2018/08/">Aug</a></td><td class="year-calendar-month-future">Sep</td> -<td class="year-calendar-month-future">Oct</td> -<td class="year-calendar-month-future">Nov</td> -<td class="year-calendar-month-future">Dec</td> -</tr> -</table> - - - <h2>Search</h2> - <form method="GET" action="http://www.google.com/custom"> - <p style="text-align: center"> - <input type="hidden" name="domains" value="aperiodic.net"> - <input type="hidden" name="cof" VALUE="GALT:#66CC6;S:http://aperiodic.net/phil/;GL:2;VLC:#CC66CC;AH:center;BGC:#000000;LC:#6666CC;GFNT:#666666;ALC:#CC6666;T:#CCCCCC;GIMP:#FFFFFF;AWFID:d3f1afbc39619250;"> - <input type="hidden" name="sitesearch" value="aperiodic.net"> - <input name="q" type="text" size="25" maxlength="255" style="width: 10em"><br> - Powered by <a href="http://www.google.com/"><span class="google-G1">G</span><span class="google-o1">o</span><span class="google-o2">o</span><span class="google-g2">g</span><span class="google-l">l</span><span class="google-e">e</span></a> - </p> - </form> - - - <h2>Currently Reading</h2> - - <div id="wb55a1f3ca64835526140c06560a0205e"></div> - <script type="text/javascript" charset="UTF-8" - src="http://www.librarything.com/widget_get.php?userid=asciiphil&theID=wb55a1f3ca64835526140c06560a0205e"> - </script> - - <h2>Recent Books</h2> - - <div id="wa13cfbb5a4be4d629ebe322b83f1e2f6"></div> - <script type="text/javascript" charset="UTF-8" - src="http://www.librarything.com/widget_get.php?userid=asciiphil&theID=wa13cfbb5a4be4d629ebe322b83f1e2f6"> - </script> - -</div> - -<div class="hr"><hr></div> -<address><a href="mailto:phil_g@pobox.com">Phil! Gold</a></address> -<p class="footer"> -<a href="/phil/">Back to main page.</a><br> -</p> -<ul class="validation"> - <li> - <a href="http://validator.w3.org/check/referer"> - <img src="/phil/pics/html401.png" alt="Valid HTML 4.01"> - </a> - </li> - - <li> - <a href="http://jigsaw.w3.org/css-validator/check/referer"> - <img src="/phil/pics/validcss.png" alt="Valid CSS 2"> - </a> - </li> - - <li> - <a href="http://aperiodic.net/phil/archives/index.rss"> - <img src="/phil/pics/rss10.png" alt="RSS syndication"> - </a> - </li> - - <li> - <a href="http://feedvalidator.org/check?url=http://aperiodic.net/phil/archives/index.rss"> - <img src="/phil/pics/validrss.png" alt="Valid RSS 1.0"> - </a> - </li> - -</ul> - -</html> diff --git a/spaghetti-monster/rampingios/rampingios-v3.md b/spaghetti-monster/rampingios/rampingios-v3.md deleted file mode 100644 index bc0e2b7..0000000 --- a/spaghetti-monster/rampingios/rampingios-v3.md +++ /dev/null @@ -1,262 +0,0 @@ -RampingIOS V3 Manual - -This Markdown-formatted manual was contributed by phil_g under a -Creative Commons CC0 waiver: - http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html - https://creativecommons.org/publicdomain/zero/1.0/ - - -<figure style="float: right"> - <a href="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png"> - <!-- img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3.svg-20180807025420-q28902kbav01123w-1/rampingiosv3.svg" --> - <img width="256em" src="https://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/download/head:/rampingiosv3ui.png-20180807025443-zdamv4ixtu49o7hm-1/rampingiosv3-ui.png"> - </a> - <figcaption>RampingIOS V3 UI diagram</figcaption> -</figure> - -The Emisar [D4S][emisar-d4s] flashlights use a firmware named RampingIOS -V3. (The Emisar [D4][emisar-d4], [D1][emisar-d1], and [D1S][emisar-d1s] -all use [RampingIOS V2][rampingios-v2].) There's not really a manual; the -only thing we get is the diagram on the right. It's reasonably -comprehensive, but there's a fair amount of detail it merely summarizes, -so I thought a textual manual would be nice. - - [emisar-d4]: https://intl-outdoor.com/emisar-d4-high-power-led-flashlight-p-921.html - [emisar-d1]: https://intl-outdoor.com/emisar-d1-mini-thrower-p-922.html - [emisar-d1s]: https://intl-outdoor.com/emisar-d1s-thrower-p-926.html - [emisar-d4s]: https://intl-outdoor.com/emisar-d4s-26650-high-power-led-flashlight-p-932.html - [rampingios-v2]: http://aperiodic.net/phil/archives/Geekery/rampingios-v2.html - -The Emisar D4S only works when the head and tailcap are tightened fully. -You can physically lock it out--prevent it from turning on -accidentally--by simply loosening the tailcap a small amount. A quarter -turn will do it. - -Emisar lights are known for their ramping interfaces. Rather than have a -small number of distinct brightness levels, they can vary their brightness -anywhere between their lowest and highest levels, like a light on a -dimmer. The D4S is in ramping mode by default, but it also has a stepped -mode that can be configured to be closer to how non-ramping lights work. - -Each mode--ramping and stepped--can have differently-configured brightness -floors and ceilings. - -The driver for the D4S has two different chipsets. At low brightness -levels, a fairly-efficient but low-power chipset (called a *7135*) is -used. These lowest brightness levels are called the "*regulated levels*". -Each regulated level will always be the same brightness regardless of how -much charge the battery has. Above a particular brightness level, the -light switches over to a less-efficient but high-power chipset (called a -*FET*). These levels are called "*direct-drive*". The brightness of the -direct-drive levels is directly related to the battery's charge level; the -more charged the battery, the brighter the levels. The light is at its -most efficient, in terms of power used for every lumen generated, at the -brightest regulated level. When the light is first powered by tightening -the tailcap, it will default to this level. - -At higher brightness levels, the light's LEDs generate a lot of heat. If -the light exceeds its configured maximum temperature, it will begin -dimming itself automatically until the temperature drops below the allowed -maximum. - -The D4S has a set of cyan-colored auxiliary LEDs that can be on when the -main LEDs are off. You can configure the behavior of the aux LEDs. - -#### Basic Usage - -The default mode for the light is ramping mode. Triple-pressing the -button (**3 clicks**) while the light is on will toggle between ramping -and stepped mode. - -While the light is off, press and release the button (**1 click**) to turn -it on. It will turn on at the last-used brightness level. (This is -called "*mode memory*".) Immediately after loosening and tightening the -tailcap (or after changing the battery), the memorized level will be the -light's max regulated level. - -When the light is on, 1 click will turn it off. The current brightness -level will be memorized for future use. There's a fraction of a second -delay between pressing the button and the light actually turning off. -That's because of the way the light processes input; it's waiting to make -sure you're only going to press the button once (since multiple presses -will trigger other actions). - -When the light is on, holding the button down will brighten the light. In -ramping mode, the brightness will increase gradually ("*ramping up*"). In -stepped mode, the light will jump through increasing brightness levels. -If you press, release, and then hold the button, it will begin dimming. -In ramping mode, the brightness will decrease gradually ("*ramping -down*"). In stepped mode, the light will jump through decreasing -brightness levels. While the light is changing, if you release the button -and immediately hold it again, the direction (dimming or brightening) will -switch. - -In ramping mode, while the light is ramping, it'll briefly blink off and -on again at two different brightness levels: the maximum regulated level -and the brightness ceiling. - -While the light is off, double-pressing the button (**2 clicks**) will -immediately jump to the brightness ceiling. - -While the light is on, **2 clicks** will jump to the maximum brightness -level, regardless of the configured brightness ceiling. Another two -clicks will go back to the previous brightness level. - -While the light is off, if you hold the button the light will turn on at -its lowest level. If you continue holding the button, the light will -begin brightening from there. - -##### Configuration Menus - -The light has several different configuration modes. Each of those modes -works more or less the same way. The mode will have a series of menu -items that it will go through. For each menu item, the light will first -blink a number of times corresponding to the item number (first, second, -etc.) After that, the light will begin fluttering on and off fairly -quickly. While the light is fluttering, you can click the button a number -of times; the light will count the number of button presses and use that -number as its new configuration for that menu item. After a short period -of time, the fluttering will stop and the light will move on to the next -menu item. After the light has gone through all of the menu items, it -will return to whatever mode it was in before entering the configuration -mode. - -If you don't press the button during a particular menu item's fluttering, -that item will remain unchanged. - -##### Configuring the Basic Modes - -While the light is on, **4 clicks** will enter ramping or stepped -configuration mode, depending on which mode the light was in before the 4 -clicks. - -For ramping mode, there are two menu options: - - 1. Brightness floor (default 1/150) - 2. Brightness ceiling (default 150/150) - -During the floor configuration, press the button equal to the number of -ramping levels (out of 150) at which the floor should be. To set the -lowest possible floor, click the button once. - -The ceiling is configured similarly, but you press the button equal to the -number of steps away from maximum brightness. To set the highest possible -ceiling (at max brightness), click the button once. - -For stepped mode, there are three menu options: - - 1. Brightness floor (default 20/150) - 2. Brightness ceiling (default 120/150) - 3. Number of steps (default 7) - -#### Other Modes - -The other modes largely involve multiple clicks from off. Most of them -are not generally needed for everyday use, but they supplement the light's -basic operations. - -##### BattCheck/TempCheck Modes - -From off, **3 clicks** will enter "BattCheck" mode, which blinks out the -current battery voltage. First it blinks the number of volts, then it -pauses, then it blinks out the tenths of volts. Thus, if the battery were -at 3.5 volts, the light would blink three times, pause, then five times. -For zeroes, it gives a very short blink. - -A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8 -volts to be an empty battery and won't turn on if the battery is at or -below 2.8 volts. - -The voltage sequence will continue blinking until you turn off the light -with a single click. - -While the light is in BattCheck mode, **2 clicks** will enter TempCheck -mode. Instead of blinking out the battery voltage, the light will start -blinking out its current temperature in degrees Celsius, first the tens -digit then the units digit. Like BattCheck mode, the light will continue -blinking out the temperature until you turn it off with a single click. - -While the light is in TempCheck mode, **4 clicks** will enter thermal -configuration mode. See the thermal configuration mode documentation -below for how that works. - -##### Tactical Mode - -From off, **4 clicks** will enter "tactical" or "momentary" mode. The -light will flash once to show that it's entered the mode. The auxiliary -LEDs will turn off (if they were on). In tactical mode, the light will -turn on at its memorized brightness for as long as the button is being -held down. It will turn off as soon as the button is released. - -There's no button press combination that will exit tactical mode. To exit -it, you will have to partially unscrew and retighten the tailcap. - -##### Lockout Mode - -From off, **6 clicks** will enter lockout mode. The light will flash -twice to show that it's entered the mode. There's a separate aux LED mode -for lockout mode, so you can tell whether the light is in lockout or not. - -In lockout mode, pressing the button will turn on the light at its lowest -brightness ("*moonlight mode*") for as long as the button is held down. - -Another 6 clicks will exit lockout mode. The light will flash twice to -show that it's left the mode. - -While in lockout mode, **3 clicks** will cycle through the various -settings for the aux LEDs in lockout mode. The four modes are, in order: -low, high, blink (on high), and off. The default mode is blink. - -Remember that loosening the tailcap a quarter turn will also lock out the -light. Using the 6 clicks is called "*electronic lockout*", while turning -the tailcap is "*physical lockout*". - -##### Aux LED Configuration - -From off, **7 clicks** will cycle to the next aux LED mode. The four -modes are, in order: low, high, blink (on high), and off. The default -mode is low. - -##### Beacon Mode - -From off, **8 clicks** will enter beacon mode. In beacon mode, the light -will blink on and off every few seconds. - -By default, the light will blink every two seconds. To change the timing, -use **4 clicks** while in beacon mode. The light will enter a one-item -menu. During the flickering for input, press the button a number of times -equal to the number of seconds between blinks. - -1 click will exit beacon mode. - -##### Thermal Configuration Mode - -From off, **10 clicks** will enter thermal configuration mode. - -The menu items here are: - - 1. Current temperature (every click is one degree Celsius) - 2. Temperature ceiling (every click is one degree *above 30°C*) - -The "current temperature" item can be used to adjust the calibration of -the light's temperature sensor. To use it, make sure the light has been -off long enough that all of its components have cooled (or warmed) to the -ambient temperature. Check the ambient temperature using a thermometer -you trust. Go to thermal configuration mode, and enter the current -temperature by clicking the button a number of times equal to the -temperature in degrees Celsius. (If it's 22°C, click the button 22 -times.) - -You can check the default calibration by entering TempCheck mode from a -room-temperature light. The D4Ss are supposed to go through a temperature -calibration at the factory, so hopefully most of them won't need manual -thermal calibration. - -The temperature ceiling is simply the highest temperature the light should -be allowed to reach. Once it hits its temperature ceiling, it will -progressively dim itself until the temperature stabilizes below the -ceiling. Note that the number of clicks in that menu option is added to -*30* to reach the actual ceiling. (Thus, you can't set a ceiling below -31°C.) The maximum allowed ceiling is 70°C. - -The default temperature ceiling is 45°C. diff --git a/spaghetti-monster/rampingios/rampingios-v3.txt b/spaghetti-monster/rampingios/rampingios-v3.txt deleted file mode 100644 index 4598a76..0000000 --- a/spaghetti-monster/rampingios/rampingios-v3.txt +++ /dev/null @@ -1,324 +0,0 @@ -RampingIOS V3 Manual -http://aperiodic.net/phil/archives/Geekery/rampingios-v3.html - -Tue, 28 Aug 2018 -9:47AM | Geekery | # - - -RampingIOS V3 Manual --------------------- - -[rampingiosv3-ui.png] RampingIOS V3 UI diagram - -The Emisar D4S flashlights use a firmware named RampingIOS V3. (The Emisar D4, -D1, and D1S all use RampingIOS V2.) There's not really a manual; the only thing -we get is the diagram on the right. It's reasonably comprehensive, but there's -a fair amount of detail it merely summarizes, so I thought a textual manual -would be nice. - -The Emisar D4S only works when the head and tailcap are tightened fully. You -can physically lock it out--prevent it from turning on accidentally--by simply -loosening the tailcap a small amount. A quarter turn will do it. - -Emisar lights are known for their ramping interfaces. Rather than have a small -number of distinct brightness levels, they can vary their brightness anywhere -between their lowest and highest levels, like a light on a dimmer. The D4S is -in ramping mode by default, but it also has a stepped mode that can be -configured to be closer to how non-ramping lights work. - -Each mode--ramping and stepped--can have differently-configured brightness -floors and ceilings. - -The driver for the D4S has two different chipsets. At low brightness levels, a -fairly-efficient but low-power chipset (called a 7135) is used. These lowest -brightness levels are called the "regulated levels". Each regulated level will -always be the same brightness regardless of how much charge the battery has. -Above a particular brightness level, the light switches over to a -less-efficient but high-power chipset (called a FET). These levels are called " -direct-drive". The brightness of the direct-drive levels is directly related to -the battery's charge level; the more charged the battery, the brighter the -levels. The light is at its most efficient, in terms of power used for every -lumen generated, at the brightest regulated level. When the light is first -powered by tightening the tailcap, it will default to this level. - -At higher brightness levels, the light's LEDs generate a lot of heat. If the -light exceeds its configured maximum temperature, it will begin dimming itself -automatically until the temperature drops below the allowed maximum. - -The D4S has a set of cyan-colored auxiliary LEDs that can be on when the main -LEDs are off. You can configure the behavior of the aux LEDs. - - -Basic Usage ------------ - -The default mode for the light is ramping mode. Triple-pressing the button (3 -clicks) while the light is on will toggle between ramping and stepped mode. - -While the light is off, press and release the button (1 click) to turn it on. -It will turn on at the last-used brightness level. (This is called "mode memory -".) Immediately after loosening and tightening the tailcap (or after changing -the battery), the memorized level will be the light's max regulated level. - -When the light is on, 1 click will turn it off. The current brightness level -will be memorized for future use. There's a fraction of a second delay between -pressing the button and the light actually turning off. That's because of the -way the light processes input; it's waiting to make sure you're only going to -press the button once (since multiple presses will trigger other actions). - -When the light is on, holding the button down will brighten the light. In -ramping mode, the brightness will increase gradually ("ramping up"). In stepped -mode, the light will jump through increasing brightness levels. If you press, -release, and then hold the button, it will begin dimming. In ramping mode, the -brightness will decrease gradually ("ramping down"). In stepped mode, the light -will jump through decreasing brightness levels. While the light is changing, if -you release the button and immediately hold it again, the direction (dimming or -brightening) will switch. - -In ramping mode, while the light is ramping, it'll briefly blink off and on -again at two different brightness levels: the maximum regulated level and the -brightness ceiling. - -While the light is off, double-pressing the button (2 clicks) will immediately -jump to the brightness ceiling. - -While the light is on, 2 clicks will jump to the maximum brightness level, -regardless of the configured brightness ceiling. Another two clicks will go -back to the previous brightness level. - -While the light is off, if you hold the button the light will turn on at its -lowest level. If you continue holding the button, the light will begin -brightening from there. - - -Configuration Menus -------------------- - -The light has several different configuration modes. Each of those modes works -more or less the same way. The mode will have a series of menu items that it -will go through. For each menu item, the light will first blink a number of -times corresponding to the item number (first, second, etc.) After that, the -light will begin fluttering on and off fairly quickly. While the light is -fluttering, you can click the button a number of times; the light will count -the number of button presses and use that number as its new configuration for -that menu item. After a short period of time, the fluttering will stop and the -light will move on to the next menu item. After the light has gone through all -of the menu items, it will return to whatever mode it was in before entering -the configuration mode. - -If you don't press the button during a particular menu item's fluttering, that -item will remain unchanged. - - -Configuring the Basic Modes - -While the light is on, 4 clicks will enter ramping or stepped configuration -mode, depending on which mode the light was in before the 4 clicks. - -For ramping mode, there are two menu options: - - 1. Brightness floor (default 1/150) - 2. Brightness ceiling (default 150/150) - -During the floor configuration, press the button equal to the number of ramping -levels (out of 150) at which the floor should be. To set the lowest possible -floor, click the button once. - -The ceiling is configured similarly, but you press the button equal to the -number of steps away from maximum brightness. To set the highest possible -ceiling (at max brightness), click the button once. - -For stepped mode, there are three menu options: - - 1. Brightness floor (default 20/150) - 2. Brightness ceiling (default 120/150) - 3. Number of steps (default 7) - - -Other Modes ------------ - -The other modes largely involve multiple clicks from off. Most of them are not -generally needed for everyday use, but they supplement the light's basic -operations. - - -BattCheck/TempCheck Modes - -From off, 3 clicks will enter "BattCheck" mode, which blinks out the current -battery voltage. First it blinks the number of volts, then it pauses, then it -blinks out the tenths of volts. Thus, if the battery were at 3.5 volts, the -light would blink three times, pause, then five times. For zeroes, it gives a -very short blink. - -A fully-charged lithium-ion battery is 4.2 volts. The light considers 2.8 volts -to be an empty battery and won't turn on if the battery is at or below 2.8 -volts. - -The voltage sequence will continue blinking until you turn off the light with a -single click. - -While the light is in BattCheck mode, 2 clicks will enter TempCheck mode. -Instead of blinking out the battery voltage, the light will start blinking out -its current temperature in degrees Celsius, first the tens digit then the units -digit. Like BattCheck mode, the light will continue blinking out the -temperature until you turn it off with a single click. - -While the light is in TempCheck mode, 4 clicks will enter thermal configuration -mode. See the thermal configuration mode documentation below for how that -works. - - -Tactical Mode - -From off, 4 clicks will enter "tactical" or "momentary" mode. The light will -flash once to show that it's entered the mode. The auxiliary LEDs will turn off -(if they were on). In tactical mode, the light will turn on at its memorized -brightness for as long as the button is being held down. It will turn off as -soon as the button is released. - -There's no button press combination that will exit tactical mode. To exit it, -you will have to partially unscrew and retighten the tailcap. - - -Lockout Mode - -From off, 6 clicks will enter lockout mode. The light will flash twice to show -that it's entered the mode. There's a separate aux LED mode for lockout mode, -so you can tell whether the light is in lockout or not. - -In lockout mode, pressing the button will turn on the light at its lowest -brightness ("moonlight mode") for as long as the button is held down. - -Another 6 clicks will exit lockout mode. The light will flash twice to show -that it's left the mode. - -While in lockout mode, 3 clicks will cycle through the various settings for the -aux LEDs in lockout mode. The four modes are, in order: low, high, blink (on -high), and off. The default mode is blink. - -Remember that loosening the tailcap a quarter turn will also lock out the -light. Using the 6 clicks is called "electronic lockout", while turning the -tailcap is "physical lockout". - - -Aux LED Configuration - -From off, 7 clicks will cycle to the next aux LED mode. The four modes are, in -order: low, high, blink (on high), and off. The default mode is low. - - -Beacon Mode - -From off, 8 clicks will enter beacon mode. In beacon mode, the light will blink -on and off every few seconds. - -By default, the light will blink every two seconds. To change the timing, use 4 -clicks while in beacon mode. The light will enter a one-item menu. During the -flickering for input, press the button a number of times equal to the number of -seconds between blinks. - -1 click will exit beacon mode. - - -Thermal Configuration Mode - -From off, 10 clicks will enter thermal configuration mode. - -The menu items here are: - - 1. Current temperature (every click is one degree Celsius) - 2. Temperature ceiling (every click is one degree above 30?C) - -The "current temperature" item can be used to adjust the calibration of the -light's temperature sensor. To use it, make sure the light has been off long -enough that all of its components have cooled (or warmed) to the ambient -temperature. Check the ambient temperature using a thermometer you trust. Go to -thermal configuration mode, and enter the current temperature by clicking the -button a number of times equal to the temperature in degrees Celsius. (If it's -22?C, click the button 22 times.) - -You can check the default calibration by entering TempCheck mode from a -room-temperature light. The D4Ss are supposed to go through a temperature -calibration at the factory, so hopefully most of them won't need manual thermal -calibration. - -The temperature ceiling is simply the highest temperature the light should be -allowed to reach. Once it hits its temperature ceiling, it will progressively -dim itself until the temperature stabilizes below the ceiling. Note that the -number of clicks in that menu option is added to 30 to reach the actual -ceiling. (Thus, you can't set a ceiling below 31?C.) The maximum allowed -ceiling is 70?C. - -The default temperature ceiling is 45?C. - - -Static - - * zsh prompt - * PGP - * SSH - * MTA - * tutorials - * config files - * desktop - * books I own - * stuff I'm giving away - * Dr. Who eps I have - * bookmarks - * photos - * about - -Directory - - * Root (143) - + Books (32) - + Events (7) - o Burning Man (3) - o Camping (2) - o PDF (2) - + Geekery (36) - o Test (3) - + General (24) - + Links (12) - o Slashdot (1) - + MTA (22) - + Recipes (4) - + Video Games (6) - o FFXI (1) - -Archive - - ?August? -Sun Mon Tue Wed Thu Fri Sat - 1 2 3 4 -5 6 7 8 9 10 11 -12 13 14 15 16 17 18 -19 20 21 22 23 24 25 -26 27 28 29 30 31 - - ?2018? - Months -Jan Feb Mar Apr May Jun -Jul Aug Sep Oct Nov Dec - -Search - -[ ] -Powered by Google - -Currently Reading - -Recent Books - -------------------------------------------------------------------------------- - -Copyright (C) 2018 Phil Gold - -Back to main page. - - * Valid HTML 4.01 - * Valid CSS 2 - * RSS syndication - * Valid RSS 1.0 - diff --git a/spaghetti-monster/rampingios/rampingiosv3-ui.png b/spaghetti-monster/rampingios/rampingiosv3-ui.png Binary files differdeleted file mode 100644 index d02dbf6..0000000 --- a/spaghetti-monster/rampingios/rampingiosv3-ui.png +++ /dev/null diff --git a/spaghetti-monster/rampingios/rampingiosv3.c b/spaghetti-monster/rampingios/rampingiosv3.c deleted file mode 100644 index e990a5a..0000000 --- a/spaghetti-monster/rampingios/rampingiosv3.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* - * RampingIOS V3: FSM-based version of RampingIOS V2 UI, with upgrades. - * - * Copyright (C) 2018-2019 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/********* User-configurable options *********/ -// Anduril config file name (set it here or define it at the gcc command line) -//#define CONFIGFILE cfg-emisar-d4s.h - -#define USE_LVP // FIXME: won't build when this option is turned off - -// parameters for this defined below or per-driver -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this -#define USE_TENCLICK_THERMAL_CONFIG // ten clicks from off -> thermal config mode - -// short blip when crossing from "click" to "hold" from off -// (helps the user hit moon mode exactly, instead of holding too long -// or too short) -#define MOON_TIMING_HINT -// short blips while ramping -#define BLINK_AT_RAMP_MIDDLE -//#define BLINK_AT_RAMP_FLOOR -#define BLINK_AT_RAMP_CEILING -//#define BLINK_AT_STEPS // whenever a discrete ramp mode is passed in smooth mode - -// ramp down via regular button hold if a ramp-up ended <1s ago -// ("hold, release, hold" ramps down instead of up) -#define USE_REVERSING - -// battery readout style (pick one) -#define BATTCHECK_VpT -//#define BATTCHECK_8bars // FIXME: breaks build -//#define BATTCHECK_4bars // FIXME: breaks build - -// enable beacon mode -#define USE_BEACON_MODE - -// make the ramps configurable by the user -#define USE_RAMP_CONFIG - -/***** specific settings for known driver types *****/ -#include "tk.h" -#include incfile(CONFIGFILE) - - -// thermal properties, if not defined per-driver -#ifndef MIN_THERM_STEPDOWN -#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to -#endif -#ifndef THERM_FASTER_LEVEL - #ifdef MAX_Nx7135 - #define THERM_FASTER_LEVEL MAX_Nx7135 // throttle back faster when high - #else - #define THERM_FASTER_LEVEL (RAMP_SIZE*4/5) // throttle back faster when high - #endif -#endif -#ifdef USE_THERMAL_REGULATION -#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments -#endif - - -/********* Configure SpaghettiMonster *********/ -#define USE_DELAY_ZERO -#define USE_RAMPING -#ifndef RAMP_LENGTH -#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file -#endif -#define USE_BATTCHECK -#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending -#define USE_DYNAMIC_UNDERCLOCKING // cut clock speed at very low modes for better efficiency - -// try to auto-detect how many eeprom bytes -#define USE_EEPROM -#define EEPROM_BYTES_BASE 7 - -#ifdef USE_INDICATOR_LED -#define EEPROM_INDICATOR_BYTES 1 -#else -#define EEPROM_INDICATOR_BYTES 0 -#endif - -#ifdef USE_THERMAL_REGULATION -#define EEPROM_THERMAL_BYTES 2 -#else -#define EEPROM_THERMAL_BYTES 0 -#endif - -#define EEPROM_BYTES (EEPROM_BYTES_BASE+EEPROM_INDICATOR_BYTES+EEPROM_THERMAL_BYTES) - - -#include "spaghetti-monster.h" - - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -// simple numeric entry config menu -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()); -#define MAX_CONFIG_VALUES 3 -uint8_t config_state_values[MAX_CONFIG_VALUES]; -// ramping mode and its related config mode -uint8_t steady_state(Event event, uint16_t arg); -#ifdef USE_RAMP_CONFIG -uint8_t ramp_config_state(Event event, uint16_t arg); -#endif -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg); -#endif -#ifdef USE_THERMAL_REGULATION -#define USE_BLINK_NUM -uint8_t tempcheck_state(Event event, uint16_t arg); -uint8_t thermal_config_state(Event event, uint16_t arg); -#endif -#ifdef USE_BEACON_MODE -// beacon mode and its related config mode -uint8_t beacon_state(Event event, uint16_t arg); -uint8_t beacon_config_state(Event event, uint16_t arg); -#endif -// soft lockout -#define MOON_DURING_LOCKOUT_MODE -// if enabled, 2nd lockout click goes to the other ramp's floor level -//#define LOCKOUT_MOON_FANCY -uint8_t lockout_state(Event event, uint16_t arg); -// momentary / signalling mode -uint8_t momentary_state(Event event, uint16_t arg); - -// general helper function for config modes -uint8_t number_entry_state(Event event, uint16_t arg); -// return value from number_entry_state() -volatile uint8_t number_entry_value; - -void blink_confirm(uint8_t num); -#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) -void indicator_blink(uint8_t arg); -#endif - -// remember stuff even after battery was changed -void load_config(); -void save_config(); - -// default ramp options if not overridden earlier per-driver -#ifndef RAMP_SMOOTH_FLOOR - #define RAMP_SMOOTH_FLOOR 1 -#endif -#ifndef RAMP_SMOOTH_CEIL - #if PWM_CHANNELS == 3 - #define RAMP_SMOOTH_CEIL MAX_Nx7135 - #else - #define RAMP_SMOOTH_CEIL MAX_LEVEL - 30 - #endif -#endif -#ifndef RAMP_DISCRETE_FLOOR - #define RAMP_DISCRETE_FLOOR 20 -#endif -#ifndef RAMP_DISCRETE_CEIL - #define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL -#endif -#ifndef RAMP_DISCRETE_STEPS - #define RAMP_DISCRETE_STEPS 7 -#endif - -// mile marker(s) partway up the ramp -// default: blink only at border between regulated and FET -#ifdef BLINK_AT_RAMP_MIDDLE - #if PWM_CHANNELS >= 3 - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_Nx7135 - #ifndef BLINK_AT_RAMP_MIDDLE_2 - #define BLINK_AT_RAMP_MIDDLE_2 MAX_1x7135 - #endif - #endif - #else - #ifndef BLINK_AT_RAMP_MIDDLE_1 - #define BLINK_AT_RAMP_MIDDLE_1 MAX_1x7135 - #endif - #endif -#endif - -// brightness control -#ifndef DEFAULT_LEVEL -#define DEFAULT_LEVEL MAX_1x7135 -#endif -uint8_t memorized_level = DEFAULT_LEVEL; -// smooth vs discrete ramping -volatile uint8_t ramp_style = 0; // 0 = smooth, 1 = discrete -volatile uint8_t ramp_smooth_floor = RAMP_SMOOTH_FLOOR; -volatile uint8_t ramp_smooth_ceil = RAMP_SMOOTH_CEIL; -volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR; -volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL; -volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS; -uint8_t ramp_discrete_step_size; // don't set this - -#ifdef USE_INDICATOR_LED - // bits 2-3 control lockout mode - // bits 0-1 control "off" mode - // modes are: 0=off, 1=low, 2=high, 3=blinking (if TICK_DURING_STANDBY enabled) - #ifdef INDICATOR_LED_DEFAULT_MODE - uint8_t indicator_led_mode = INDICATOR_LED_DEFAULT_MODE; - #else - #ifdef USE_INDICATOR_LED_WHILE_RAMPING - //uint8_t indicator_led_mode = (1<<2) + 2; - uint8_t indicator_led_mode = (2<<2) + 1; - #else - uint8_t indicator_led_mode = (3<<2) + 1; - #endif - #endif -#endif - -// calculate the nearest ramp level which would be valid at the moment -// (is a no-op for smooth ramp, but limits discrete ramp to only the -// correct levels for the user's config) -uint8_t nearest_level(int16_t target); - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - -#ifdef USE_BEACON_MODE -// beacon timing -volatile uint8_t beacon_seconds = 2; -#endif - - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if (event == EV_enter_state) { - set_level(0); - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode & 0x03); - #endif - // sleep while off (lower power use) - go_to_standby = 1; - return EVENT_HANDLED; - } - // go back to sleep eventually if we got bumped but didn't leave "off" state - else if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode & 0x03); - #endif - } - return EVENT_HANDLED; - } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) - // blink the indicator LED, maybe - else if (event == EV_sleep_tick) { - if ((indicator_led_mode & 0b00000011) == 0b00000011) { - indicator_blink(arg); - } - return EVENT_HANDLED; - } - #endif - // hold (initially): go to lowest level (floor), but allow abort for regular click - else if (event == EV_click1_press) { - set_level(nearest_level(1)); - return EVENT_HANDLED; - } - // hold: go to lowest level - else if (event == EV_click1_hold) { - #ifdef MOON_TIMING_HINT - if (arg == 0) { - // let the user know they can let go now to stay at moon - uint8_t temp = actual_level; - set_level(0); - delay_4ms(3); - set_level(temp); - } else - #endif - // don't start ramping immediately; - // give the user time to release at moon level - //if (arg >= HOLD_TIMEOUT) { // smaller - if (arg >= (!ramp_style) * HOLD_TIMEOUT) { // more consistent - set_state(steady_state, 1); - } - return EVENT_HANDLED; - } - // hold, release quickly: go to lowest level (floor) - else if (event == EV_click1_hold_release) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - set_level(nearest_level(memorized_level)); - return EVENT_HANDLED; - } - // 1 click: regular mode - else if (event == EV_1click) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // click, hold: go to highest level (ceiling) (for ramping down) - else if (event == EV_click2_hold) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 2 clicks: highest mode (ceiling) - else if (event == EV_2clicks) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 3 clicks (initial press): off, to prep for later events - else if (event == EV_click3_press) { - set_level(0); - return EVENT_HANDLED; - } - #ifdef USE_BATTCHECK - // 3 clicks: battcheck mode / blinky mode group 1 - else if (event == EV_3clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // 4 clicks: momentary - else if (event == EV_4clicks) { - blink_confirm(1); - set_state(momentary_state, 0); - return EVENT_HANDLED; - } - // 6 clicks: lockout mode - else if (event == EV_6clicks) { - blink_confirm(2); - set_state(lockout_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_INDICATOR_LED - // 7 clicks: next aux LED mode - else if (event == EV_7clicks) { - blink_confirm(1); - uint8_t mode = (indicator_led_mode & 3) + 1; - #ifdef TICK_DURING_STANDBY - mode = mode & 3; - #else - mode = mode % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (indicator_led_mode & 0b11111100) | mode; - indicator_led(mode); - save_config(); - return EVENT_HANDLED; - } - #endif - // 8 clicks: beacon mode - else if (event == EV_8clicks) { - set_state(beacon_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_TENCLICK_THERMAL_CONFIG - // 10 clicks: thermal config mode - else if (event == EV_10clicks) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -uint8_t steady_state(Event event, uint16_t arg) { - uint8_t mode_min = ramp_smooth_floor; - uint8_t mode_max = ramp_smooth_ceil; - uint8_t ramp_step_size = 1; - #ifdef USE_REVERSING - static int8_t ramp_direction = 1; - #endif - if (ramp_style) { - mode_min = ramp_discrete_floor; - mode_max = ramp_discrete_ceil; - ramp_step_size = ramp_discrete_step_size; - } - - // turn LED on when we first enter the mode - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - // if we just got back from config mode, go back to memorized level - if (event == EV_reenter_state) { - arg = memorized_level; - } - // remember this level, unless it's moon or turbo - if ((arg > mode_min) && (arg < mode_max)) - memorized_level = arg; - // use the requested level even if not memorized - arg = nearest_level(arg); - #ifdef USE_THERMAL_REGULATION - target_level = arg; - #endif - set_level(arg); - #ifdef USE_REVERSING - ramp_direction = 1; - #endif - return EVENT_HANDLED; - } - // 1 click: off - else if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: go to/from highest level - else if (event == EV_2clicks) { - if (actual_level < MAX_LEVEL) { - #ifdef USE_THERMAL_REGULATION - target_level = MAX_LEVEL; - #endif - // true turbo, not the mode-specific ceiling - set_level(MAX_LEVEL); - } - else { - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - } - return EVENT_HANDLED; - } - // 3 clicks: toggle smooth vs discrete ramping - else if (event == EV_3clicks) { - ramp_style = !ramp_style; - memorized_level = nearest_level(actual_level); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #ifdef USE_SET_LEVEL_GRADUALLY - //set_level_gradually(lvl); - #endif - #endif - save_config(); - set_level(0); - delay_4ms(20/4); - set_level(memorized_level); - return EVENT_HANDLED; - } - #ifdef USE_RAMP_CONFIG - // 4 clicks: configure this ramp mode - else if (event == EV_4clicks) { - push_state(ramp_config_state, 0); - return EVENT_HANDLED; - } - #endif - // hold: change brightness (brighter) - else if (event == EV_click1_hold) { - // ramp slower in discrete mode - if (ramp_style && (arg % HOLD_TIMEOUT != 0)) { - return EVENT_HANDLED; - } - #ifdef USE_REVERSING - // make it ramp down instead, if already at max - if ((arg <= 1) && (actual_level >= mode_max)) { - ramp_direction = -1; - } - memorized_level = nearest_level((int16_t)actual_level \ - + (ramp_step_size * ramp_direction)); - #else - memorized_level = nearest_level((int16_t)actual_level + ramp_step_size); - #endif - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - #if defined(BLINK_AT_RAMP_CEILING) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #ifdef BLINK_AT_RAMP_MIDDLE_1 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_1) - #endif - #ifdef BLINK_AT_RAMP_MIDDLE_2 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_2) - #endif - #ifdef BLINK_AT_RAMP_CEILING - || (memorized_level == mode_max) - #endif - #if defined(USE_REVERSING) && defined(BLINK_AT_RAMP_FLOOR) - || (memorized_level == mode_min) - #endif - )) { - set_level(0); - delay_4ms(8/4); - } - #endif - #if defined(BLINK_AT_STEPS) - uint8_t foo = ramp_style; - ramp_style = 1; - uint8_t nearest = nearest_level((int16_t)actual_level); - ramp_style = foo; - // only blink once for each threshold - if ((memorized_level != actual_level) && - (ramp_style == 0) && - (memorized_level == nearest) - ) - { - set_level(0); - delay_4ms(8/4); - } - #endif - set_level(memorized_level); - return EVENT_HANDLED; - } - #if defined(USE_REVERSING) - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - #ifdef USE_REVERSING - ramp_direction = -ramp_direction; - #endif - return EVENT_HANDLED; - } - #endif - // click, hold: change brightness (dimmer) - else if (event == EV_click2_hold) { - #ifdef USE_REVERSING - ramp_direction = 1; - #endif - // ramp slower in discrete mode - if (ramp_style && (arg % HOLD_TIMEOUT != 0)) { - return EVENT_HANDLED; - } - // TODO? make it ramp up instead, if already at min? - memorized_level = nearest_level((int16_t)actual_level - ramp_step_size); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - #if defined(BLINK_AT_RAMP_FLOOR) || defined(BLINK_AT_RAMP_MIDDLE) - // only blink once for each threshold - if ((memorized_level != actual_level) && ( - 0 // for easier syntax below - #ifdef BLINK_AT_RAMP_MIDDLE_1 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_1) - #endif - #ifdef BLINK_AT_RAMP_MIDDLE_2 - || (memorized_level == BLINK_AT_RAMP_MIDDLE_2) - #endif - #ifdef BLINK_AT_RAMP_FLOOR - || (memorized_level == mode_min) - #endif - )) { - set_level(0); - delay_4ms(8/4); - } - #endif - #if defined(BLINK_AT_STEPS) - uint8_t foo = ramp_style; - ramp_style = 1; - uint8_t nearest = nearest_level((int16_t)actual_level); - ramp_style = foo; - // only blink once for each threshold - if ((memorized_level != actual_level) && - (ramp_style == 0) && - (memorized_level == nearest) - ) - { - set_level(0); - delay_4ms(8/4); - } - #endif - set_level(memorized_level); - return EVENT_HANDLED; - } - #if defined(USE_SET_LEVEL_GRADUALLY) || defined(USE_REVERSING) - else if (event == EV_tick) { - #ifdef USE_REVERSING - // un-reverse after 1 second - if (arg == TICKS_PER_SECOND) ramp_direction = 1; - #endif - #ifdef USE_SET_LEVEL_GRADUALLY - // make thermal adjustment speed scale with magnitude - if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) { - return EVENT_HANDLED; // adjust slower when not a high mode - } - #ifdef THERM_HARD_TURBO_DROP - else if ((! (actual_level < THERM_FASTER_LEVEL)) - && (actual_level > gradual_target)) { - gradual_tick(); - } - else { - #endif - // [int(62*4 / (x**0.8)) for x in (1,2,4,8,16,32,64,128)] - //uint8_t intervals[] = {248, 142, 81, 46, 26, 15, 8, 5}; - // [int(62*4 / (x**0.9)) for x in (1,2,4,8,16,32,64,128)] - //uint8_t intervals[] = {248, 132, 71, 38, 20, 10, 5, 3}; - // [int(62*4 / (x**0.95)) for x in (1,2,4,8,16,32,64,128)] - uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2}; - uint8_t diff; - static uint8_t ticks_since_adjust = 0; - ticks_since_adjust ++; - if (gradual_target > actual_level) diff = gradual_target - actual_level; - else { - diff = actual_level - gradual_target; - } - uint8_t magnitude = 0; - #ifndef THERM_HARD_TURBO_DROP - // if we're on a really high mode, drop faster - if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; } - #endif - while (diff) { - magnitude ++; - diff >>= 1; - } - uint8_t ticks_per_adjust = intervals[magnitude]; - if (ticks_since_adjust > ticks_per_adjust) - { - gradual_tick(); - ticks_since_adjust = 0; - } - //if (!(arg % ticks_per_adjust)) gradual_tick(); - #ifdef THERM_HARD_TURBO_DROP - } - #endif - #endif - return EVENT_HANDLED; - } - #endif - #ifdef USE_THERMAL_REGULATION - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - #if 0 - uint8_t foo = actual_level; - set_level(0); - delay_4ms(2); - set_level(foo); - #endif - #ifdef THERM_HARD_TURBO_DROP - if (actual_level > THERM_FASTER_LEVEL) { - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(THERM_FASTER_LEVEL); - #else - set_level(THERM_FASTER_LEVEL); - #endif - target_level = THERM_FASTER_LEVEL; - } else - #endif - if (actual_level > MIN_THERM_STEPDOWN) { - int16_t stepdown = actual_level - arg; - if (stepdown < MIN_THERM_STEPDOWN) stepdown = MIN_THERM_STEPDOWN; - else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepdown); - #else - set_level(stepdown); - #endif - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - #if 0 - uint8_t foo = actual_level; - set_level(0); - delay_4ms(2); - set_level(foo); - #endif - if (actual_level < target_level) { - //int16_t stepup = actual_level + (arg>>1); - int16_t stepup = actual_level + arg; - if (stepup > target_level) stepup = target_level; - else if (stepup < MIN_THERM_STEPDOWN) stepup = MIN_THERM_STEPDOWN; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepup); - #else - set_level(stepup); - #endif - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: tempcheck mode - else if (event == EV_2clicks) { - set_state(tempcheck_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -#ifdef USE_THERMAL_REGULATION -uint8_t tempcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 4 clicks: thermal config mode - else if (event == EV_4clicks) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -#ifdef USE_BEACON_MODE -uint8_t beacon_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // TODO: use sleep ticks to measure time between pulses, - // to save power - // 4 clicks: beacon config mode - else if (event == EV_4clicks) { - push_state(beacon_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif // #ifdef USE_BEACON_MODE - - -uint8_t lockout_state(Event event, uint16_t arg) { - #ifdef MOON_DURING_LOCKOUT_MODE - // momentary(ish) moon mode during lockout - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - #ifdef LOCKOUT_MOON_LOWEST - // Use lowest moon configured - uint8_t lvl = ramp_smooth_floor; - if (ramp_discrete_floor < lvl) lvl = ramp_discrete_floor; - set_level(lvl); - #elif defined(LOCKOUT_MOON_FANCY) - uint8_t levels[] = { ramp_smooth_floor, ramp_discrete_floor }; - if ((event & 0x0f) == 2) { - set_level(levels[ramp_style^1]); - } else { - set_level(levels[ramp_style]); - } - #else - // Use moon from current ramp - set_level(nearest_level(1)); - #endif - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - set_level(0); - } - #endif - - // regular event handling - // conserve power while locked out - // (allow staying awake long enough to exit, but otherwise - // be persistent about going back to sleep every few seconds - // even if the user keeps pressing the button) - #ifdef USE_INDICATOR_LED - if (event == EV_enter_state) { - indicator_led(indicator_led_mode >> 2); - } else - #endif - if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { - go_to_standby = 1; - #ifdef USE_INDICATOR_LED - indicator_led(indicator_led_mode >> 2); - #endif - } - return EVENT_HANDLED; - } - #if defined(TICK_DURING_STANDBY) && defined(USE_INDICATOR_LED) - else if (event == EV_sleep_tick) { - if ((indicator_led_mode & 0b00001100) == 0b00001100) { - indicator_blink(arg); - } - return EVENT_HANDLED; - } - #endif - #ifdef USE_INDICATOR_LED - // 3 clicks: rotate through indicator LED modes (lockout mode) - else if (event == EV_3clicks) { - uint8_t mode = indicator_led_mode >> 2; - #ifdef TICK_DURING_STANDBY - mode = (mode + 1) & 3; - #else - mode = (mode + 1) % 3; - #endif - #ifdef INDICATOR_LED_SKIP_LOW - if (mode == 1) { mode ++; } - #endif - indicator_led_mode = (mode << 2) + (indicator_led_mode & 0x03); - indicator_led(mode); - save_config(); - return EVENT_HANDLED; - } - #endif - // 6 clicks: exit - else if (event == EV_6clicks) { - blink_confirm(1); - set_state(off_state, 0); - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - - -uint8_t momentary_state(Event event, uint16_t arg) { - // TODO: momentary strobe here? (for light painting) - - // light up when the button is pressed; go dark otherwise - // button is being held - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - set_level(memorized_level); - return EVENT_HANDLED; - } - // button was released - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - set_level(0); - //go_to_standby = 1; // sleep while light is off - return EVENT_HANDLED; - } - - // Sleep, dammit! (but wait a few seconds first) - // (because standby mode uses such little power that it can interfere - // with exiting via tailcap loosen+tighten unless you leave power - // disconnected for several seconds, so we want to be awake when that - // happens to speed up the process) - else if ((event == EV_tick) && (actual_level == 0)) { - if (arg > TICKS_PER_SECOND*15) { // sleep after 15 seconds - go_to_standby = 1; // sleep while light is off - // TODO: lighted button should use lockout config? - } - return EVENT_HANDLED; - } - - return EVENT_NOT_HANDLED; -} - - -// ask the user for a sequence of numbers, then save them and return to caller -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()) { - static uint8_t config_step; - if (event == EV_enter_state) { - config_step = 0; - set_level(0); - return EVENT_HANDLED; - } - // advance forward through config steps - else if (event == EV_tick) { - if (config_step < num_config_steps) { - push_state(number_entry_state, config_step + 1); - } - else { - // TODO: blink out some sort of success pattern - savefunc(); - save_config(); - //set_state(retstate, retval); - pop_state(); - } - return EVENT_HANDLED; - } - // an option was set (return from number_entry_state) - else if (event == EV_reenter_state) { - config_state_values[config_step] = number_entry_value; - config_step ++; - return EVENT_HANDLED; - } - //return EVENT_NOT_HANDLED; - // eat all other events; don't pass any through to parent - return EVENT_HANDLED; -} - -#ifdef USE_RAMP_CONFIG -void ramp_config_save() { - // parse values - uint8_t val; - if (ramp_style) { // discrete / stepped ramp - - val = config_state_values[0]; - if (val) { ramp_discrete_floor = val; } - - val = config_state_values[1]; - if (val) { ramp_discrete_ceil = MAX_LEVEL + 1 - val; } - - val = config_state_values[2]; - if (val) ramp_discrete_steps = val; - - } else { // smooth ramp - - val = config_state_values[0]; - if (val) { ramp_smooth_floor = val; } - - val = config_state_values[1]; - if (val) { ramp_smooth_ceil = MAX_LEVEL + 1 - val; } - - } -} - -uint8_t ramp_config_state(Event event, uint16_t arg) { - uint8_t num_config_steps; - num_config_steps = 2 + ramp_style; - return config_state_base(event, arg, - num_config_steps, ramp_config_save); -} -#endif // #ifdef USE_RAMP_CONFIG - - -#ifdef USE_THERMAL_REGULATION -void thermal_config_save() { - // parse values - uint8_t val; - - // calibrate room temperature - val = config_state_values[0]; - if (val) { - int8_t rawtemp = temperature - therm_cal_offset; - therm_cal_offset = val - rawtemp; - reset_thermal_history = 1; // invalidate all recent temperature data - } - - val = config_state_values[1]; - if (val) { - // set maximum heat limit - therm_ceil = 30 + val - 1; - } - if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL; -} - -uint8_t thermal_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 2, thermal_config_save); -} -#endif // #ifdef USE_THERMAL_REGULATION - - -#ifdef USE_BEACON_MODE -void beacon_config_save() { - // parse values - uint8_t val = config_state_values[0]; - if (val) { - beacon_seconds = val; - } -} - -uint8_t beacon_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 1, beacon_config_save); -} - -inline void beacon_mode_iter() { - // one iteration of main loop() - set_level(memorized_level); - nice_delay_ms(100); - set_level(0); - nice_delay_ms(((beacon_seconds) * 1000) - 100); -} -#endif // #ifdef USE_BEACON_MODE - - -uint8_t number_entry_state(Event event, uint16_t arg) { - static uint8_t value; - static uint8_t blinks_left; - static uint8_t entry_step; - static uint16_t wait_ticks; - if (event == EV_enter_state) { - value = 0; - blinks_left = arg; - entry_step = 0; - wait_ticks = 0; - return EVENT_HANDLED; - } - // advance through the process: - // 0: wait a moment - // 1: blink out the 'arg' value - // 2: wait a moment - // 3: "buzz" while counting clicks - // 4: save and exit - else if (event == EV_tick) { - // wait a moment - if ((entry_step == 0) || (entry_step == 2)) { - if (wait_ticks < TICKS_PER_SECOND/2) - wait_ticks ++; - else { - entry_step ++; - wait_ticks = 0; - } - } - // blink out the option number - else if (entry_step == 1) { - if (blinks_left) { - if ((wait_ticks & 31) == 10) { - set_level(RAMP_SIZE/4); - } - else if ((wait_ticks & 31) == 20) { - set_level(0); - } - else if ((wait_ticks & 31) == 31) { - blinks_left --; - } - wait_ticks ++; - } - else { - entry_step ++; - wait_ticks = 0; - } - } - else if (entry_step == 3) { // buzz while waiting for a number to be entered - wait_ticks ++; - // buzz for N seconds after last event - if ((wait_ticks & 3) == 0) { - set_level(RAMP_SIZE/6); - } - else if ((wait_ticks & 3) == 2) { - set_level(RAMP_SIZE/8); - } - // time out after 3 seconds - if (wait_ticks > TICKS_PER_SECOND*3) { - //number_entry_value = value; - set_level(0); - entry_step ++; - } - } - else if (entry_step == 4) { - number_entry_value = value; - pop_state(); - } - return EVENT_HANDLED; - } - // count clicks - else if (event == EV_click1_release) { - empty_event_sequence(); - if (entry_step == 3) { // only count during the "buzz" - value ++; - wait_ticks = 0; - // flash briefly - set_level(RAMP_SIZE/2); - delay_4ms(8/2); - set_level(0); - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -// find the ramp level closest to the target, -// using only the levels which are allowed in the current state -uint8_t nearest_level(int16_t target) { - // bounds check - // using int16_t here saves us a bunch of logic elsewhere, - // by allowing us to correct for numbers < 0 or > 255 in one central place - uint8_t mode_min = ramp_smooth_floor; - uint8_t mode_max = ramp_smooth_ceil; - if (ramp_style) { - mode_min = ramp_discrete_floor; - mode_max = ramp_discrete_ceil; - } - if (target < mode_min) return mode_min; - if (target > mode_max) return mode_max; - // the rest isn't relevant for smooth ramping - if (! ramp_style) return target; - - uint8_t ramp_range = ramp_discrete_ceil - ramp_discrete_floor; - ramp_discrete_step_size = ramp_range / (ramp_discrete_steps-1); - uint8_t this_level = ramp_discrete_floor; - - for(uint8_t i=0; i<ramp_discrete_steps; i++) { - this_level = ramp_discrete_floor + (i * (uint16_t)ramp_range / (ramp_discrete_steps-1)); - int16_t diff = target - this_level; - if (diff < 0) diff = -diff; - if (diff <= (ramp_discrete_step_size>>1)) - return this_level; - } - return this_level; -} - - -void blink_confirm(uint8_t num) { - for (; num>0; num--) { - set_level(MAX_LEVEL/4); - delay_4ms(10/4); - set_level(0); - delay_4ms(100/4); - } -} - - -#if defined(USE_INDICATOR_LED) && defined(TICK_DURING_STANDBY) -// beacon-like mode for the indicator LED -void indicator_blink(uint8_t arg) { - #define USE_FANCIER_BLINKING_INDICATOR - #ifdef USE_FANCIER_BLINKING_INDICATOR - - // fancy blink, set off/low/high levels here: - uint8_t seq[] = {0, 1, 2, 1, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0}; - indicator_led(seq[arg & 15]); - - #else // basic blink, 1/8th duty cycle - - if (! (arg & 7)) { - indicator_led(2); - } - else { - indicator_led(0); - } - - #endif -} -#endif - - -void load_config() { - if (load_eeprom()) { - ramp_style = eeprom[0]; - #ifdef USE_RAMP_CONFIG - ramp_smooth_floor = eeprom[1]; - ramp_smooth_ceil = eeprom[2]; - ramp_discrete_floor = eeprom[3]; - ramp_discrete_ceil = eeprom[4]; - ramp_discrete_steps = eeprom[5]; - #endif - #ifdef USE_BEACON_MODE - beacon_seconds = eeprom[6]; - #endif - #ifdef USE_THERMAL_REGULATION - therm_ceil = eeprom[EEPROM_BYTES_BASE]; - therm_cal_offset = eeprom[EEPROM_BYTES_BASE+1]; - #endif - #ifdef USE_INDICATOR_LED - indicator_led_mode = eeprom[EEPROM_BYTES_BASE+EEPROM_THERMAL_BYTES]; - #endif - } -} - -void save_config() { - eeprom[0] = ramp_style; - #ifdef USE_RAMP_CONFIG - eeprom[1] = ramp_smooth_floor; - eeprom[2] = ramp_smooth_ceil; - eeprom[3] = ramp_discrete_floor; - eeprom[4] = ramp_discrete_ceil; - eeprom[5] = ramp_discrete_steps; - #endif - #ifdef USE_BEACON_MODE - eeprom[6] = beacon_seconds; - #endif - #ifdef USE_THERMAL_REGULATION - eeprom[EEPROM_BYTES_BASE ] = therm_ceil; - eeprom[EEPROM_BYTES_BASE+1] = therm_cal_offset; - #endif - #ifdef USE_INDICATOR_LED - eeprom[EEPROM_BYTES_BASE+EEPROM_THERMAL_BYTES] = indicator_led_mode; - #endif - - save_eeprom(); -} - -void low_voltage() { - StatePtr state = current_state; - - // TODO: turn off aux LED(s) when power is really low - - if (0) {} // placeholder - - // in normal mode, step down or turn off - else if (state == steady_state) { - if (actual_level > 1) { - uint8_t lvl = (actual_level >> 1) + (actual_level >> 2); - set_level(lvl); - #ifdef USE_THERMAL_REGULATION - target_level = lvl; - #ifdef USE_SET_LEVEL_GRADUALLY - // not needed? - //set_level_gradually(lvl); - #endif - #endif - } - else { - set_state(off_state, 0); - } - } - // all other modes, just turn off when voltage is low - else { - set_state(off_state, 0); - } -} - - -void setup() { - // blink at power-on to let user know power is connected - set_level(RAMP_SIZE/8); - delay_4ms(3); - set_level(0); - - load_config(); - - push_state(off_state, 0); -} - - -void loop() { - - StatePtr state = current_state; - - if (0) {} - - #ifdef USE_BATTCHECK - else if (state == battcheck_state) { - battcheck(); - } - #endif - - #ifdef USE_BEACON_MODE - else if (state == beacon_state) { - beacon_mode_iter(); - } - #endif - - #ifdef USE_THERMAL_REGULATION - // TODO: blink out therm_ceil during thermal_config_state? - else if (state == tempcheck_state) { - blink_num(temperature); - nice_delay_ms(1000); - } - #endif - - #ifdef USE_IDLE_MODE - else { - // doze until next clock tick - idle_mode(); - } - #endif - -} diff --git a/spaghetti-monster/rampingios/rampingiosv3.svg b/spaghetti-monster/rampingios/rampingiosv3.svg deleted file mode 100644 index bc9e6b3..0000000 --- a/spaghetti-monster/rampingios/rampingiosv3.svg +++ /dev/null @@ -1,4113 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="18.056446cm" - height="26.675991cm" - id="svg2" - version="1.1" - inkscape:version="0.92.1 r15371" - sodipodi:docname="rampingiosv3.svg" - inkscape:export-filename="/tmp/rampingiosv3-ui.png" - inkscape:export-xdpi="114.26005" - inkscape:export-ydpi="114.26005"> - <defs - id="defs4"> - <linearGradient - inkscape:collect="always" - id="linearGradient18929"> - <stop - id="stop18927" - offset="0" - style="stop-color:#0000ff;stop-opacity:0" /> - <stop - id="stop18925" - offset="1" - style="stop-color:#0000ff;stop-opacity:1" /> - </linearGradient> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker61712" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path61710" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#7777ff;fill-opacity:1;fill-rule:evenodd;stroke:#7777ff;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker50318" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart"> - <path - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path50316" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker49438" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path49436" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#7777ff;fill-opacity:1;fill-rule:evenodd;stroke:#7777ff;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker48588" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart"> - <path - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path48586" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path12697" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker12161" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9801" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(-0.4,0,0,-0.4,-4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Lstart" - orient="auto" - refY="0" - refX="0" - id="Arrow1Lstart" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9792" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.8,0,0,0.8,10,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker11118" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path11116" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker10592" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path10590" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mstart" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9798" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker9610" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path9608" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <pattern - inkscape:stockid="Sand (bitmap)" - id="pattern7084" - height="256" - width="256" - patternUnits="userSpaceOnUse"> - <!-- Seamless texture provided by FreeSeamlessTextures.com --> - <!-- License: creative commons attribution --> - <image - xlink:href="data:image/jpeg;base64,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 /p1//9k= " - y="0" - x="0" - id="image7082" - height="260" - width="260" /> - </pattern> - <linearGradient - id="linearGradient1694" - inkscape:collect="always"> - <stop - id="stop1690" - offset="0" - style="stop-color:#000000;stop-opacity:0.74496644" /> - <stop - id="stop1692" - offset="1" - style="stop-color:#000000;stop-opacity:0;" /> - </linearGradient> - <linearGradient - id="linearGradient5876"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop5878" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop5880" /> - </linearGradient> - <linearGradient - id="linearGradient5850" - osb:paint="solid"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop5852" /> - </linearGradient> - <pattern - inkscape:stockid="Sand (bitmap)" - id="sand_bitmap" - height="256" - width="256" - patternUnits="userSpaceOnUse"> - <!-- Seamless texture provided by FreeSeamlessTextures.com --> - <!-- License: creative commons attribution --> - <image - xlink:href="data:image/jpeg;base64,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 /p1//9k= " - y="0" - x="0" - id="image9" - height="260" - width="260" /> - </pattern> - <linearGradient - id="linearGradient4336"> - <stop - style="stop-color:#ffffff;stop-opacity:0;" - offset="0" - id="stop4338" /> - <stop - id="stop5884" - offset="0.5" - style="stop-color:#ffffff;stop-opacity:0;" /> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="1" - id="stop4340" /> - </linearGradient> - <linearGradient - id="linearGradient4304"> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="0" - id="stop4306" /> - <stop - style="stop-color:#000000;stop-opacity:0.39655173;" - offset="1" - id="stop4308" /> - </linearGradient> - <linearGradient - id="linearGradient4296"> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="0" - id="stop4298" /> - <stop - style="stop-color:#000000;stop-opacity:0.28627452;" - offset="1" - id="stop4300" /> - </linearGradient> - <linearGradient - id="linearGradient4276"> - <stop - style="stop-color:#000000;stop-opacity:1;" - offset="0" - id="stop4278" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop4280" /> - </linearGradient> - <linearGradient - id="linearGradient6735" - osb:paint="gradient"> - <stop - style="stop-color:#000000;stop-opacity:0.31764707;" - offset="0" - id="stop6737" /> - <stop - style="stop-color:#000000;stop-opacity:0;" - offset="1" - id="stop6739" /> - </linearGradient> - <marker - inkscape:stockid="Arrow1Lend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Lend" - style="overflow:visible"> - <path - id="path3850" - d="M -10.666667,0 -14.933333,4.2666667 0,0 -14.933333,-4.2666667 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.85333335pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend" - style="overflow:visible"> - <path - id="path3856" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <inkscape:path-effect - effect="skeletal" - id="path-effect3841" - is_visible="true" - pattern="m 0,5 10,5 V 0 Z" - copytype="single_stretched" - prop_scale="1" - scale_y_rel="false" - spacing="0" - normal_offset="0" - tang_offset="0" - prop_units="false" - vertical_pattern="false" - fuse_tolerance="0" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-5" - style="overflow:visible"> - <path - id="path3856-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-0" - style="overflow:visible"> - <path - id="path3856-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-58" - style="overflow:visible"> - <path - id="path3856-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-9" - style="overflow:visible"> - <path - id="path3856-54" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-3" - style="overflow:visible"> - <path - id="path3856-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-03" - style="overflow:visible"> - <path - id="path3856-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-2" - style="overflow:visible"> - <path - id="path3856-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-4" - style="overflow:visible"> - <path - id="path3856-00" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-7" - style="overflow:visible"> - <path - id="path3856-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-76" - style="overflow:visible"> - <path - id="path3856-64" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-6" - style="overflow:visible"> - <path - id="path3856-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-65" - style="overflow:visible"> - <path - id="path3856-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-1" - style="overflow:visible"> - <path - id="path3856-01" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-29" - style="overflow:visible"> - <path - id="path3856-60" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-71" - style="overflow:visible"> - <path - id="path3856-83" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-26" - style="overflow:visible"> - <path - id="path3856-67" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-61" - style="overflow:visible"> - <path - id="path3856-86" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-48" - style="overflow:visible"> - <path - id="path3856-867" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5244" - style="overflow:visible"> - <path - id="path5246" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5248" - style="overflow:visible"> - <path - id="path5250" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5252" - style="overflow:visible"> - <path - id="path5254" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5256" - style="overflow:visible"> - <path - id="path5258" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5260" - style="overflow:visible"> - <path - id="path5262" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5264" - style="overflow:visible"> - <path - id="path5266" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-05" - style="overflow:visible"> - <path - id="path3856-52" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-33" - style="overflow:visible"> - <path - id="path3856-38" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-61-6" - style="overflow:visible"> - <path - id="path3856-86-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-64" - style="overflow:visible"> - <path - id="path3856-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-43" - style="overflow:visible"> - <path - id="path3856-33" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-33-5" - style="overflow:visible"> - <path - id="path3856-38-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-60" - style="overflow:visible"> - <path - id="path3856-96" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-59" - style="overflow:visible"> - <path - id="path3856-969" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-36" - style="overflow:visible"> - <path - id="path3856-02" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-8" - style="overflow:visible"> - <path - id="path3856-80" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-08" - style="overflow:visible"> - <path - id="path3856-28" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-81" - style="overflow:visible"> - <path - id="path3856-89" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-57" - style="overflow:visible"> - <path - id="path3856-66" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-22" - style="overflow:visible"> - <path - id="path3856-31" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-42" - style="overflow:visible"> - <path - id="path3856-50" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-84" - style="overflow:visible"> - <path - id="path3856-06" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-04" - style="overflow:visible"> - <path - id="path3856-62" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-32" - style="overflow:visible"> - <path - id="path3856-866" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-66" - style="overflow:visible"> - <path - id="path3856-78" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-72" - style="overflow:visible"> - <path - id="path3856-19" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-49" - style="overflow:visible"> - <path - id="path3856-34" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-96" - style="overflow:visible"> - <path - id="path3856-61" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-23" - style="overflow:visible"> - <path - id="path3856-18" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-10" - style="overflow:visible"> - <path - id="path3856-87" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-63" - style="overflow:visible"> - <path - id="path3856-317" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-01" - style="overflow:visible"> - <path - id="path3856-10" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-16" - style="overflow:visible"> - <path - id="path3856-55" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-86" - style="overflow:visible"> - <path - id="path3856-51" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62" - style="overflow:visible"> - <path - id="path3856-91" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-7" - style="overflow:visible"> - <path - id="path3856-91-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-06" - style="overflow:visible"> - <path - id="path3856-26" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79" - style="overflow:visible"> - <path - id="path3856-20" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37" - style="overflow:visible"> - <path - id="path3856-59" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-12" - style="overflow:visible"> - <path - id="path3856-93" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45" - style="overflow:visible"> - <path - id="path3856-03" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1" - style="overflow:visible"> - <path - id="path3856-20-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320" - style="overflow:visible"> - <path - id="path3856-615" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-4" - style="overflow:visible"> - <path - id="path3856-615-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-5" - style="overflow:visible"> - <path - id="path3856-615-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374" - style="overflow:visible"> - <path - id="path3856-525" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-7" - style="overflow:visible"> - <path - id="path3856-525-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30" - style="overflow:visible"> - <path - id="path3856-786" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8" - style="overflow:visible"> - <path - id="path3856-786-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1" - style="overflow:visible"> - <path - id="path3856-786-4-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2" - style="overflow:visible"> - <path - id="path3856-786-4-4-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2-8" - style="overflow:visible"> - <path - id="path3856-786-4-4-0-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-3" - style="overflow:visible"> - <path - id="path3856-525-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367" - style="overflow:visible"> - <path - id="path3856-53" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5228" - style="overflow:visible"> - <path - id="path5226" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-606" - style="overflow:visible"> - <path - id="path3856-261" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker5228-8" - style="overflow:visible"> - <path - id="path5226-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-6" - style="overflow:visible"> - <path - id="path3856-91-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6" - style="overflow:visible"> - <path - id="path3856-53-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597" - style="overflow:visible"> - <path - id="path3856-76" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-3" - style="overflow:visible"> - <path - id="path3856-53-1-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699-6" - style="overflow:visible" - inkscape:isstock="true"> - <path - inkscape:connector-curvature="0" - id="path12697-3" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1-9" - style="overflow:visible"> - <path - id="path3856-20-0-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-1" - style="overflow:visible"> - <path - id="path3856-59-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-0" - style="overflow:visible"> - <path - id="path3856-03-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3" - style="overflow:visible"> - <path - id="path3856-53-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-0" - style="overflow:visible"> - <path - id="path3856-53-8-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8" - style="overflow:visible"> - <path - id="path3856-53-8-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-7" - style="overflow:visible"> - <path - id="path3856-53-8-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-09" - style="overflow:visible"> - <path - id="path3856-25" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-09-2" - style="overflow:visible"> - <path - id="path3856-25-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-4" - style="overflow:visible"> - <path - id="path3856-53-8-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5" - style="overflow:visible"> - <path - id="path3856-53-8-86" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-0-4" - style="overflow:visible"> - <path - id="path3856-53-8-4-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8-4" - style="overflow:visible"> - <path - id="path3856-53-8-8-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-8-2" - style="overflow:visible"> - <path - id="path3856-53-8-8-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-7-0" - style="overflow:visible"> - <path - id="path3856-53-8-7-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31" - style="overflow:visible"> - <path - id="path3856-103" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0" - style="overflow:visible"> - <path - id="path3856-53-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1" - style="overflow:visible"> - <path - id="path3856-103-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3" - style="overflow:visible"> - <path - id="path3856-53-3-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3-6" - style="overflow:visible"> - <path - id="path3856-53-3-8-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0" - style="overflow:visible"> - <path - id="path3856-103-9-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-0-6" - style="overflow:visible"> - <path - id="path3856-03-8-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-1-8" - style="overflow:visible"> - <path - id="path3856-59-2-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-3-2" - style="overflow:visible"> - <path - id="path3856-53-1-6-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597-9" - style="overflow:visible"> - <path - id="path3856-76-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-6-0" - style="overflow:visible"> - <path - id="path3856-53-1-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker12699-3" - style="overflow:visible" - inkscape:isstock="true"> - <path - inkscape:connector-curvature="0" - id="path12697-2" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#009d00;fill-opacity:1;fill-rule:evenodd;stroke:#009d00;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-1-1" - style="overflow:visible"> - <path - id="path3856-20-0-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="marker7637-9" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Mstart" - inkscape:collect="always"> - <path - inkscape:connector-curvature="0" - transform="matrix(0.4,0,0,0.4,4,0)" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path7635-9" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-45-1" - style="overflow:visible"> - <path - id="path3856-03-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-37-9" - style="overflow:visible"> - <path - id="path3856-59-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-79-0" - style="overflow:visible"> - <path - id="path3856-20-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-7-5" - style="overflow:visible"> - <path - id="path3856-91-0-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-62-70" - style="overflow:visible"> - <path - id="path3856-91-4" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - inkscape:collect="always" - xlink:href="#linearGradient1694" - id="linearGradient1364-8" - x1="415.74805" - y1="495.00006" - x2="415.74805" - y2="215.43314" - gradientUnits="userSpaceOnUse" - gradientTransform="translate(904.95044,-71.333651)" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-14" - style="overflow:visible"> - <path - id="path3856-69" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9" - style="overflow:visible"> - <path - id="path3856-53-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42788" - style="overflow:visible"> - <path - id="path42786" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88" - style="overflow:visible"> - <path - id="path3856-868" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42794" - style="overflow:visible"> - <path - id="path42792" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42798" - style="overflow:visible"> - <path - id="path42796" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="marker42802" - style="overflow:visible"> - <path - id="path42800" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-5" - style="overflow:visible"> - <path - id="path3856-868-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9" - style="overflow:visible"> - <path - id="path3856-868-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4" - style="overflow:visible"> - <path - id="path3856-868-6-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-9-8" - style="overflow:visible"> - <path - id="path3856-53-2-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-1" - style="overflow:visible"> - <path - id="path3856-868-6-1-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0" - style="overflow:visible"> - <path - id="path3856-868-6-1-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7" - style="overflow:visible"> - <path - id="path3856-868-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker61712-0" - style="overflow:visible" - inkscape:isstock="true"> - <path - id="path61710-6" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#7777ff;fill-opacity:1;fill-rule:evenodd;stroke:#7777ff;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4-8" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7-6" - style="overflow:visible"> - <path - id="path3856-868-7-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-0-3-6-6" - style="overflow:visible"> - <path - id="path3856-53-3-8-4-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0-9" - style="overflow:visible"> - <path - id="path3856-103-9-0-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-0" - style="overflow:visible"> - <path - id="path3856-53-8-86-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-6" - style="overflow:visible"> - <path - id="path3856-53-8-86-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-7" - style="overflow:visible"> - <path - id="path3856-53-8-86-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-2" - style="overflow:visible"> - <path - id="path3856-53-8-86-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-5-5" - style="overflow:visible"> - <path - id="path3856-53-8-86-92" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-31-1-0-9-9" - style="overflow:visible"> - <path - id="path3856-103-9-0-1-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-02" - style="overflow:visible"> - <path - id="path3856-53-8-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-51" - style="overflow:visible"> - <path - id="path3856-53-8-10" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-367-3-50" - style="overflow:visible"> - <path - id="path3856-53-8-64" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-0-4-9" - style="overflow:visible"> - <path - id="path3856-868-6-1-5-7-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mstart" - orient="auto" - refY="0" - refX="0" - id="marker14034-2-9" - style="overflow:visible" - inkscape:isstock="true" - inkscape:collect="always"> - <path - inkscape:connector-curvature="0" - id="path14032-9-7" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1" - transform="matrix(0.4,0,0,0.4,4,0)" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-597-9-5" - style="overflow:visible"> - <path - id="path3856-76-6-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3" - style="overflow:visible"> - <path - id="path3856-868-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9" - style="overflow:visible"> - <path - id="path3856-868-1-6" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9-3" - style="overflow:visible"> - <path - id="path3856-868-1-6-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-3-9-3-4" - style="overflow:visible"> - <path - id="path3856-868-1-6-3-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-4" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-1" - style="overflow:visible"> - <path - id="path3856-868-78" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-7" - style="overflow:visible"> - <path - id="path3856-786-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-15" - style="overflow:visible"> - <path - id="path3856-786-4-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-8" - style="overflow:visible"> - <path - id="path3856-786-4-4-07" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2-1" - style="overflow:visible"> - <path - id="path3856-786-4-4-0-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-30-8-1-2-8-1" - style="overflow:visible"> - <path - id="path3856-786-4-4-0-9-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-3-3" - style="overflow:visible"> - <path - id="path3856-525-6-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-7-4" - style="overflow:visible"> - <path - id="path3856-525-4-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-374-2" - style="overflow:visible"> - <path - id="path3856-525-3" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-5-6" - style="overflow:visible"> - <path - id="path3856-615-6-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-4-9" - style="overflow:visible"> - <path - id="path3856-615-7-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-320-7" - style="overflow:visible"> - <path - id="path3856-615-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-12-2" - style="overflow:visible"> - <path - id="path3856-93-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <linearGradient - gradientTransform="translate(929.54564,-74.94436)" - inkscape:collect="always" - xlink:href="#linearGradient7283" - id="linearGradient7285" - x1="548.74939" - y1="603.33936" - x2="548.74939" - y2="671.01959" - gradientUnits="userSpaceOnUse" /> - <linearGradient - inkscape:collect="always" - id="linearGradient7283"> - <stop - style="stop-color:#ff0000;stop-opacity:1;" - offset="0" - id="stop7279" /> - <stop - style="stop-color:#ff0000;stop-opacity:0;" - offset="1" - id="stop7281" /> - </linearGradient> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4336" - id="radialGradient7151" - cx="359.77701" - cy="645.03406" - fx="359.77701" - fy="645.03406" - r="88.283775" - gradientTransform="matrix(1,0,0,0.45837941,929.54564,270.2418)" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient4336" - id="radialGradient5882" - cx="-305.73798" - cy="215.58585" - fx="-305.73798" - fy="215.58585" - r="82.355362" - gradientTransform="matrix(0.91925378,0.02375671,-0.01750658,0.91984172,-20.913072,24.544353)" - gradientUnits="userSpaceOnUse" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-3" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-5" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-7" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-0" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-7" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-07" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-2" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-2" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-6" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-76" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-9-4-4-35" - style="overflow:visible"> - <path - id="path3856-868-6-1-0-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient18929" - id="radialGradient18931" - cx="1287.2483" - cy="838.64679" - fx="1287.2483" - fy="838.64679" - r="69.243234" - gradientTransform="matrix(1.6991232,0.01607634,-0.00691966,0.73134605,-894.14208,204.61155)" - gradientUnits="userSpaceOnUse" /> - <radialGradient - inkscape:collect="always" - xlink:href="#linearGradient18929" - id="radialGradient18931-2" - cx="1287.2483" - cy="838.64679" - fx="1287.2483" - fy="838.64679" - r="69.243233" - gradientTransform="matrix(1.6991232,0.01607634,-0.00691966,0.73134605,-715.73169,39.063279)" - gradientUnits="userSpaceOnUse" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-2" - style="overflow:visible"> - <path - id="path3856-868-0" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4)" - d="m 1109.1006,543.61207 c -3.0273,101.10987 20.2381,108.5803 120.8038,109.2893" - id="path5213-6-8-4-9-9-1-3-0-0-33" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7-2" - style="overflow:visible"> - <path - id="path3856-868-7-8" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7-2-1" - style="overflow:visible"> - <path - id="path3856-868-7-8-9" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - <marker - inkscape:stockid="Arrow1Mend" - orient="auto" - refY="0" - refX="0" - id="Arrow1Mend-88-7-2-6" - style="overflow:visible"> - <path - id="path3856-868-7-8-1" - d="M -4.2666667,0 -6.4,2.1333333 1.0666667,0 -6.4,-2.1333333 Z" - style="fill-rule:evenodd;stroke:#000000;stroke-width:0.42666668pt" - inkscape:connector-curvature="0" /> - </marker> - </defs> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="1" - inkscape:pageshadow="2" - inkscape:zoom="1.2050864" - inkscape:cx="341.22418" - inkscape:cy="504.11322" - inkscape:document-units="px" - inkscape:current-layer="layer1" - showgrid="false" - showguides="true" - gridtolerance="1" - inkscape:window-width="2453" - inkscape:window-height="1415" - inkscape:window-x="0" - inkscape:window-y="0" - inkscape:window-maximized="1" - fit-margin-top="0.5" - fit-margin-left="0.5" - fit-margin-right="0.5" - fit-margin-bottom="0.5" - units="cm" - inkscape:snap-global="false" - inkscape:snap-bbox="true" - inkscape:bbox-paths="true" - inkscape:bbox-nodes="true" - inkscape:snap-bbox-edge-midpoints="true" - inkscape:snap-bbox-midpoints="true"> - <inkscape:grid - type="xygrid" - id="grid3065" - empspacing="5" - visible="true" - enabled="true" - snapvisiblegridlinesonly="true" - units="cm" - spacingx="37.795276" - spacingy="37.795276" - originx="-1038.3034" - originy="-33.268489" /> - </sodipodi:namedview> - <metadata - id="metadata7"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(-1038.3034,-81.024808)"> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:29.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1065.9954" - y="133.45045" - id="text3021-8-4-1-8-8-2-3"><tspan - sodipodi:role="line" - x="1065.9954" - y="133.45045" - style="font-size:29.33333397px;line-height:1.25;stroke-width:1.06666672" - id="tspan56267">Ramps:</tspan></text> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-4" - width="416.73956" - height="363.7735" - x="1058.2677" - y="101.00932" /> - <g - id="g14689" - transform="translate(-36.45207,-51.863501)"> - <text - id="text3021-8-4-1-8-8-7-4" - y="699.71509" - x="1639.6669" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:1;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:18.66666603px;line-height:1;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672" - y="699.71509" - x="1639.6669" - id="tspan3023-4-0-1-9-63-3-3" - sodipodi:role="line">Thermal</tspan><tspan - id="tspan4199-0" - style="font-size:18.66666603px;line-height:1;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672" - y="718.38177" - x="1639.6669" - sodipodi:role="line">Cfg</tspan></text> - <ellipse - ry="31.258007" - rx="50.681404" - cy="699.95654" - cx="1638.769" - id="path3639-4-4-6-3" - style="fill:none;stroke:#ff0000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333344, 2.13333344;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09)" - d="m 1526.1143,542.42127 c 38.1021,-33.86186 102.6,-14.46467 75.3226,68.88748" - id="path5213-6-8-4-9-9-8-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g14683" - transform="translate(-52.278414,208.69872)"> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5" - y="511.39166" - x="1639.1299" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:85.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:18.66666603px;line-height:85.00000238%;text-align:center;text-anchor:middle;stroke-width:1.06666672" - y="511.39166" - x="1639.1299" - id="tspan3023-4-0-1-9-63-8-83-9" - sodipodi:role="line">Beacon</tspan><tspan - style="font-size:18.66666603px;line-height:85.00000238%;text-align:center;text-anchor:middle;stroke-width:1.06666672" - y="527.2583" - x="1639.1299" - sodipodi:role="line" - id="tspan14667">Cfg</tspan></text> - <ellipse - inkscape:transform-center-y="8.5053065" - inkscape:transform-center-x="-3.1895436" - ry="21.797352" - rx="50.681404" - cy="512.03644" - cx="1639.2438" - id="path3639-4-4-9-1-4" - style="fill:none;stroke:#000000;stroke-width:2.39758635;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:2.13333344;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-2)" - d="m 1336.1309,751.93617 c 54.5084,-15.91562 5.2824,-32.40651 63.036,-62.65111" - id="path5213-6-8-4-9-9-8-3-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-09-2)" - d="m 1356.8036,913.47851 c 110.056,-5.75796 -71.5174,-184.74962 172.4057,-190.29891" - id="path5213-6-8-4-9-9-8-4-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <rect - style="opacity:1;fill:url(#linearGradient1364-8);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect1356-0" - width="37.795277" - height="264.56693" - x="1320.6984" - y="144.09947" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-312.03278" - y="1346.9868" - id="text3021-8-4-1-8-8-3-4" - transform="rotate(-90)"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-6-2" - x="-312.03278" - y="1346.9868" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Ramp</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1268.1858" - y="203.77095" - id="text3021-8-4-1-8-6-14-2-4-7-7-9" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1268.1858" - y="203.77095" - id="tspan3613-9-7-5-6" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Ceil</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1263.0579" - y="426.17856" - id="text3021-8-4-1-8-6-14-2-4-7-7-3-1" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1263.0579" - y="426.17856" - id="tspan3613-9-7-5-5-0" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Floor</tspan></text> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-70)" - d="M 1419.75,188.60753 V 372.1669" - id="path5213-6-8-2-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-62-7-5)" - d="M 1400.1843,366.71374 V 191.75683" - id="path5213-6-8-2-9-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-239.43126" - y="1515.5392" - id="text3021-8-4-1-8-6-14-2-4-7-7-3-3-2" - transform="matrix(0,-1.0975814,0.91109416,0,0,0)"><tspan - sodipodi:role="line" - x="-239.43126" - y="1515.5392" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672" - id="tspan2698-2">Turbo</tspan></text> - <path - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-79-0)" - d="m 1159.4045,270.23739 c 108.4581,4.22547 23.1574,-88.17063 154.3238,-89.5992" - id="path5213-6-8-4-9-9-8-2-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-37-9)" - d="m 1161.2023,305.96846 c 19.9433,0.68416 37.9411,1.8706 43.0277,22.9023 23.0349,95.24415 139.8266,163.92069 134.3257,47.65282" - id="path5213-6-8-4-9-9-9-2-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker7637-9);marker-end:url(#Arrow1Mend-45-1)" - d="m 1314.3007,333.29999 c -90.8252,5.74785 -43.5378,-60.02663 -137.7344,-45.56247" - id="path5213-6-8-4-9-9-6-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" - d="m 1320.7414,332.0074 h 37.7525" - id="path15687-90" - inkscape:connector-curvature="0" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1109.0515" - y="-593.28467" - id="text16320-2" - transform="rotate(42.138927)"><tspan - sodipodi:role="line" - id="tspan16318-8" - x="1109.0515" - y="-593.28467">Mem</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="-399.5589" - y="1453.8257" - id="text16326-8" - transform="rotate(-90)"><tspan - sodipodi:role="line" - id="tspan16324-0" - x="-399.5589" - y="1453.8257">Regulated Hybrid -------------- Direct Drive</tspan></text> - <g - id="g16453-4" - transform="translate(988.22664,-147.99262)"> - <path - inkscape:connector-curvature="0" - id="path16424-0" - d="M 453.54332,291.02364 V 555.59057" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-9" - d="M 467.5047,555.59057 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-5-1" - d="M 467.5047,480.00002 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <path - inkscape:connector-curvature="0" - id="path16426-3-9" - d="M 467.5047,291.02364 H 453.54332" - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" - d="m 1319.7047,180.764 h 37.7525" - id="path15687-2-6" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-6-0)" - d="m 1131.0344,258.42719 c 48.1809,-3.99296 64.2076,-2.68523 79.9712,-42.47521 42.8072,-108.05255 133.489,-146.16407 131.2384,-34.5044" - id="path5213-6-8-4-9-9-9-29-5-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <path - style="opacity:1;fill:#c0c0c0;fill-opacity:1;stroke:#040000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 4;stroke-dashoffset:0;stroke-opacity:1" - d="m 1319.7047,381.98134 h 37.7525" - id="path15687-9-5" - inkscape:connector-curvature="0" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-14)" - d="m 1361.0391,358.39365 c 26.3813,0.76852 22.4829,57.6582 -8.9055,81.08668 -31.3884,23.42848 -96.7886,5.87049 -137.724,-26.36711" - id="path5213-6-8-4-9-9-1-42" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <g - id="g47455" - transform="translate(-394.62442,281.246)"> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5-64" - y="119.67136" - x="1502.3363" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="119.67136" - x="1502.3363" - id="tspan3023-4-0-1-9-63-8-83-9-1" - sodipodi:role="line">Ramp</tspan></text> - <ellipse - inkscape:transform-center-y="11.351831" - inkscape:transform-center-x="-4.2569368" - ry="29.092394" - rx="67.643234" - cy="122.72764" - cx="1535.9958" - id="path3639-4-4-9-1-4-2" - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - inkscape:transform-center-y="10.020862" - inkscape:transform-center-x="-5.2422885" - id="text3021-8-4-1-8-8-2-8-5-6-8" - y="142.59866" - x="1515.2289" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672" - y="142.59866" - x="1515.2289" - id="tspan3023-4-0-1-9-63-8-83-9-9-8" - sodipodi:role="line">Cfg</tspan></text> - </g> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.6915,166.15809 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.8, 2.13333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1498.5459,209.88219 c 49.5295,21.01119 54.6565,-32.82141 113.6548,0" - id="path5213-6-8-4-9-9-9-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:2.13333344;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.0847,386.36671 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-8-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88)" - d="m 1499.0847,431.64591 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-1-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1508.8501" - y="125.85442" - id="text3021-8-4-1-8-6-1-5-3"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-6-4-1-8" - x="1508.8501" - y="125.85442" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Actions</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1368.1968" - y="205.90257" - id="text3021-8-4-1-8-6-14-2-4-0" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1368.1968" - y="205.90257" - id="tspan3613-9-4" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">1 Fast Click</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1400.5447" - y="254.90924" - id="text3021-8-4-1-8-6-14-2-4-6-7" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1400.5447" - y="254.90924" - id="tspan3613-9-8-6" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">Hold</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1364.4215" - y="446.51736" - id="text3021-8-4-1-8-6-14-2-4-7-8" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1364.4215" - y="446.51736" - id="tspan3613-9-7-9" - style="font-size:17.06666756px;line-height:1.25;stroke-width:1.06666672">3 Fast Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1363.7708" - y="497.13034" - id="text3021-8-4-1-8-6-14-2-4-1-0" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1363.7708" - y="497.13034" - id="tspan3613-9-1-6" - style="font-size:17.06666756px;line-height:1.25;fill:#7777ff;fill-opacity:1;stroke-width:1.06666672">Other Action</tspan></text> - <rect - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="rect5159-8" - width="129.83826" - height="363.63089" - x="1491.3889" - y="100.98911" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9)" - d="m 1499.2534,277.65781 c 49.5295,21.01119 54.6565,-32.82142 113.6548,0" - id="path5213-6-8-4-9-9-56-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#009d00;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:12.80000067, 2.13333344;stroke-dashoffset:2.98666692;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9)" - d="m 1498.1078,321.38191 c 49.5295,21.01119 54.6565,-32.82141 113.6548,0" - id="path5213-6-8-4-9-9-9-29-90" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1365.7407" - y="328.28253" - id="text3021-8-4-1-8-6-14-2-4-12-3" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1365.7407" - y="328.28253" - id="tspan3613-9-70-3" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">2 Fast Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#009d00;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1373.6346" - y="377.28925" - id="text3021-8-4-1-8-6-14-2-4-6-9-3" - transform="scale(1.0975814,0.91109416)"><tspan - sodipodi:role="line" - x="1373.6346" - y="377.28925" - id="tspan3613-9-8-3-7" - style="font-size:17.06666756px;line-height:1.25;fill:#009d00;fill-opacity:1;stroke-width:1.06666672">Click, Hold</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:58.66666794px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="-608.83911" - y="1684.3434" - id="text5250-2" - transform="rotate(-90)"><tspan - y="1684.3434" - x="-608.83911" - sodipodi:role="line" - id="tspan6532-6">RampingIOS V3</tspan></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666667, 4.26666667;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-5)" - d="m 1138.7763,513.59537 c 2.4,42.76971 21.5485,46.01827 55.7548,50.73993" - id="path5213-6-8-4-9-9-8-3-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9)" - d="m 874.51802,524.00086 c -12.1825,60.27066 -20.8223,402.16388 133.00958,463.61058" - id="path5213-6-8-4-9-9-1-3-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4)" - d="m 1108.922,569.09989 c -0.8727,158.93719 0.4237,191.93185 105.6048,192.31379" - id="path5213-6-8-4-9-9-1-3-0-0-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-35-3" - inkscape:transform-center-x="-2.6057619" - inkscape:transform-center-y="-24.409989" - transform="translate(2.0536898,-2.6404583)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-3-68" - id="textPath18895"><tspan - id="tspan7287-62-7"> 7 Clicks</tspan></textPath></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4)" - d="m 1109.1006,543.61207 c -3.0273,101.10987 20.2381,108.5803 120.8038,109.2893" - id="path5213-6-8-4-9-9-1-3-0-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - transform="translate(980.51459,-148.00986)" - id="g23629-5-4"> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-0-8" - cx="140.59442" - cy="435.21741" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="112.51038" - y="444.62402" - id="text3021-8-9-7"><tspan - sodipodi:role="line" - id="tspan3023-4-6-0" - x="112.51038" - y="444.62402" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - </g> - <g - transform="translate(969.27179,76.164687)" - id="g23629-5-4-8"> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-0-8-6" - cx="140.59442" - cy="435.21741" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="112.51038" - y="444.62402" - id="text3021-8-9-7-2"><tspan - sodipodi:role="line" - id="tspan3023-4-6-0-4" - x="112.51038" - y="444.62402" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - </g> - <path - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-367-9-8)" - d="m 1364.0175,147.54301 c 29.3791,49.772 28.7391,140.19451 -0.7576,180.57634" - id="path5213-6-8-4-9-9-56-7-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0)" - d="m 905.55573,555.02274 c 8.2381,55.86142 12.4246,16.66987 28.876,-16.227 18.1418,-36.27675 65.1509,-72.19798 76.57317,0.99224" - id="path5213-6-8-4-9-9-1-3-0-0-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7)" - d="m 983.17997,330.24226 c -47.6705,-9.8516 -110.3689,-9.28576 -158.1487,2.96046" - id="path5213-6-8-4-9-9-3-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:none;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4)" - d="m 881.66303,554.67556 c 0,0 25.6454,8.80842 22.0934,-6.76915" - id="path5213-6-8-4-9-9-1-3-0-0-6-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:none;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.133, 2.133;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4-8)" - d="m 1366.1809,151.11654 c 0,0 8.8213,16.58792 -2.1634,-3.57353" - id="path5213-6-8-4-9-9-1-3-0-0-6-4-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2" - inkscape:transform-center-x="1.1517845" - inkscape:transform-center-y="-2.5788507" - transform="translate(11.068361,12.736197)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-6" - id="textPath20030"><tspan - id="tspan7287-5-5-6"> 4 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - transform="translate(3.9941843,-3.1212455)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0" - id="textPath20018"><tspan - id="tspan7287-5-5-6-6"> 4 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-6" - inkscape:transform-center-x="-1.5564693" - inkscape:transform-center-y="-1.9746618" - transform="translate(4.5029255)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0" - id="textPath20024"><tspan - id="tspan7287-5-5-6-6-4"> Click, Click, Hold</tspan></textPath></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7-6)" - d="m 805.17382,500.33641 c 0.4912,-26.15636 0.9882,-169.24427 7.3904,-226.98309" - id="path5213-6-8-4-9-9-3-4-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-9" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - x="4.0937777" - y="-2.4259422" - transform="translate(3.7169557,-2.2115172)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-3" - id="textPath20021"><tspan - id="tspan7287-5-5-6-6-1"> 6 Clicks</tspan></textPath></text> - <path - style="fill:none;stroke:none;stroke-width:1.32938921;stroke-miterlimit:4;stroke-dasharray:1.32938933, 1.32938933;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-0-4-9)" - d="m 1400.1241,365.79536 c 0,0 0.043,-10.40514 -0.024,5.00754" - id="path5213-6-8-4-9-9-1-3-0-0-6-4-9" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:4.26666689, 4.26666689;stroke-dashoffset:4.05333376;stroke-opacity:1;marker-start:url(#marker14034-2-9);marker-end:url(#Arrow1Mend-597-9-5)" - d="m 1159.7225,198.62656 c 67.9862,-0.44112 68.743,-36.42258 0.1793,-35.70399" - id="path5213-6-8-4-9-9-8-7-3-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <g - id="g18567" - transform="translate(13.62988,7.3367765)"> - <text - id="text56273" - y="160.56241" - x="1067.6877" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan56275" - y="160.56241" - x="1067.6877" - sodipodi:role="line">Smooth </tspan></text> - <ellipse - ry="14.669211" - rx="39.313492" - cy="154.67567" - cx="1101.8171" - id="path11546" - style="opacity:1;fill:none;fill-opacity:1;stroke:#010109;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <g - id="g8460"> - <text - id="text3021-8-4-1-8-8-2-3-0" - y="787.48492" - x="1434.2471" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="787.48492" - x="1434.2471" - id="tspan3023-4-0-1-9-63-8-8-2" - sodipodi:role="line">Ramp Cfg</tspan><tspan - id="tspan39566" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="802.48492" - x="1434.2471" - sodipodi:role="line" /><tspan - id="tspan39568" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="802.48492" - x="1434.2471" - sodipodi:role="line" /><tspan - id="tspan39570" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="802.48492" - x="1434.2471" - sodipodi:role="line" /><tspan - id="tspan39590" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="802.48492" - x="1434.2471" - sodipodi:role="line" /></text> - <g - id="g16522-3" - transform="translate(9.0949204,-123.27684)"> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1810.7634" - y="915.72546" - id="text7289-7-6-21-8-8" - transform="rotate(-0.20350505)" - inkscape:transform-center-x="1.8963668" - inkscape:transform-center-y="-2.0513889"><tspan - sodipodi:role="line" - id="tspan7287-5-5-7-5-6" - x="1810.7634" - y="915.72546"> 4 Clicks</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9-3)" - d="m 1814.2439,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - id="path5213-6-8-4-9-9-1-3-8-4-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - </g> - <g - id="g16522-3-8" - transform="translate(9.0949217,89.635331)"> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1810.7634" - y="915.72546" - id="text7289-7-6-21-8-8-8" - transform="rotate(-0.20350505)" - inkscape:transform-center-x="1.8963668" - inkscape:transform-center-y="-2.0513889"><tspan - sodipodi:role="line" - id="tspan7287-5-5-7-5-6-9" - x="1810.7634" - y="915.72546"> 4 Clicks</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9-3-4)" - d="m 1814.2439,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - id="path5213-6-8-4-9-9-1-3-8-4-0-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - </g> - <rect - y="758.40918" - x="1424.8558" - height="310.87778" - width="275.93164" - id="rect5159-4-9" - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text39556" - y="806.21515" - x="1444.4535" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan39558" - y="806.21515" - x="1444.4535" - sodipodi:role="line">1. Floor</tspan><tspan - id="tspan58144" - y="822.34851" - x="1444.4535" - sodipodi:role="line"> (click N times for level N)</tspan><tspan - id="tspan39562" - y="838.48181" - x="1444.4535" - sodipodi:role="line">2. Ceiling</tspan><tspan - id="tspan58146" - y="854.61517" - x="1444.4535" - sodipodi:role="line"> (click N times for 1 + Turbo - N)</tspan><tspan - id="tspan39606" - y="870.74847" - x="1444.4535" - sodipodi:role="line">3. Number of steps</tspan><tspan - id="tspan43997" - y="886.88184" - x="1444.4535" - sodipodi:role="line"> (stepped ramp only)</tspan></text> - <text - id="text39623" - y="929.23431" - x="1444.4535" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="929.23431" - x="1444.4535" - id="tspan39621" - sodipodi:role="line">1. Current temperature</tspan><tspan - id="tspan14663" - y="945.36768" - x="1444.4535" - sodipodi:role="line"> (click N times for N deg C)</tspan><tspan - id="tspan14661" - y="961.50098" - x="1444.4535" - sodipodi:role="line">2. Temperature limit</tspan><tspan - id="tspan39625" - y="977.63434" - x="1444.4535" - sodipodi:role="line"> (click N times for 30 C + N)</tspan></text> - <text - id="text39629" - y="1019.1274" - x="1444.4535" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:110.00000238%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - y="1019.1274" - x="1444.4535" - id="tspan39627" - sodipodi:role="line">1. Beacon speed</tspan><tspan - id="tspan39631" - y="1035.2607" - x="1444.4535" - sodipodi:role="line"> (click N times</tspan><tspan - id="tspan43995" - y="1051.394" - x="1444.4535" - sodipodi:role="line"> for N seconds per flash)</tspan></text> - <text - id="text3021-8-4-1-8-8-2-3-0-5" - y="910.76184" - x="1436.6729" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - id="tspan39596-4" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="910.76184" - x="1436.6729" - sodipodi:role="line">Thermal Cfg</tspan><tspan - id="tspan39590-9" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="925.76184" - x="1436.6729" - sodipodi:role="line" /></text> - <text - id="text3021-8-4-1-8-8-2-3-0-3" - y="1000.3971" - x="1434.2471" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - xml:space="preserve"><tspan - id="tspan39590-4" - style="font-size:24px;line-height:1.25;stroke-width:1.06666672" - y="1000.3971" - x="1434.2471" - sodipodi:role="line">Beacon Cfg</tspan></text> - <g - transform="translate(9.094912)" - id="g16522"> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#7777ff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1810.7634" - y="915.72546" - id="text7289-7-6-21-8" - transform="rotate(-0.20350505)" - inkscape:transform-center-x="1.8963668" - inkscape:transform-center-y="-2.0513889"><tspan - sodipodi:role="line" - id="tspan7287-5-5-7-5" - x="1810.7634" - y="915.72546"> 4 Clicks</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:5.11919975;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-3-9)" - d="m 1814.2439,904.32938 c -2.5427,0.005 -34.933,0.0197 -38.794,0" - id="path5213-6-8-4-9-9-1-3-8-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - </g> - </g> - <g - id="g18572" - transform="translate(-76.57207,43.516866)"> - <rect - ry="3" - rx="3" - y="142.29279" - x="1152.8596" - height="25.367319" - width="78.318939" - id="rect11665" - style="opacity:1;fill:none;fill-opacity:1;stroke:#010109;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <text - id="text56273-7" - y="160.56241" - x="1154.8745" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - xml:space="preserve"><tspan - id="tspan56275-6" - y="160.56241" - x="1154.8745" - sodipodi:role="line">Stepped</tspan></text> - </g> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-4)" - d="m 1117.6932,712.70686 c -0.3699,-0.68086 -0.7041,-2.21056 -1.9908,-6.7818" - id="path5213-6-8-4-9-9-1-3-0-0-3-0" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - sodipodi:type="star" - style="fill:url(#radialGradient5882);fill-opacity:1;stroke:#000000;stroke-width:3.75277472;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path4327" - sodipodi:sides="7" - sodipodi:cx="-309.93027" - sodipodi:cy="215.58585" - sodipodi:r1="84.671265" - sodipodi:r2="50.343449" - sodipodi:arg1="0" - sodipodi:arg2="0.68976368" - inkscape:flatsided="false" - inkscape:rounded="0.007" - inkscape:randomized="0" - d="m -225.259,215.58585 c -0.0935,0.38012 -45.66671,31.68359 -45.83651,32.0363 -0.11206,0.23275 14.1915,34.05419 13.95691,34.16236 -0.35549,0.16391 -53.24395,-15.94928 -53.62558,-15.86212 -0.25184,0.0575 -17.77639,32.3278 -18.00722,32.21184 -0.34979,-0.17574 -20.72741,-51.57201 -21.0335,-51.81604 -0.20198,-0.16104 -36.35829,6.25792 -36.41154,6.00514 -0.0807,-0.38305 27.39728,-48.35997 27.39724,-48.75142 -3e-5,-0.25833 -27.56167,-24.52431 -27.39724,-24.72355 0.24917,-0.30192 54.89127,-8.73189 55.1973,-8.97599 0.20194,-0.16109 1.98946,-36.83923 2.24774,-36.8349 0.39141,0.007 41.05102,37.47148 41.43267,37.55854 0.25185,0.0574 30.04248,-21.41346 30.20013,-21.20882 0.23891,0.3101 -3.70149,55.45806 -3.5316,55.81073 0.11211,0.23273 35.47289,10.13708 35.4112,10.38793 z" - transform="matrix(0.92047755,0,0,0.7899176,1570.1356,490.73628)" - inkscape:transform-center-x="-3.8589074" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:24px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1283.365" - y="661.61969" - id="text3021-8-4-1-8"><tspan - sodipodi:role="line" - x="1283.365" - y="661.61969" - style="font-size:24px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan4155">Tactical</tspan></text> - <path - style="fill:none;stroke:#009d00;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-12-2)" - d="m 1365.5639,545.80243 c 85.2437,-57.56024 -28.9149,97.17858 67.2262,45" - id="path5213-6-8-4-9-9-8-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - inkscape:connector-curvature="0" - id="path3202-5" - d="m 1288.4731,602.92569 c -0.4528,-0.77951 -1.0803,-1.93107 -1.3943,-2.55904 -1.0737,-2.14685 -4.3132,-7.98949 -5.87,-10.58711 -4.3266,-7.21903 -7.6037,-10.33824 -10.9595,-10.43127 -1.1187,-0.0309 -1.3542,0.0431 -2.4509,0.77103 -1.2711,0.84373 -2.1683,1.85544 -3.5537,4.00743 -0.4567,0.70938 -0.958,1.29061 -1.114,1.29161 -0.156,0.001 -0.9033,-0.54296 -1.6607,-1.20878 -7.1051,-6.24594 -14.3753,-9.53314 -19.4236,-8.7823 -3.48,0.51759 -5.0204,1.56173 -6.3938,4.33401 l -0.8858,1.78805 0.011,2.61009 c 0.011,2.85728 0.4129,4.7602 1.6033,7.59226 1.304,3.10248 4.2705,7.39835 7.3473,10.63996 0.8946,0.9425 1.5704,1.71317 1.5019,1.71263 -0.4463,-0.003 -7.9187,-2.69233 -10.6412,-3.82902 -9.6708,-4.03772 -16.4977,-8.35341 -21.7399,-13.74329 -4.3679,-4.49084 -7.1775,-8.79859 -8.874,-13.60588 -1.423,-4.03226 -1.7223,-8.61526 -0.7973,-12.20916 1.2721,-4.94273 4.1587,-9.44906 9.1295,-14.25253 8.9547,-8.65325 21.3332,-14.86929 39.844,-20.00822 2.5963,-0.72078 4.771,-1.26013 4.8326,-1.19854 0.062,0.0616 -0.1839,0.42841 -0.5455,0.81514 -3.4868,3.729 -6.1246,8.13223 -6.7636,11.29025 -0.8015,3.96135 0.9708,8.08749 4.5023,10.48189 3.6869,2.49979 7.1211,3.43584 12.0741,3.29111 2.5161,-0.0735 2.8886,-0.1349 3.9401,-0.64934 2.5532,-1.24918 4.3141,-3.15132 6.0569,-6.54273 1.7409,-3.38781 2.0096,-4.74402 2.7417,-13.83851 0.2853,-3.54386 0.5748,-6.74799 0.6434,-7.12032 0.2923,-1.58661 0.8641,-1.01936 2.6229,2.60221 0.6806,1.40141 1.4217,2.64659 1.6468,2.76707 0.2885,0.15436 1.0531,0.1497 2.5905,-0.0158 1.632,-0.17572 2.9123,-0.17461 5.0851,0.004 2.8669,0.2362 2.91,0.23344 3.39,-0.21752 0.2674,-0.25122 0.8726,-1.35826 1.3449,-2.46008 0.4722,-1.10183 1.099,-2.36999 1.3928,-2.81817 l 0.5342,-0.81485 0.2758,0.52623 c 0.4689,0.89501 0.8326,3.8019 1.4248,11.38899 0.4971,6.36774 1.4643,9.24832 4.3881,13.06838 2.6506,3.46298 4.5846,4.27584 9.7379,4.09266 3.3642,-0.11958 5.0057,-0.46765 7.4657,-1.58306 4.2373,-1.92126 6.8173,-4.97803 7.4071,-8.77563 0.4545,-2.92687 -0.5377,-6.24976 -2.9384,-9.84036 -1.1827,-1.7688 -2.478,-3.40213 -3.8135,-4.80832 -0.5385,-0.5671 -0.7241,-0.88226 -0.5194,-0.88226 0.4592,0 9.5441,2.56459 12.6219,3.56306 22.3994,7.26655 37.858,19.25169 41.1432,31.89844 1.8774,7.22754 -0.9294,15.82998 -7.7794,23.84266 -2.308,2.69978 -3.5406,3.82883 -7.087,6.49171 -6.1933,4.65046 -11.5703,7.47767 -20.5514,10.80591 -2.9406,1.08974 -6.411,2.26689 -6.7199,2.27938 -0.042,0.001 0.5459,-0.65721 1.3072,-1.46427 4.3463,-4.60728 7.4331,-9.51352 8.6471,-13.74407 0.6134,-2.13752 0.7622,-5.66081 0.313,-7.41075 -0.6515,-2.53772 -1.9946,-4.20202 -4.2556,-5.27337 -1.3335,-0.63187 -1.4404,-0.64784 -4.2739,-0.63813 -2.6104,0.01 -3.086,0.0691 -4.6708,0.59188 -3.9756,1.31118 -8.4584,3.98094 -12.5592,7.47975 -1.1418,0.97413 -2.1694,1.76995 -2.2835,1.76848 -0.1142,-10e-4 -0.6268,-0.63027 -1.139,-1.39734 -2.7305,-4.08839 -5.1372,-5.32966 -8.1429,-4.19963 -1.7271,0.64937 -3.2592,2.01781 -5.3119,4.74462 -2.2156,2.9433 -4.0421,5.9743 -8.3381,13.83722 -1.7466,3.19688 -3.2017,5.8431 -3.2335,5.88048 -0.032,0.0373 -0.4282,-0.56984 -0.881,-1.34934 z" - style="fill:url(#radialGradient7151);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - sodipodi:nodetypes="csscsscsssccsscsssssscssssssssscccssscsssssssssssssscsssscsscssssccc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1223.3358" - y="572.08801" - id="text3021-8-4-1-8-1"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-7" - x="1223.3358" - y="572.08801" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">BattCheck</tspan></text> - <ellipse - style="fill:#505050;fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4" - cx="1288.233" - cy="763.54663" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1239.5554" - y="772.37585" - id="text3021-8-4-1-8-8"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63" - x="1239.5554" - y="772.37585" - style="font-size:25.60000038px;line-height:1.25;fill:#c0c0c0;fill-opacity:1;stroke-width:1.06666672">Lockout</tspan></text> - <ellipse - style="fill:url(#linearGradient7285);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-3" - cx="1480.8682" - cy="565.26556" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1418.7936" - y="571.9975" - id="text3021-8-4-1-8-60"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-2" - x="1418.7936" - y="571.9975" - style="font-size:21.33333397px;line-height:1.25;stroke-width:1.06666672">TempCheck</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1239.9597" - y="921.75562" - id="text3021-8-4-1-8-8-2"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-8" - x="1239.9597" - y="921.75562" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">Beacon</tspan></text> - <ellipse - style="fill:none;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-9" - cx="1288.6375" - cy="913.93665" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1288.1405" - y="996.59717" - id="text3021-8-4-1-8-8-7"><tspan - sodipodi:role="line" - id="tspan3023-4-0-1-9-63-3" - x="1288.1405" - y="996.59717" - style="font-size:25.60000038px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672">Thermal</tspan><tspan - sodipodi:role="line" - x="1288.1405" - y="1028.5972" - style="font-size:25.60000038px;line-height:1.25;text-align:center;text-anchor:middle;fill:#ff0000;fill-opacity:1;stroke-width:1.06666672" - id="tspan4199">Cfg</tspan></text> - <ellipse - style="fill:none;stroke:#ff0000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-6" - cx="1288.7599" - cy="999.38477" - rx="67.643234" - ry="41.719299" /> - <ellipse - style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:4.26666689;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-2-9" - cx="658.7066" - cy="1047.7236" - rx="48.48732" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.80000019px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="630.6225" - y="1057.1302" - id="text3021-8-47"><tspan - sodipodi:role="line" - id="tspan3023-4-8" - x="630.6225" - y="1057.1302" - style="font-size:25.60000038px;line-height:1.25;stroke-width:1.06666672">OFF</tspan></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-320-7)" - d="m 697.35842,924.31834 c 49.5295,21.01119 21.574,57.08215 0.2652,95.96446" - id="path5213-6-8-4-9-9-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-320-4-9)" - d="m 543.52862,921.79149 c 34.1247,72.78151 53.8989,0.009 84.6129,95.20691" - id="path5213-6-8-4-9-9-5-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-320-5-6)" - d="m 468.52094,717.28118 c 65.4701,1.8183 82.3057,-31.9173 105.9487,-90.40865" - id="path5213-6-8-4-9-9-5-9" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-374-2)" - d="m 472.95584,647.89594 c 24.7807,-1.21217 41.0401,-15.20503 74.2737,-36.42676" - id="path5213-6-8-4-9-9-1-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-374-7-4)" - d="m 474.39624,552.67716 c 33.8721,8.38428 35.3977,6.33668 77.2175,25.52105" - id="path5213-6-8-4-9-9-1-4-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-30-7)" - d="m 726.25616,420.9873 c 28.3163,57.37668 52.2535,139.95605 111.2518,172.77747" - id="path5213-6-8-4-9-9-1-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-30-8-15)" - d="m 713.26226,422.61475 c 15.1842,76.56958 72.9689,230.33933 151.16,268.21152" - id="path5213-6-8-4-9-9-1-8-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-30-8-1-8)" - d="m 696.03886,421.21509 c 15.6894,96.26755 75.5376,329.69142 157.7694,374.63467" - id="path5213-6-8-4-9-9-1-8-3-9" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-30-8-1-2-1)" - d="m 681.57206,417.59823 c 2.5574,139.19904 62.548,390.30058 173.064,451.4063" - id="path5213-6-8-4-9-9-1-8-3-9-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-30-8-1-2-8-1)" - d="m 669.34276,409.84061 c -23.6324,190.71681 59.0125,466.74032 187.2929,535.84062" - id="path5213-6-8-4-9-9-1-8-3-9-6-2" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1231.9467" - y="673.88409" - id="text5202"><tspan - sodipodi:role="line" - id="tspan5200" - x="1231.9467" - y="673.88409">(momentary)</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="920.47632" - y="900.1734" - id="text7289" - transform="rotate(-19.048886)" - inkscape:transform-center-x="21.194928" - inkscape:transform-center-y="-11.551537"><tspan - sodipodi:role="line" - id="tspan7287" - x="920.47632" - y="900.1734">3 Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="891.51764" - y="-353.34348" - id="text7289-3" - transform="rotate(50.003142)" - inkscape:transform-center-x="-3.1244591" - inkscape:transform-center-y="-24.312134"><tspan - sodipodi:role="line" - id="tspan7287-6" - x="891.51764" - y="-353.34348">4 Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="1201.4386" - y="-316.4696" - id="text7289-7" - transform="rotate(54.064752)" - inkscape:transform-center-x="-4.7794388" - inkscape:transform-center-y="-23.958945"><tspan - sodipodi:role="line" - id="tspan7287-5" - x="1201.4386" - y="-316.4696">6 Clicks</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-35" - inkscape:transform-center-x="-2.6057619" - inkscape:transform-center-y="-24.409989" - transform="translate(2.0536898,-2.6404583)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-3-67" - id="textPath18899"><tspan - id="tspan7287-62"> 8 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-9" - inkscape:transform-center-x="-2.9817013" - inkscape:transform-center-y="-24.428981" - transform="translate(2.0536898,-2.6404583)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-3-0-0-3-8" - startOffset="50%" - id="textPath18903"><tspan - id="tspan15689"> 10 Clicks</tspan></textPath></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:2.13333333, 8.53333333;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-374-3-3)" - d="m 471.69754,802.31437 c 71.9236,-4.7836 141.3973,-47.3479 138.5594,-175.71244" - id="path5213-6-8-4-9-9-1-4-7" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <ellipse - style="fill:url(#radialGradient18931);stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;fill-opacity:1" - id="path3639-4-4-9-8" - cx="1287.2483" - cy="838.64679" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1288.3867" - y="844.58032" - id="text3021-8-4-1-8-8-2-0"><tspan - sodipodi:role="line" - x="1288.3867" - y="844.58032" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530">Aux LED</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1287.882" - y="862.0556" - id="text3021-8-4-1-8-8-2-0-5"><tspan - sodipodi:role="line" - x="1287.882" - y="862.0556" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530-7">mode</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1284.6385" - y="827.58423" - id="text3021-8-4-1-8-8-2-0-5-4"><tspan - sodipodi:role="line" - x="1284.6385" - y="827.58423" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530-7-5">next</tspan></text> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-7)" - d="m 874.33081,937.81505 c -0.8727,171.59185 22.2064,184.87845 105.8123,186.09015" - id="path5213-6-8-4-9-9-1-3-0-0-3-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-0)" - d="m 873.74391,862.1219 c -0.8727,171.5919 22.2064,184.8784 105.8123,186.0902" - id="path5213-6-8-4-9-9-1-3-0-0-3-4" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-07)" - d="m 874.33071,1023.4833 c -0.8727,171.5918 22.2064,184.8783 105.8123,186.0901" - id="path5213-6-8-4-9-9-1-3-0-0-3-3" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-2)" - d="m 1109.3743,645.79672 c -0.8727,158.93719 -1.63,191.93185 103.5511,192.31379" - id="path5213-6-8-4-9-9-1-3-0-0-3-68" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-6)" - d="m 1109.8871,722.67091 c -0.8727,158.9372 -1.0432,191.93186 104.1379,192.3138" - id="path5213-6-8-4-9-9-1-3-0-0-3-67" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#7777ff;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:2.1329999, 2.1329999;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-9-4-4-35)" - d="m 1110.6079,808.09274 c -0.8727,158.93724 0.2162,192.96916 105.3973,193.35116" - id="path5213-6-8-4-9-9-1-3-0-0-3-8" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <ellipse - style="fill:url(#radialGradient18931-2);fill-opacity:1;stroke:#000000;stroke-width:3.20000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="path3639-4-4-9-8-6" - cx="1465.6587" - cy="673.09851" - rx="67.643234" - ry="29.092394" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1466.7971" - y="679.03204" - id="text3021-8-4-1-8-8-2-0-1"><tspan - sodipodi:role="line" - x="1466.7971" - y="679.03204" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530-5">lockout LED</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1466.2924" - y="696.50732" - id="text3021-8-4-1-8-8-2-0-5-7"><tspan - sodipodi:role="line" - x="1466.2924" - y="696.50732" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530-7-59">mode</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.33333397px;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:Sans;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.06666672" - x="1463.049" - y="662.03595" - id="text3021-8-4-1-8-8-2-0-5-4-4"><tspan - sodipodi:role="line" - x="1463.049" - y="662.03595" - style="font-size:21.33333397px;line-height:1.25;text-align:center;text-anchor:middle;stroke-width:1.06666672" - id="tspan8530-7-5-3">next</tspan></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-5" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - transform="translate(2.9338426,2.6404583)"><textPath - xlink:href="#path5213-6-8-4-9-9-1-42" - id="textPath20567"><tspan - id="tspan7287-5-5-6-6-0"> 4 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-5-9" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - x="2.6404583" - y="-2.6404583" - transform="translate(2.3470741,-2.0536898)"><textPath - xlink:href="#path5213-6-8-4-9-9-8-4" - id="textPath20570"><tspan - id="tspan7287-5-5-6-6-0-8"> 4 Clicks</tspan></textPath></text> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - id="text7289-7-6-2-0-5-7" - inkscape:transform-center-x="0.36232032" - inkscape:transform-center-y="-2.4072198" - x="-1.4669213" - y="-3.520611" - transform="translate(-0.58676852,-3.2272268)"><textPath - xlink:href="#path5213-6-8-4-9-9-8-4-4" - id="textPath20573"><tspan - id="tspan7287-5-5-6-6-0-80"> 4 Clicks</tspan></textPath></text> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7-2)" - d="m 1347.6426,532.88115 c 28.3161,-33.90911 -58.4398,-54.76032 -187.1937,-34.00596" - id="path5213-6-8-4-9-9-3-4-6" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.1329999;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m 1502.9065,536.58006 c 28.3161,-33.90911 -117.5677,-45.05348 -245.4416,-46.00955" - id="path5213-6-8-4-9-9-3-4-6-5" - inkscape:connector-curvature="0" - sodipodi:nodetypes="cc" /> - <path - style="fill:none;stroke:#000000;stroke-width:2.13333344;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-88-7-2-6)" - d="m 1346.2394,930.44842 c 122.4168,138.24568 -22.1872,139.99868 -157.1836,132.73448 -106.969,-5.7562 -130.2218,-49.2021 -109.224,-521.14862" - id="path5213-6-8-4-9-9-3-4-6-1" - inkscape:connector-curvature="0" - sodipodi:nodetypes="csc" /> - </g> -</svg> diff --git a/spaghetti-monster/spaghetti-monster.h b/spaghetti-monster/spaghetti-monster.h deleted file mode 100644 index 77431f8..0000000 --- a/spaghetti-monster/spaghetti-monster.h +++ /dev/null @@ -1,75 +0,0 @@ -// spaghetti-monster.h: UI toolkit / microkernel for e-switch flashlights. -// Copyright (C) 2017-2023 Selene ToyKeeper -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -/* - * SpaghettiMonster: Generic foundation code for e-switch flashlights. - * Other possible names: - * - FSM - * - RoundTable - * - Mostly Harmless - * - ... - */ - -#include "tk-attiny.h" - -#include <avr/eeprom.h> -#include <avr/power.h> - -// include project definitions to help with recognizing symbols -#include "fsm-events.h" -#include "fsm-states.h" -#include "fsm-adc.h" -#include "fsm-wdt.h" -#include "fsm-pcint.h" -#include "fsm-standby.h" -#include "fsm-channels.h" -#include "fsm-ramping.h" -#include "fsm-random.h" -#ifdef USE_EEPROM -#include "fsm-eeprom.h" -#endif -#include "fsm-misc.h" -#include "fsm-main.h" - -#if defined(USE_DELAY_MS) || defined(USE_DELAY_4MS) || defined(USE_DELAY_ZERO) || defined(USE_DEBUG_BLINK) -#define OWN_DELAY -#include "tk-delay.h" -#endif - -#ifdef USE_DEBUG_BLINK -#define DEBUG_FLASH PWM1_LVL = 64; delay_4ms(2); PWM1_LVL = 0; -void debug_blink(uint8_t num) { - for(; num>0; num--) { - PWM1_LVL = 32; - delay_4ms(100/4); - PWM1_LVL = 0; - delay_4ms(100/4); - } -} -#endif - -// Define these in your SpaghettiMonster recipe -// boot-time tasks -void setup(); -// single loop iteration, runs continuously -void loop(); - -// include executable functions too, for easier compiling -#include "fsm-states.c" -#include "fsm-events.c" -#include "fsm-adc.c" -#include "fsm-wdt.c" -#include "fsm-pcint.c" -#include "fsm-standby.c" -#include "fsm-channels.c" -#include "fsm-ramping.c" -#include "fsm-random.c" -#ifdef USE_EEPROM -#include "fsm-eeprom.c" -#endif -#include "fsm-misc.c" -#include "fsm-main.c" - diff --git a/spaghetti-monster/spaghetti-monster.txt b/spaghetti-monster/spaghetti-monster.txt deleted file mode 100644 index 434e1bc..0000000 --- a/spaghetti-monster/spaghetti-monster.txt +++ /dev/null @@ -1,325 +0,0 @@ -Spaghetti Monster: A UI toolkit library for flashlights -------------------------------------------------------- - -This toolkit takes care of most of the obnoxious parts of dealing with -tiny embedded chips and flashlight hardware, leaving you to focus on the -interface and user-visible features. - -For a quick start, look at the example UIs provided to see how things -are done. They are probably the most useful reference. However, other -details can be found here or in the FSM source code. - - -Why is it called Spaghetti Monster? - - This toolkit is a finite state machine, or FSM. Another thing FSM - stands for is Flying Spaghetti Monster. Source code tends to weave - into intricate knots like spaghetti, called spaghetti code, - particularly when the code isn't using appropriate abstractions for - the task it implements. - - Prior e-switch light code had a tendency to get pretty spaghetti-like, - and it made the code difficult to write, understand, and modify. So I - started from scratch and logically separated the hardware details from - the UI. This effectively put the spaghetti monster in a box, put it - on a leash, to make it behave and stay out of the way while we focus - on the user interface. - - Also, it's just kind of a fun name. :) - - -General concept: - - Spaghetti Monster (FSM) implements a stack-based finite state machine - with an event-handling system. - - Each FSM program should have a setup() function, a loop() function, - and at least one State: - - - The setup() function runs once each time power is connected. - - - The loop() function is called repeatedly whenever the system is - otherwise idle. Put your long-running tasks here, preferably with - consideration taken to allow for cooperative multitasking. - - - The States on the stack will be called whenever an event happens. - States are called in top-to-bottom order until a state returns an - "EVENT_HANDLED" signal. Only do quick tasks here. - - -Finite State Machine: - - Each "State" is simply a callback function which handles events. It - should return EVENT_HANDLED for each event type it does something - with, or EVENT_NOT_HANDLED otherwise. - - Transitions between states typically involve mapping an Event to a new - State, such as this: - - // 3 clicks: go to strobe modes - else if (event == EV_3clicks) { - set_state(strobe_state, 0); - return EVENT_HANDLED; - } - - It is strongly recommended that your State functions never do anything - which takes more than a few milliseconds... and certainly not longer - than 16ms. If you do this, the pending events may pile up to the - point where new events get thrown away. So, do only quick tasks in - the event handler, and do your longer-running tasks in the loop() - function instead. Preferably with precautions taken to allow for - cooperative multitasking. - - If your State function takes longer than one WDT tick (16ms) once in a - while, the system won't break. Several events can be queued. But be - sure not to do it very often. - - Several state management functions are provided: - - - set_state(new_state, arg): Replace the current state on the stack. - Send 'arg' to the new state for its init event. - - - push_state(new_state, arg): Add a new state to the stack, leaving - the current state below it. Send 'arg' to the new state for its - init event. - - - pop_state(): Get rid of (and return) the top-most state. Re-enter - the state below. - - -Event types: - - Event types are defined in fsm-events.h. You may want to adjust these - to fit your program, but the defaults are: - - State transitions: - - - EV_enter_state: Sent to each new State once when it goes onto - the stack. The 'arg' is whatever you define it to be. - - - EV_leave_state: Sent to a state immediately before it is removed - from the stack. - - - EV_reenter_state: If a State gets pushed on top of this one, and - then it pops off, a re-enter Event happens. This should handle - things like consuming the return value of a nested input handler - State. - - Time passing: - - - EV_tick: This happens once per clock tick, which is 16ms or - 62.5Hz by default. The 'arg' is the number of ticks since - entering the state. When 'arg' exceeds 65535, it wraps around - to 32768. - - - EV_sleep_tick: This happens every 0.5s during standby, if - enabled at compile time. The 'arg' is the number of ticks since - entering the state. When 'arg' exceeds 65535, it wraps around - to 32768. - - LVP and thermal regulation: - - - EV_voltage_low: Sent whenever the input power drops below the - VOLTAGE_LOW threshold. Minimum of VOLTAGE_WARNING_SECONDS - between events. - - - EV_temperature_high: Sent whenever the MCU's projected temperature - is higher than therm_ceil. Minimum of one second between events. - The 'arg' indicates how far the temperature exceeds the limit. - - - EV_temperature_low: Sent whenever the MCU's projected temperature - is lower than (therm_ceil - THERMAL_WINDOW_SIZE). Minimum of - one second between events. The 'arg' indicates how far the - temperature exceeds the limit. - - Button presses: - - Button events can be referred to either by pre-defined symbols, or - by teasing out the flags manually. The structure of a button - event is as follows: - - - Bit 7: 1 for button events, 0 otherwise. - - - Bit 6: 1 for a "timeout" event (signals the end of a - sequence), or 0 otherwise. - - - Bit 5: 1 for a "hold" event, 0 otherwise. This flag is only - necessary because, without it, it would be impossible to - distinguish between "click, click, timeout" and "click, hold, - release". - - - Bit 4: 1 if button is currently pressed, 0 otherwise. Button - release events look just like button press events, except this - is not set. - - - Bits 0,1,2,3: Counter for how many clicks there have been. - The first click is 1, second is 2, and it goes up to 15 clicks - in a row. Clicks after 15 are coded as 15. - - The pre-defined button event symbols are like the following: - - - EV_click1_press: The user pressed the button, but no time has - passed since then. - - - EV_click1_release: The user pressed and released the button, - but no time has passed since then. - - - EV_click1_complete: The user clicked the e-switch, released - it, and enough time passed that no more clicks were detected. - (a.k.a. EV_1click) - - - EV_click1_hold: The user pressed the button, and continued - holding it long enough to count as a "hold" event. This event - is sent once per timer tick as long as the button is held, and - the 'arg' value indicates how many timer ticks since the - button state went from 'press' to 'hold'. - - - EV_click1_hold_release: The button was released at the end of - a "hold" event. This is the end of the input sequence, - because no timeout period is used after a hold. - - It's worth noting that a "hold" event can only happen at the - end of an input sequence, and the sequence will reset to empty - after the hold is released. - - If the user pressed the button more than once, events follow the - same pattern. These are the same as above, except with a full - short-press and release first. - - - EV_click2_press - - EV_click2_release - - EV_click2_complete (a.k.a. EV_2clicks) - - EV_click2_hold - - EV_click2_hold_release - - Each of the above patterns continues up to 15 clicks. - - To match entire categories of events, use the bitmasks provided. - For example, to match button events where the button is down or - the button is up, the code would look like this: - - if ((event & (B_CLICK | B_PRESS)) == (B_CLICK | B_PRESS)) { - // button is down (can be a press event or a hold event) - } - else if ((event & (B_CLICK | B_PRESS)) == (B_CLICK)) { - // button was just released - } - - In theory, you could also define your own arbitrary event types, and - emit() them as necessary, and handle them in State functions the same - as any other event. - - -Cooperative multitasking: - - Since we don't have true preemptive multitasking, the best we can do - is cooperative multitasking. In practice, this means: - - - Declare global variables as volatile if they can be changed by an - event handler. This keeps the compiler from caching the value and - causing incorrect behavior. - - - Don't put long-running tasks into State functions. Each State - will get called at least once every 16ms for a clock tick, so they - should not run for longer than 16ms. - - - Put long-running tasks into loop() instead. - - - For long delay() calls, use nice_delay_ms(). This allows the MCU - to process events while we wait. It also automatically aborts if - it detects a state change, and returns a different value. - - In many cases, it shouldn't be necessary to do anything more than - this, but sometimes it will also be a good idea to check the - return value and abort the current task: - - if (! nice_delay_ms(mydelay)) break; - - - In general, try to do small amounts of work and then return - control to other parts of the program. Keep doing small amounts - and yielding until a task is done, instead of trying to do it all - at once. - - -Persistent data in EEPROM: - - To save data which lasts after a battery change, use the eeprom - functions. Define an eeprom style (or two) at the top, define how - many bytes to allocate, and then use the relevant functions as - appropriate. - - - USE_EEPROM / USE_EEPROM_WL: Enable the eeprom-related functions. - With "WL", it uses wear-levelling. Without, it does not. Note: - Wear levelling is not necessarily better -- it uses more ROM, and - it writes more bytes per save(). So, use it only for a few bytes - which change frequently -- not for many bytes or infrequent - changes. - - - EEPROM_BYTES N / EEPROM_WL_BYTES N: Allocate N bytes for the - eeprom data. - - - load_eeprom() / load_eeprom_wl(): Load the stored data into the - eeprom[] or eeprom_wl[] arrays. - Returns 1 if data was found, 0 otherwise. - - - save_eeprom() / save_eeprom_wl(): Save the eeprom[] or eeprom_wl[] - array data to persistent storage. The WL version erases all old - values and writes new ones in a different part of the eeprom - space. The non-WL version updates values in place, and does not - overwrite values which didn't change. - - Note that all interrupts will be disabled during eeprom operations. - - -Useful #defines: - - A variety of things can be #defined before including - spaghetti-monster.h in your program. This allows you to tweak the - behavior and set options to fit your needs: - - - FSM_something_LAYOUT: Select a driver type from tk-attiny.h. This - controls how many power channels there are, which pins they're on, - and what other driver features are available. - - - USE_LVP: Enable low-voltage protection. - - - VOLTAGE_LOW: What voltage should LVP trigger at? Defaults to 29 (2.9V). - - - VOLTAGE_FUDGE_FACTOR: Add this much to the voltage measurements, - to compensate for voltage drop across the reverse-polarity - diode. - - - VOLTAGE_WARNING_SECONDS: How long to wait between LVP events. - - - USE_THERMAL_REGULATION: Enable thermal regulation - - - DEFAULT_THERM_CEIL: Set the temperature limit to use by default - when the user hasn't configured anything. - - - USE_RAMPING: Enable smooth ramping helpers. - - - RAMP_LENGTH: Pick a pre-defined ramp by length. Defined sizes - are 50, 75, and 150 levels. - - - USE_DELAY_4MS, USE_DELAY_MS, USE_DELAY_ZERO: Enable the delay_4ms, - delay_ms(), and delay_zero() functions. Useful for timing-related - activities. - - - HOLD_TIMEOUT: How many clock ticks before a "press" event becomes - a "hold" event? - - - RELEASE_TIMEOUT: How many clock ticks before a "release" event - becomes a "click" event? Basically, the maximum time between - clicks in a double-click or triple-click. - - - USE_BATTCHECK: Enable the battcheck function. Also define one of - the following to select a display style: - - - BATTCHECK_VpT: Volts, pause, tenths. - - BATTCHECK_4bars: Blink up to 4 times. - - BATTCHECK_6bars: Blink up to 6 times. - - BATTCHECK_8bars: Blink up to 8 times. - - - ... and many others. Will try to document them over time, but - they can be found by searching for pretty much anything in - all-caps in the fsm-*.[ch] files. diff --git a/spaghetti-monster/werner/Makefile b/spaghetti-monster/werner/Makefile deleted file mode 100644 index 21d85f7..0000000 --- a/spaghetti-monster/werner/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: - ./build-all.sh - -clean: - rm -f cfg-*.h *.hex *~ *.elf *.o - -.phony: clean diff --git a/spaghetti-monster/werner/README b/spaghetti-monster/werner/README deleted file mode 100644 index 5fe392d..0000000 --- a/spaghetti-monster/werner/README +++ /dev/null @@ -1,56 +0,0 @@ -This is a Werner-style interface for dual-switch lights -(e-switch + clicky switch). What that means is: - -While the clicky switch is off: - - - Click the clicky switch: Turn on, at the last-used level. The clicky - switch works as a momentary mode. - - - Click the clicky switch while holding the e-switch: Go into sort of a - utility mode. - -While on, in a normal steady mode: - - - Click the clicky switch: Turn off. - - - Click the e-switch: Brighter. One step per click. - - - Hold the e-switch: Dimmer. Keep holding to go down multiple steps. - -While in standby, in utility mode: - - - Click the e-switch: Turn on. - - - Hold the e-switch: Turn on at lowest level. - - - Double-click the e-switch: Turn on at highest level. - - - Triple-click the e-switch: Battery check mode. - - - Quad-click the e-switch: Ramp config mode. - -While in battery check mode: - - - Click either switch: Turn off. - - - Double-click the e-switch: Go to temperature check mode. - -While in temperature check mode: - - - Click either switch: Turn off. - - - Double-click the e-switch: Go to battery check mode. - - - Quad-click the e-switch: Go to thermal config mode. - -Ramp config mode and thermal config mode work the same as in Anduril or -RampingIOS V3. The options are: - - - Ramp config mode: - 1. Floor level. - 2. Ceiling level. - 3. Number of steps. - - - Thermal config mode: - 1. Calibrate sensor by entering current temperature in C. - 2. Set temperature limit to 30 C + N clicks. diff --git a/spaghetti-monster/werner/build-all.sh b/spaghetti-monster/werner/build-all.sh deleted file mode 100755 index b114101..0000000 --- a/spaghetti-monster/werner/build-all.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -cp -av ../anduril/cfg*.h . - -UI=werner - -for TARGET in cfg-*.h ; do - NAME=$(echo "$TARGET" | perl -ne '/cfg-(.*).h/ && print "$1\n";') - echo "===== $NAME =====" - ATTINY=$(grep 'ATTINY:' $TARGET | awk '{ print $3 }') - if [ -z "$ATTINY" ]; then ATTINY=85 ; fi - echo ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}" - ../../../bin/build.sh $ATTINY "$UI" "-DCONFIGFILE=${TARGET}" - mv -f "$UI".hex "$UI".$NAME.hex -done diff --git a/spaghetti-monster/werner/werner.c b/spaghetti-monster/werner/werner.c deleted file mode 100644 index f3241ee..0000000 --- a/spaghetti-monster/werner/werner.c +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Werner: Werner-style dual-switch UI for SpaghettiMonster. - * Side click to go up, side hold to go down, tail click for on/off. - * - * Copyright (C) 2018 Selene ToyKeeper - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/********* User-configurable options *********/ -// Physical driver type (uncomment one of the following or define it at the gcc command line) -//#define CONFIGFILE cfg-emisar-d4.h - -#define USE_LVP // FIXME: won't build when this option is turned off - -// parameters for this defined below or per-driver -#define USE_THERMAL_REGULATION -#define DEFAULT_THERM_CEIL 45 // try not to get hotter than this - -// battery readout style (pick one) -#define BATTCHECK_VpT -//#define BATTCHECK_8bars // FIXME: breaks build -//#define BATTCHECK_4bars // FIXME: breaks build - -// cut clock speed at very low modes for better efficiency -// (defined here so config files can override it) -#define USE_DYNAMIC_UNDERCLOCKING - -/***** specific settings for known driver types *****/ -#ifdef CONFIGFILE -#include "tk.h" -#include incfile(CONFIGFILE) -#else -#error You need to define CONFIGFILE -#endif - -// thermal properties, if not defined per-driver -#ifndef MIN_THERM_STEPDOWN -#define MIN_THERM_STEPDOWN MAX_1x7135 // lowest value it'll step down to -#endif -#ifndef THERM_FASTER_LEVEL - #ifdef MAX_Nx7135 - #define THERM_FASTER_LEVEL MAX_Nx7135 // throttle back faster when high - #else - #define THERM_FASTER_LEVEL (RAMP_SIZE*4/5) // throttle back faster when high - #endif -#endif -#ifdef USE_THERMAL_REGULATION -#define USE_SET_LEVEL_GRADUALLY // isn't used except for thermal adjustments -#endif - - -/********* Configure SpaghettiMonster *********/ -#define USE_DELAY_ZERO -#define USE_RAMPING -#define RAMP_LENGTH 150 // default, if not overridden in a driver cfg file -#define USE_BATTCHECK -#define USE_IDLE_MODE // reduce power use while awake and no tasks are pending - -// auto-detect how many eeprom bytes -#define USE_EEPROM -#ifdef USE_THERMAL_REGULATION -#define EEPROM_BYTES 5 -#else -#define EEPROM_BYTES 3 -#endif -// for mode memory on tail switch -#define USE_EEPROM_WL -#define EEPROM_WL_BYTES 1 - -#include "spaghetti-monster.h" - - -// FSM states -uint8_t off_state(Event event, uint16_t arg); -// simple numeric entry config menu -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()); -#define MAX_CONFIG_VALUES 3 -uint8_t config_state_values[MAX_CONFIG_VALUES]; -// ramping mode and its related config mode -uint8_t steady_state(Event event, uint16_t arg); -uint8_t ramp_config_state(Event event, uint16_t arg); -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg); -#endif -#ifdef USE_THERMAL_REGULATION -uint8_t tempcheck_state(Event event, uint16_t arg); -uint8_t thermal_config_state(Event event, uint16_t arg); -#endif - -// general helper function for config modes -uint8_t number_entry_state(Event event, uint16_t arg); -// return value from number_entry_state() -volatile uint8_t number_entry_value; - -void blink_confirm(uint8_t num); - -// remember stuff even after battery was changed -void load_config(); -void save_config(); -void save_config_wl(); - -// default ramp options if not overridden earlier per-driver -#ifndef RAMP_DISCRETE_FLOOR - #define RAMP_DISCRETE_FLOOR 1 -#endif -#ifndef RAMP_DISCRETE_CEIL - #define RAMP_DISCRETE_CEIL RAMP_SIZE -#endif -#ifndef RAMP_DISCRETE_STEPS - #define RAMP_DISCRETE_STEPS 7 -#endif - -// brightness control -uint8_t memorized_level = MAX_1x7135; -// smooth vs discrete ramping -volatile uint8_t ramp_discrete_floor = RAMP_DISCRETE_FLOOR; -volatile uint8_t ramp_discrete_ceil = RAMP_DISCRETE_CEIL; -volatile uint8_t ramp_discrete_steps = RAMP_DISCRETE_STEPS; -uint8_t ramp_discrete_step_size; // don't set this - -// calculate the nearest ramp level which would be valid at the moment -// (is a no-op for smooth ramp, but limits discrete ramp to only the -// correct levels for the user's config) -uint8_t nearest_level(int16_t target); - -#ifdef USE_THERMAL_REGULATION -// brightness before thermal step-down -uint8_t target_level = 0; -#endif - - -uint8_t off_state(Event event, uint16_t arg) { - // turn emitter off when entering state - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - // let the user know the power is connected - blink_confirm(1); - // but otherwise stay off - set_level(0); - // sleep while off (lower power use) - go_to_standby = 1; - return EVENT_HANDLED; - } - // go back to sleep eventually if we got bumped but didn't leave "off" state - else if (event == EV_tick) { - if (arg > TICKS_PER_SECOND*2) { - go_to_standby = 1; - } - return EVENT_HANDLED; - } - // hold (initially): go to lowest level, but allow abort for regular click - else if (event == EV_click1_press) { - set_level(nearest_level(1)); - return EVENT_HANDLED; - } - // hold: go to lowest level - else if (event == EV_click1_hold) { - // don't start ramping immediately; - // give the user time to release at moon level - if (arg >= HOLD_TIMEOUT) { - set_state(steady_state, 1); - } - return EVENT_HANDLED; - } - // hold, release quickly: go to lowest level - else if (event == EV_click1_hold_release) { - set_state(steady_state, 1); - return EVENT_HANDLED; - } - // 1 click (before timeout): go to memorized level, but allow abort for double click - else if (event == EV_click1_release) { - set_level(nearest_level(memorized_level)); - return EVENT_HANDLED; - } - // 1 click: regular mode - else if (event == EV_1click) { - set_state(steady_state, memorized_level); - return EVENT_HANDLED; - } - // 2 clicks (initial press): off, to prep for later events - else if (event == EV_click2_press) { - set_level(0); - return EVENT_HANDLED; - } - // click, hold: go to highest level (for ramping down) - else if (event == EV_click2_hold) { - set_state(steady_state, MAX_LEVEL); - return EVENT_HANDLED; - } - // 2 clicks: highest mode - else if (event == EV_2clicks) { - set_state(steady_state, nearest_level(MAX_LEVEL)); - return EVENT_HANDLED; - } - #ifdef USE_BATTCHECK - // 3 clicks: battcheck mode / blinky mode group - else if (event == EV_3clicks) { - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - #endif - // 4 clicks: configure ramp - else if (event == EV_4clicks) { - push_state(ramp_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -uint8_t steady_state(Event event, uint16_t arg) { - uint8_t mode_min = ramp_discrete_floor; - uint8_t mode_max = ramp_discrete_ceil; - uint8_t ramp_step_size = ramp_discrete_step_size; - - // turn LED on when we first enter the mode - if ((event == EV_enter_state) || (event == EV_reenter_state)) { - // if we just got back from config mode, go back to memorized level - if (event == EV_reenter_state) { - arg = memorized_level; - } - // remember this level, unless it's moon or turbo - if ((arg > mode_min) && (arg < mode_max)) - memorized_level = arg; - // use the requested level even if not memorized - #ifdef USE_THERMAL_REGULATION - target_level = arg; - #endif - set_level(nearest_level(arg)); - return EVENT_HANDLED; - } - // click: brighter - else if (event == EV_click1_release) { - memorized_level = nearest_level((int16_t)actual_level + ramp_step_size); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - // make sure next click will respond quickly - empty_event_sequence(); - // remember mode for later - save_config_wl(); - return EVENT_HANDLED; - } - // hold: dimmer - else if (event == EV_click1_hold) { - // ramp slower in discrete mode - if (arg % HOLD_TIMEOUT != 0) { - return EVENT_HANDLED; - } - memorized_level = nearest_level((int16_t)actual_level - ramp_step_size); - #ifdef USE_THERMAL_REGULATION - target_level = memorized_level; - #endif - set_level(memorized_level); - return EVENT_HANDLED; - } - // reverse ramp direction on hold release - else if (event == EV_click1_hold_release) { - save_config_wl(); - return EVENT_HANDLED; - } - #if defined(USE_SET_LEVEL_GRADUALLY) - // gradual thermal regulation - else if (event == EV_tick) { - #ifdef USE_SET_LEVEL_GRADUALLY - // make thermal adjustment speed scale with magnitude - if ((arg & 1) && (actual_level < THERM_FASTER_LEVEL)) { - return EVENT_HANDLED; // adjust slower when not a high mode - } - #ifdef THERM_HARD_TURBO_DROP - else if ((! (actual_level < THERM_FASTER_LEVEL)) - && (actual_level > gradual_target)) { - gradual_tick(); - } - else { - #endif - // [int(62*4 / (x**0.95)) for x in (1,2,4,8,16,32,64,128)] - uint8_t intervals[] = {248, 128, 66, 34, 17, 9, 4, 2}; - uint8_t diff; - static uint8_t ticks_since_adjust = 0; - ticks_since_adjust ++; - if (gradual_target > actual_level) diff = gradual_target - actual_level; - else { - diff = actual_level - gradual_target; - } - uint8_t magnitude = 0; - #ifndef THERM_HARD_TURBO_DROP - // if we're on a really high mode, drop faster - if (actual_level >= THERM_FASTER_LEVEL) { magnitude ++; } - #endif - while (diff) { - magnitude ++; - diff >>= 1; - } - uint8_t ticks_per_adjust = intervals[magnitude]; - if (ticks_since_adjust > ticks_per_adjust) - { - gradual_tick(); - ticks_since_adjust = 0; - } - //if (!(arg % ticks_per_adjust)) gradual_tick(); - #ifdef THERM_HARD_TURBO_DROP - } - #endif - #endif - return EVENT_HANDLED; - } - #endif - #ifdef USE_THERMAL_REGULATION - // overheating: drop by an amount proportional to how far we are above the ceiling - else if (event == EV_temperature_high) { - #ifdef THERM_HARD_TURBO_DROP - if (actual_level > THERM_FASTER_LEVEL) { - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(THERM_FASTER_LEVEL); - #else - set_level(THERM_FASTER_LEVEL); - #endif - } else - #endif - if (actual_level > MIN_THERM_STEPDOWN) { - int16_t stepdown = actual_level - arg; - if (stepdown < MIN_THERM_STEPDOWN) stepdown = MIN_THERM_STEPDOWN; - else if (stepdown > MAX_LEVEL) stepdown = MAX_LEVEL; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepdown); - #else - set_level(stepdown); - #endif - } - return EVENT_HANDLED; - } - // underheating: increase slowly if we're lower than the target - // (proportional to how low we are) - else if (event == EV_temperature_low) { - if (actual_level < target_level) { - //int16_t stepup = actual_level + (arg>>1); - int16_t stepup = actual_level + arg; - if (stepup > target_level) stepup = target_level; - else if (stepup < MIN_THERM_STEPDOWN) stepup = MIN_THERM_STEPDOWN; - #ifdef USE_SET_LEVEL_GRADUALLY - set_level_gradually(stepup); - #else - set_level(stepup); - #endif - } - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} - - -#ifdef USE_BATTCHECK -uint8_t battcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - #ifdef USE_THERMAL_REGULATION - // 2 clicks: tempcheck mode - else if (event == EV_2clicks) { - blink_confirm(2); - set_state(tempcheck_state, 0); - return EVENT_HANDLED; - } - #endif - return EVENT_NOT_HANDLED; -} -#endif - -#ifdef USE_THERMAL_REGULATION -uint8_t tempcheck_state(Event event, uint16_t arg) { - // 1 click: off - if (event == EV_1click) { - set_state(off_state, 0); - return EVENT_HANDLED; - } - // 2 clicks: battcheck mode - else if (event == EV_2clicks) { - blink_confirm(1); - set_state(battcheck_state, 0); - return EVENT_HANDLED; - } - // 4 clicks: thermal config mode - else if (event == EV_4clicks) { - push_state(thermal_config_state, 0); - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} -#endif - - -// ask the user for a sequence of numbers, then save them and return to caller -uint8_t config_state_base(Event event, uint16_t arg, - uint8_t num_config_steps, - void (*savefunc)()) { - static uint8_t config_step; - if (event == EV_enter_state) { - config_step = 0; - set_level(0); - return EVENT_HANDLED; - } - // advance forward through config steps - else if (event == EV_tick) { - if (config_step < num_config_steps) { - push_state(number_entry_state, config_step + 1); - } - else { - // TODO: blink out some sort of success pattern - savefunc(); - save_config(); - //set_state(retstate, retval); - pop_state(); - } - return EVENT_HANDLED; - } - // an option was set (return from number_entry_state) - else if (event == EV_reenter_state) { - config_state_values[config_step] = number_entry_value; - config_step ++; - return EVENT_HANDLED; - } - //return EVENT_NOT_HANDLED; - // eat all other events; don't pass any through to parent - return EVENT_HANDLED; -} - -void ramp_config_save() { - // parse values - uint8_t val; - - val = config_state_values[0]; - if (val) { ramp_discrete_floor = val; } - - val = config_state_values[1]; - if (val) { ramp_discrete_ceil = MAX_LEVEL + 1 - val; } - - val = config_state_values[2]; - if (val) ramp_discrete_steps = val; -} - -uint8_t ramp_config_state(Event event, uint16_t arg) { - uint8_t num_config_steps; - num_config_steps = 3; - return config_state_base(event, arg, - num_config_steps, ramp_config_save); -} - - -#ifdef USE_THERMAL_REGULATION -void thermal_config_save() { - // parse values - uint8_t val; - - // calibrate room temperature - val = config_state_values[0]; - if (val) { - int8_t rawtemp = temperature - therm_cal_offset; - therm_cal_offset = val - rawtemp; - reset_thermal_history = 1; // invalidate all recent temperature data - } - - val = config_state_values[1]; - if (val) { - // set maximum heat limit - therm_ceil = 30 + val - 1; - } - if (therm_ceil > MAX_THERM_CEIL) therm_ceil = MAX_THERM_CEIL; -} - -uint8_t thermal_config_state(Event event, uint16_t arg) { - return config_state_base(event, arg, - 2, thermal_config_save); -} -#endif - - -uint8_t number_entry_state(Event event, uint16_t arg) { - static uint8_t value; - static uint8_t blinks_left; - static uint8_t entry_step; - static uint16_t wait_ticks; - if (event == EV_enter_state) { - value = 0; - blinks_left = arg; - entry_step = 0; - wait_ticks = 0; - return EVENT_HANDLED; - } - // advance through the process: - // 0: wait a moment - // 1: blink out the 'arg' value - // 2: wait a moment - // 3: "buzz" while counting clicks - // 4: save and exit - else if (event == EV_tick) { - // wait a moment - if ((entry_step == 0) || (entry_step == 2)) { - if (wait_ticks < TICKS_PER_SECOND/2) - wait_ticks ++; - else { - entry_step ++; - wait_ticks = 0; - } - } - // blink out the option number - else if (entry_step == 1) { - if (blinks_left) { - if ((wait_ticks & 31) == 10) { - set_level(RAMP_SIZE/4); - } - else if ((wait_ticks & 31) == 20) { - set_level(0); - } - else if ((wait_ticks & 31) == 31) { - blinks_left --; - } - wait_ticks ++; - } - else { - entry_step ++; - wait_ticks = 0; - } - } - else if (entry_step == 3) { // buzz while waiting for a number to be entered - wait_ticks ++; - // buzz for N seconds after last event - if ((wait_ticks & 3) == 0) { - set_level(RAMP_SIZE/6); - } - else if ((wait_ticks & 3) == 2) { - set_level(RAMP_SIZE/8); - } - // time out after 3 seconds - if (wait_ticks > TICKS_PER_SECOND*3) { - //number_entry_value = value; - set_level(0); - entry_step ++; - } - } - else if (entry_step == 4) { - number_entry_value = value; - pop_state(); - } - return EVENT_HANDLED; - } - // count clicks - else if (event == EV_click1_release) { - empty_event_sequence(); - if (entry_step == 3) { // only count during the "buzz" - value ++; - wait_ticks = 0; - // flash briefly - set_level(RAMP_SIZE/2); - delay_4ms(8/2); - set_level(0); - } - return EVENT_HANDLED; - } - return EVENT_NOT_HANDLED; -} - - -// find the ramp level closest to the target, -// using only the levels which are allowed in the current state -uint8_t nearest_level(int16_t target) { - // bounds check - // using int16_t here saves us a bunch of logic elsewhere, - // by allowing us to correct for numbers < 0 or > 255 in one central place - uint8_t mode_min = ramp_discrete_floor; - uint8_t mode_max = ramp_discrete_ceil; - if (target < mode_min) return mode_min; - if (target > mode_max) return mode_max; - - uint8_t ramp_range = ramp_discrete_ceil - ramp_discrete_floor; - ramp_discrete_step_size = ramp_range / (ramp_discrete_steps-1); - uint8_t this_level = ramp_discrete_floor; - - for(uint8_t i=0; i<ramp_discrete_steps; i++) { - this_level = ramp_discrete_floor + (i * (uint16_t)ramp_range / (ramp_discrete_steps-1)); - int16_t diff = target - this_level; - if (diff < 0) diff = -diff; - if (diff <= (ramp_discrete_step_size>>1)) - return this_level; - } - return this_level; -} - - -void blink_confirm(uint8_t num) { - for (; num>0; num--) { - set_level(MAX_LEVEL/4); - delay_4ms(10/4); - set_level(0); - delay_4ms(100/4); - } -} - - -void load_config() { - if (load_eeprom()) { - ramp_discrete_floor = eeprom[0]; - ramp_discrete_ceil = eeprom[1]; - ramp_discrete_steps = eeprom[2]; - #ifdef USE_THERMAL_REGULATION - therm_ceil = eeprom[3]; - therm_cal_offset = eeprom[4]; - #endif - } - if (load_eeprom_wl()) { - memorized_level = eeprom_wl[0]; - } -} - - -void save_config() { - eeprom[0] = ramp_discrete_floor; - eeprom[1] = ramp_discrete_ceil; - eeprom[2] = ramp_discrete_steps; - #ifdef USE_THERMAL_REGULATION - eeprom[3] = therm_ceil; - eeprom[4] = therm_cal_offset; - #endif - - save_eeprom(); -} - - -void save_config_wl() { - eeprom_wl[0] = memorized_level; - save_eeprom_wl(); -} - - -void low_voltage() { - StatePtr state = current_state; - - // in normal mode, step down or turn off - if (state == steady_state) { - if (actual_level > 1) { - uint8_t lvl = (actual_level >> 1) + (actual_level >> 2); - set_level(lvl); - #ifdef USE_THERMAL_REGULATION - target_level = lvl; - #endif - } - else { - set_state(off_state, 0); - } - } - // all other modes, just turn off when voltage is low - else { - set_state(off_state, 0); - } -} - - -void setup() { - // dual switch: e-switch + power clicky - // power clicky acts as a momentary mode - load_config(); - - if (button_is_pressed()) - // hold button to go to moon - push_state(off_state, 0); - else - // otherwise use memory - push_state(steady_state, memorized_level); -} - - -void loop() { - - StatePtr state = current_state; - - if (0) {} - - #ifdef USE_BATTCHECK - else if (state == battcheck_state) { - battcheck(); - } - #endif - #ifdef USE_THERMAL_REGULATION - // TODO: blink out therm_ceil during thermal_config_state - else if (state == tempcheck_state) { - blink_num(temperature); - nice_delay_ms(1000); - } - #endif - - #ifdef USE_IDLE_MODE - else { - // doze until next clock tick - idle_mode(); - } - #endif - -} |
